diff --git a/docker-compose-integrationtest.yml b/docker-compose-integrationtest.yml
index 9125770c2b27a127475511b3fcc0b50c88892a01..e5969840658a7d67fcd07d130e482bbc3ce90132 100644
--- a/docker-compose-integrationtest.yml
+++ b/docker-compose-integrationtest.yml
@@ -48,6 +48,7 @@ services:
       - ./src/main/resources/db/migration/V3__Notification_CC_List.sql:/docker-entrypoint-initdb.d/V3__Notification_CC_List.sql
       - ./src/main/resources/db/migration/V4__Schema_data_migration.sql:/docker-entrypoint-initdb.d/V4__Schema_data_migration.sql
       - ./src/main/resources/db/migration/V5.2__Data_transformation_status_deleted.sql:/docker-entrypoint-initdb.d/V5.2__Data_transformation_status_deleted.sql
+      - ./src/main/resources/db/migration/V6.2__Schema_data_migration_audit.sql:/docker-entrypoint-initdb.d/V6.2__Schema_data_migration_audit.sql
 
 volumes:
   naming-data:
diff --git a/docs/about/naming_rest_api_brief_introduction.docx b/docs/about/naming_rest_api_brief_introduction.docx
index f0fea57cdce32cfe454227409c601e8060cc97f3..cf9b43f69aa71bb74b70981ebec6bfe372c8958a 100644
Binary files a/docs/about/naming_rest_api_brief_introduction.docx and b/docs/about/naming_rest_api_brief_introduction.docx differ
diff --git a/docs/about/naming_rest_api_brief_introduction.pdf b/docs/about/naming_rest_api_brief_introduction.pdf
index 5edc1bc49af1aaef32afbceb136e3796cd18bf8c..147232219ca8392b0f0dc0e275fe84305488ce97 100644
Binary files a/docs/about/naming_rest_api_brief_introduction.pdf and b/docs/about/naming_rest_api_brief_introduction.pdf differ
diff --git a/docs/about/naming_rest_api_cheat_sheet.pdf b/docs/about/naming_rest_api_cheat_sheet.pdf
index 81b692bb4c3b790166199789aa9f8bfce540b75b..a16ac9197e183ef8793798470a54da33d3a84c2d 100644
Binary files a/docs/about/naming_rest_api_cheat_sheet.pdf and b/docs/about/naming_rest_api_cheat_sheet.pdf differ
diff --git a/docs/about/naming_rest_api_cheat_sheet.pptx b/docs/about/naming_rest_api_cheat_sheet.pptx
index 8a9c8fa594dc6a38467474a1f869dd70d327e029..84099a157f180af10e3be28f8844009f1075618b 100644
Binary files a/docs/about/naming_rest_api_cheat_sheet.pptx and b/docs/about/naming_rest_api_cheat_sheet.pptx differ
diff --git a/docs/about/naming_rest_api_excel_guide.docx b/docs/about/naming_rest_api_excel_guide.docx
index 1145e4371e1460ed56ed29ce135149947d9f445e..8651ce1f0ad649df65addc51a2c09c0117f36722 100644
Binary files a/docs/about/naming_rest_api_excel_guide.docx and b/docs/about/naming_rest_api_excel_guide.docx differ
diff --git a/docs/about/naming_rest_api_excel_guide.pdf b/docs/about/naming_rest_api_excel_guide.pdf
index 655a029d74b7cfd0c3859cca0bd823716f07c686..28fead09929b09debb88f023da259fff60ca996d 100644
Binary files a/docs/about/naming_rest_api_excel_guide.pdf and b/docs/about/naming_rest_api_excel_guide.pdf differ
diff --git a/docs/developer/naming_architecture_code.docx b/docs/developer/naming_architecture_code.docx
index 250dcaa483668efd7abf1ff0214f4e085a5c2ccb..e48c7a115271bce2c8b6b3b67aaff8994a6f55cb 100644
Binary files a/docs/developer/naming_architecture_code.docx and b/docs/developer/naming_architecture_code.docx differ
diff --git a/docs/developer/naming_architecture_code.pdf b/docs/developer/naming_architecture_code.pdf
index 40fa47b623c43e8d3a906ca1e5c065a57a98d196..8b23667e3178472142058b83761a4a38773d2e4f 100644
Binary files a/docs/developer/naming_architecture_code.pdf and b/docs/developer/naming_architecture_code.pdf differ
diff --git a/docs/todo_for_first_releases.txt b/docs/todo_for_first_releases.txt
new file mode 100644
index 0000000000000000000000000000000000000000..397b2658ddeda7ccf26b2ae6857685c771030632
--- /dev/null
+++ b/docs/todo_for_first_releases.txt
@@ -0,0 +1,191 @@
+To do - in particular at time of first set of releases
+
+----------------------------------------------------------------------------------------------------
+
+Content
+    (a) Before first release
+            1. verification      - static
+            2. verification      - data & application
+    (b) For first release
+            1. preparation       - close & backup
+            2. migration scripts - run
+            3. verification      - data & application
+            4. release           - release & deploy
+            5. post              - open & use
+    (c) For second release
+            1. preparation       - close & backup
+            2. remove code       - remove obsolete
+            3. migration script  - make new, remove previous
+            4. upgrade database  - to latest postgres
+            5. remove obsolete database content
+            6. flyway            - introduce
+            7. release           - release & deploy
+            8. post              - open & use
+
+----------------------------------------------------------------------------------------------------
+
+Note
+    - First release
+            migration of database and functionality
+          ( migration script V6.2 - audit tables contain all )
+    - Second release
+            one migration script only
+            upgrade Postgres database
+            introduction of Flyway
+          ( possibility to do first and second release together and deploy Naming after second release )
+    ------------------------------------------------------------------------------------------------
+    - Tests should be able to run at all times
+            see src/test/resources/INTEGRATIONTEST_DOCKER_RUN.md
+                To build and run all unit tests and integration tests (Docker) with code coverage.
+    - Verification of migration with endpoints
+            /verification - concerns verification of migration up to script V5 (pre audit)
+    - Configuration not mentioned below
+            additional configfuration may be required
+    - Keep migration documentation until judged ok to remove
+            keep docs/developer/naming_rest_api_migration.doc (.pdf) until some later time
+            to be able to guide users of old Naming REST API to new Naming REST API
+    - Respect integrations
+
+----------------------------------------------------------------------------------------------------
+
+(a) Before first release
+        1. verification          - static
+                1.1 migration scripts
+                1.2 code
+                1.3 documentation
+        2. verification          - data & application
+                2.1 use endpoints
+                        /report
+                            /report/about
+                        /verification
+                            /verification/migration_structures
+                            /verification/migration_names
+                            /verification/data_reachable
+                            /verification/restapi_oldvsnew
+                2.2 analyse database
+                        example sql queries
+                2.3 swagger
+                2.4 other
+
+----------------------------------------------------------------------------------------------------
+
+(b) For first release
+        1. preparation           - close & backup
+                1.1 close Naming (old)
+                1.2 backup database
+        2. migration scripts     - run
+                2.1 run migration script - src/main/resources/db/migration/V4__Schema_data_migration.sql
+                2.2 run migration script - src/main/resources/db/migration/V5.2__Data_transformation_status_deleted.sql
+                2.3 run migration script - src/main/resources/db/migration/V6.2__Schema_data_migration_audit.sql
+
+                about
+                        V4   - migrate to temporary tables, "work in progress"
+                        V5.2 - delete entries that never have been active
+                        V6.2 - migrate to permanent tables, audit tables with all entries
+        3. verification          - data & application
+                3.1 use old Naming REST API
+                3.2 use new Naming REST API
+                        /report
+                            /report/about
+                        /verification
+                            /verification/migration_structures
+                            /verification/migration_names
+                            /verification/data_reachable
+                            /verification/restapi_oldvsnew
+                        swagger
+                3.2 analyse database
+                        example sql queries
+                3.3 other
+        4. release               - release & deploy
+        5. post                  - open & use
+                4.1 open Naming (new)
+
+----------------------------------------------------------------------------------------------------
+
+(c) For second release
+        1. preparation           - close & backup
+                1.1 close Naming (new)
+                1.2 backup database
+        2. remove code       - remove obsolete
+                2.1. remove code - old and wip (work-in-progress)
+                        src/main/java
+                            org.openepics.names.old.business
+                            org.openepics.names.old.model
+                            org.openepics.names.old.nameviews
+                            org.openepics.names.repository.model.wip
+                            org.openepics.names.repository.old
+                            org.openepics.names.repository.wip
+                            org.openepics.names.rest.beans.old
+                            org.openepics.names.rest.controller.old
+                            org.openepics.names.util.old
+                            org.openepics.names.util.wip
+                            ( org.openepics.names.old )
+                            org.openepics.names.rest.controller/ReportController.java
+                            org.openepics.names.rest.controller/VerificationController.java
+                        src/test/java
+                            org.openepics.names.repository.model.wip
+                            org.openepics.names.docker.ReportIT.java
+                            org.openepics.names.docker.VerificationIT.java
+
+                        old - refers to code for old Naming tool                              - for reference and verification purposes
+                        wip - refers to work-in-progress (temporary) code for new Naming tool - for migration and verification purposes
+                2.2. update documentation ( related to removal of code )
+                        src/test/resources
+                            INTEGRATIONTEST_DOCKER_RUN.md
+                        docs/developer
+                            naming_architecture_code.docx
+                            naming_architecture_code.pdf
+        3. migration script  - make new, remove previous
+                3.1 create with database management tool, e.g. DBeaver
+                3.2 give name V1__*.sql
+                3.3 update docker-compose-integrationtest.yml to use new migration script V1__*.sql instead of old migration scripts (V1 - V6)
+        4. upgrade database  - to latest postgres
+                4.1 decide postgres version to upgrade to, e.g. 16.2
+                4.2 update docker compose files
+                        docker-compose.yml
+                        docker-compose-demo.yml
+                        docker-compose-integrationtest.yml
+        5. remove obsolete database content
+                5.1 remove obsolete tables - tables no longer in use - see 6.2 - decide on flyway table
+                        tables
+                            remove
+                                appinfo
+                                device
+                                devicerevision
+                              ( flyway_schema_history )
+                                namepart
+                                namepartrevision
+                                useraccount
+                                wip_devicegroup
+                                wip_devicetype
+                                wip_discipline
+                                wip_name
+                                wip_subsystem
+                                wip_system
+                                wip_systemgroup
+                            keep
+                                audit_name
+                                audit_structure
+                                devicegroup
+                                devicetype
+                                discipline
+                              ( flyway_schema_history )
+                                name
+                                subsystem
+                                system
+                                systemgroup
+                                user_notification
+                        other
+                            related to wip tables -- see also V4__Schema_data_migration.sql
+                            indices
+                            foreign keys
+                            sequences
+                            functions
+        6. flyway            - introduce
+                6.1 possibly use existing table flyway_schema_history or create a new table
+                6.2 introduce flyway and make use of new migration script V1__*.sql - see 5.1 - decide on flyway table
+        7. release           - release & deploy
+        8. post              - open & use
+                8.1 open Naming (new)
+
+----------------------------------------------------------------------------------------------------
diff --git a/docs/useful/useful.odg b/docs/useful/useful.odg
index aa618b21bde4f435f52e848b85c261cac07cd654..edfb1fb75ee05ce678947c34fca2c94f16b1ee22 100644
Binary files a/docs/useful/useful.odg and b/docs/useful/useful.odg differ
diff --git a/src/main/java/org/openepics/names/exception/handler/GlobalControllerExceptionHandler.java b/src/main/java/org/openepics/names/exception/handler/GlobalControllerExceptionHandler.java
index 23ecfd4b2f12d6959ee8f2c7ee288e1e88d97a03..a7c60a99b2d6047d7fae98db2ec43c4f277e796a 100644
--- a/src/main/java/org/openepics/names/exception/handler/GlobalControllerExceptionHandler.java
+++ b/src/main/java/org/openepics/names/exception/handler/GlobalControllerExceptionHandler.java
@@ -57,9 +57,6 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
 @RestControllerAdvice
 public class GlobalControllerExceptionHandler extends ResponseEntityExceptionHandler {
 
-    // note
-    //     no logging here
-
     @ExceptionHandler
     protected ResponseEntity<Response> handleConflict(RuntimeException ex, WebRequest request) {
         Response response = new Response("", "", "");
diff --git a/src/main/java/org/openepics/names/repository/AuditNameRepository.java b/src/main/java/org/openepics/names/repository/AuditNameRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..6dc81049588cd4ef6c7c5805552bb3205ee43199
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/AuditNameRepository.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2024 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.repository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.AuditName;
+import org.openepics.names.repository.model.NameStructure;
+import org.openepics.names.util.RepositoryUtil;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Handle audit name information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public class AuditNameRepository {
+
+    @PersistenceContext
+    private EntityManager em;
+
+    /**
+     * Count audit names.
+     *
+     * @param uuid uuid
+     * @return count of audit names
+     */
+    public Long countAuditNames(String uuid) {
+        // where
+        //     uuid
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<AuditName> from = cq.from(AuditName.class);
+
+        cq.where(cb.and(preparePredicatesAuditNames(cb, cq, from,
+                uuid).toArray(new Predicate[0])));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find audit names.
+     *
+     * @param uuid uuid
+     * @return list of audit names
+     */
+    public List<AuditName> readAuditNames(String uuid,
+            Integer offset, Integer limit) {
+
+        // where
+        //     uuid
+        // order
+        //     processed asc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<AuditName> cq = cb.createQuery(AuditName.class);
+        Root<AuditName> from = cq.from(AuditName.class);
+
+        cq.where(cb.and(preparePredicatesAuditNames(cb, cq, from,
+                uuid).toArray(new Predicate[0])));
+        cq.select(from);
+
+        cq.orderBy(cb.asc(from.get(NameStructure.FIELD_REQUESTED)));
+
+        TypedQuery<AuditName> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Prepare predicates for audit names.
+     *
+     * @param cb criteria builder
+     * @param cq criteria query
+     * @param from criteria query root
+     * @param uuid uuid
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesAuditNames(CriteriaBuilder cb, CriteriaQuery cq, Root<AuditName> from,
+            String uuid) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(NameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Persist audit name into persistence context.
+     *
+     * @param auditName audit name
+     */
+    public void createAuditName(AuditName auditName) {
+        em.persist(auditName);
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/AuditStructureRepository.java b/src/main/java/org/openepics/names/repository/AuditStructureRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd919e8d15ee4c3493c064bf07131e8da37752e4
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/AuditStructureRepository.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2024 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.repository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.AuditStructure;
+import org.openepics.names.rest.beans.Type;
+import org.openepics.names.util.RepositoryUtil;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Handle audit structure information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public class AuditStructureRepository {
+
+    @PersistenceContext
+    private EntityManager em;
+
+    /**
+     * Count audit structures.
+     *
+     * @param type type
+     * @param uuid uuid
+     * @return count of audit structures
+     */
+    public Long countAuditStructures(Type type, String uuid) {
+        // where
+        //     type
+        //     uuid
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<AuditStructure> from = cq.from(AuditStructure.class);
+
+        cq.where(cb.and(preparePredicatesAuditStructures(cb, cq, from,
+                type, uuid).toArray(new Predicate[0])));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find audit structures.
+     *
+     * @param type type
+     * @param uuid uuid
+     * @return list of structures
+     */
+    public List<AuditStructure> readAuditStructures(Type type, String uuid,
+            Integer offset, Integer limit) {
+
+        // where
+        //     type
+        //     uuid
+        // order
+        //     processed asc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<AuditStructure> cq = cb.createQuery(AuditStructure.class);
+        Root<AuditStructure> from = cq.from(AuditStructure.class);
+
+        cq.where(cb.and(preparePredicatesAuditStructures(cb, cq, from,
+                type, uuid).toArray(new Predicate[0])));
+        cq.select(from);
+
+        cq.orderBy(cb.asc(from.get(AuditStructure.FIELD_PROCESSED)));
+
+        TypedQuery<AuditStructure> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Prepare predicates for audit structures.
+     *
+     * @param cb criteria builder
+     * @param cq criteria query
+     * @param from criteria query root
+     * @param type type
+     * @param uuid uuid
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesAuditStructures(CriteriaBuilder cb, CriteriaQuery cq, Root<AuditStructure> from,
+            Type type, String uuid) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (type != null) {
+            predicates.add(cb.and(cb.equal(from.get(AuditStructure.FIELD_AUDIT_TABLE), type.name().toLowerCase())));
+        }
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(AuditStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Persist audit structure into persistence context.
+     *
+     * @param auditStructure audit structure
+     */
+    public void createAuditStructure(AuditStructure auditStructure) {
+        em.persist(auditStructure);
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/DeviceGroupRepository.java b/src/main/java/org/openepics/names/repository/DeviceGroupRepository.java
index 63b65a039f3f7d7a0cf39f844c058700754c6f49..0037cbe9d5fd086fa8b5963de04ba2f0508a08ba 100644
--- a/src/main/java/org/openepics/names/repository/DeviceGroupRepository.java
+++ b/src/main/java/org/openepics/names/repository/DeviceGroupRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -29,7 +29,6 @@ import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
-import javax.persistence.criteria.Subquery;
 
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -38,7 +37,6 @@ import org.openepics.names.repository.model.NameStructure;
 import org.openepics.names.repository.model.Persistable;
 import org.openepics.names.repository.model.Structure;
 import org.openepics.names.rest.beans.FieldStructure;
-import org.openepics.names.rest.beans.Status;
 import org.openepics.names.util.RepositoryUtil;
 import org.springframework.stereotype.Repository;
 
@@ -64,12 +62,10 @@ public class DeviceGroupRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return count of device groups
      */
     public Long countDeviceGroups(Boolean deleted,
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         // note
         //     use of function for mnemonic path
@@ -82,8 +78,7 @@ public class DeviceGroupRepository {
         Root<DeviceGroup> from = cq.from(DeviceGroup.class);
 
         cq.where(cb.and(preparePredicatesDeviceGroups(cb, cq, from, deleted,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(cb.count(from));
 
         return em.createQuery(cq).getSingleResult();
@@ -107,7 +102,7 @@ public class DeviceGroupRepository {
 
         return readDeviceGroups(deleted,
                 uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.FALSE, null, null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -121,7 +116,6 @@ public class DeviceGroupRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @param orderBy order by
      * @param isAsc is ascending
      * @param offset offset
@@ -130,7 +124,7 @@ public class DeviceGroupRepository {
      */
     public List<DeviceGroup> readDeviceGroups(Boolean deleted,
             String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+            FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
         // note
         //     use of function for mnemonic path
@@ -147,8 +141,7 @@ public class DeviceGroupRepository {
         Root<DeviceGroup> from = cq.from(DeviceGroup.class);
 
         cq.where(cb.and(preparePredicatesDeviceGroups(cb, cq, from, deleted,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(from);
 
         if (orderBy != null) {
@@ -183,75 +176,13 @@ public class DeviceGroupRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return list of predicates
      */
     private List<Predicate> preparePredicatesDeviceGroups(CriteriaBuilder cb, CriteriaQuery cq, Root<DeviceGroup> from, Boolean deleted,
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         List<Predicate> predicates = new ArrayList<>();
 
-        if (!Boolean.TRUE.equals(includeHistory)) {
-            // purpose of Naming to show valid entries
-            //     therefore
-            //         exclude some values unless history requested
-            //         make sure to not exclude present and future values (latest approved and pending)
-            //
-            // condition(s)
-            //     exclude content (with latest) before latest
-            //     exclude content (with latest) after  latest (cancelled, rejected)
-            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
-            //         <-->
-            //         select * from structure s
-            //         where (
-            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
-            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
-            //         )
-            //         <-->
-            //                     not (exists (subquery id) and s.id < (subquery id))
-            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (subquery id) and s.id < (subquery 2))
-            //
-            // note
-            //     persistence libraries may optimize query
-            //         e.g. change (!a and !b) to !(a or b)
-
-            Subquery<Long> sub = cq.subquery(Long.class);
-            Root<DeviceGroup> fromSub = sub.from(DeviceGroup.class);
-            sub.where(cb.and(
-                    cb.equal(fromSub.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub.get(NameStructure.FIELD_LATEST), Boolean.TRUE)
-                    ));
-            sub.select(fromSub.get(Persistable.FIELD_ID));
-
-            Subquery<Long> sub2 = cq.subquery(Long.class);
-            Root<DeviceGroup> fromSub2 = sub2.from(DeviceGroup.class);
-            sub2.where(cb.and(
-                    cb.equal(fromSub2.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub2.get(NameStructure.FIELD_LATEST), Boolean.FALSE)
-                    ));
-            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
-
-            Predicate predicateExclude =
-                    cb.and(
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
-                                    cb.or(
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.CANCELLED),
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.REJECTED)))),
-                            cb.not(cb.and(
-                                    cb.not(cb.exists(sub)),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
-                            );
-            predicates.add(predicateExclude);
-        }
-
         if (deleted != null) {
             predicates.add(cb.equal(from.get(NameStructure.FIELD_DELETED), deleted));
         }
@@ -264,7 +195,7 @@ public class DeviceGroupRepository {
             predicates.add(cb.and(cb.equal(from.get(NameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
         }
         if (!StringUtils.isEmpty(parentUuid)) {
-            predicates.add(cb.and(cb.equal(from.get(DeviceGroup.FIELD_PARENT_UUID), RepositoryUtil.preparePattern(parentUuid))));
+            predicates.add(cb.and(cb.equal(cb.function(DeviceGroup.FUNCTION_GET_PARENT_UUID_DEVICEGROUP, String.class, from.get(Persistable.FIELD_ID)), RepositoryUtil.preparePattern(parentUuid))));
         }
         if (!StringUtils.isEmpty(mnemonic)) {
             predicates.add(cb.and(cb.like(from.get(Structure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
@@ -273,7 +204,7 @@ public class DeviceGroupRepository {
             predicates.add(cb.and(cb.like(from.get(Structure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
         }
         if (!StringUtils.isEmpty(mnemonicPath)) {
-            predicates.add(cb.and(cb.like(cb.function(DeviceGroup.FUNCTION_GET_MNEMONIC_PATH_DEVICEGROUP, String.class, from.get(NameStructure.FIELD_UUID)), RepositoryUtil.preparePattern(mnemonicPath))));
+            predicates.add(cb.and(cb.like(cb.function(DeviceGroup.FUNCTION_GET_MNEMONIC_PATH_DEVICEGROUP, String.class, from.get(Persistable.FIELD_ID)), RepositoryUtil.preparePattern(mnemonicPath))));
         }
         if (!StringUtils.isEmpty(description)) {
             predicates.add(cb.and(cb.like(from.get(NameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
@@ -296,7 +227,7 @@ public class DeviceGroupRepository {
         if (FieldStructure.UUID.equals(orderBy)) {
             return root.get(NameStructure.FIELD_UUID);
         } else if (FieldStructure.PARENT.equals(orderBy)) {
-            return root.get(DeviceGroup.FIELD_PARENT_UUID);
+            return root.get(DeviceGroup.FIELD_PARENT_ID);
         } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
             return root.get(Structure.FIELD_MNEMONIC);
         } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
@@ -312,100 +243,6 @@ public class DeviceGroupRepository {
         }
     }
 
-    /**
-     * Count device groups history.
-     *
-     * @param uuid uuid
-     * @param parentUuid parent uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @return count of device groups
-     */
-    public Long countDeviceGroupsHistory(
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
-        Root<DeviceGroup> from = cq.from(DeviceGroup.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<DeviceGroup> fromSub = sub.from(DeviceGroup.class);
-        sub.where(cb.and(preparePredicatesDeviceGroups(cb, cq, fromSub, null,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(cb.count(from));
-
-        return em.createQuery(cq).getSingleResult();
-    }
-
-    /**
-     * Find device groups history.
-     *
-     * @param uuid uuid
-     * @param parentUuid parent uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @param orderBy order by
-     * @param isAsc is ascending
-     * @return list of device groups
-     */
-    public List<DeviceGroup> readDeviceGroupsHistory(
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            FieldStructure orderBy, Boolean isAsc) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-        // order
-        //     orderBy, isAsc
-        // paging
-        //     outside of method
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<DeviceGroup> cq = cb.createQuery(DeviceGroup.class);
-        Root<DeviceGroup> from = cq.from(DeviceGroup.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<DeviceGroup> fromSub = sub.from(DeviceGroup.class);
-        sub.where(cb.and(preparePredicatesDeviceGroups(cb, cq, fromSub, null,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(from);
-
-        if (orderBy != null) {
-            Expression<String> exp = orderBy(from, orderBy);
-            if (BooleanUtils.toBoolean(isAsc)) {
-                cq.orderBy(cb.asc(exp));
-            } else {
-                cq.orderBy(cb.desc(exp));
-            }
-        }
-
-        return em.createQuery(cq).getResultList();
-    }
-
     /**
      * Persist device group into persistence context.
      *
diff --git a/src/main/java/org/openepics/names/repository/DeviceTypeRepository.java b/src/main/java/org/openepics/names/repository/DeviceTypeRepository.java
index 772f16f24cbe42b0e5e684d342fad85bb520de33..b422885676be2754c9acf2321cd892143778f0c5 100644
--- a/src/main/java/org/openepics/names/repository/DeviceTypeRepository.java
+++ b/src/main/java/org/openepics/names/repository/DeviceTypeRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -29,7 +29,6 @@ import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
-import javax.persistence.criteria.Subquery;
 
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -38,7 +37,6 @@ import org.openepics.names.repository.model.NameStructure;
 import org.openepics.names.repository.model.Persistable;
 import org.openepics.names.repository.model.Structure;
 import org.openepics.names.rest.beans.FieldStructure;
-import org.openepics.names.rest.beans.Status;
 import org.openepics.names.util.RepositoryUtil;
 import org.springframework.stereotype.Repository;
 
@@ -64,12 +62,10 @@ public class DeviceTypeRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return count of device types
      */
     public Long countDeviceTypes(Boolean deleted,
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         // note
         //     use of function for mnemonic path
@@ -82,8 +78,7 @@ public class DeviceTypeRepository {
         Root<DeviceType> from = cq.from(DeviceType.class);
 
         cq.where(cb.and(preparePredicatesDeviceTypes(cb, cq, from, deleted,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(cb.count(from));
 
         return em.createQuery(cq).getSingleResult();
@@ -107,7 +102,7 @@ public class DeviceTypeRepository {
 
         return readDeviceTypes(deleted,
                 uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.FALSE, null, null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -121,7 +116,6 @@ public class DeviceTypeRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @param orderBy order by
      * @param isAsc is ascending
      * @param offset offset
@@ -130,7 +124,7 @@ public class DeviceTypeRepository {
      */
     public List<DeviceType> readDeviceTypes(Boolean deleted,
             String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+            FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
         // note
         //     use of function for mnemonic path
@@ -147,8 +141,7 @@ public class DeviceTypeRepository {
         Root<DeviceType> from = cq.from(DeviceType.class);
 
         cq.where(cb.and(preparePredicatesDeviceTypes(cb, cq, from, deleted,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(from);
 
         if (orderBy != null) {
@@ -183,75 +176,13 @@ public class DeviceTypeRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return list of predicates
      */
     private List<Predicate> preparePredicatesDeviceTypes(CriteriaBuilder cb, CriteriaQuery cq, Root<DeviceType> from, Boolean deleted,
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         List<Predicate> predicates = new ArrayList<>();
 
-        if (!Boolean.TRUE.equals(includeHistory)) {
-            // purpose of Naming to show valid entries
-            //     therefore
-            //         exclude some values unless history requested
-            //         make sure to not exclude present and future values (latest approved and pending)
-            //
-            // condition(s)
-            //     exclude content (with latest) before latest
-            //     exclude content (with latest) after  latest (cancelled, rejected)
-            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
-            //         <-->
-            //         select * from structure s
-            //         where (
-            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
-            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
-            //         )
-            //         <-->
-            //                     not (exists (subquery id) and s.id < (subquery id))
-            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (subquery id) and s.id < (subquery 2))
-            //
-            // note
-            //     persistence libraries may optimize query
-            //         e.g. change (!a and !b) to !(a or b)
-
-            Subquery<Long> sub = cq.subquery(Long.class);
-            Root<DeviceType> fromSub = sub.from(DeviceType.class);
-            sub.where(cb.and(
-                    cb.equal(fromSub.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub.get(NameStructure.FIELD_LATEST), Boolean.TRUE)
-                    ));
-            sub.select(fromSub.get(Persistable.FIELD_ID));
-
-            Subquery<Long> sub2 = cq.subquery(Long.class);
-            Root<DeviceType> fromSub2 = sub2.from(DeviceType.class);
-            sub2.where(cb.and(
-                    cb.equal(fromSub2.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub2.get(NameStructure.FIELD_LATEST), Boolean.FALSE)
-                    ));
-            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
-
-            Predicate predicateExclude =
-                    cb.and(
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
-                                    cb.or(
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.CANCELLED),
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.REJECTED)))),
-                            cb.not(cb.and(
-                                    cb.not(cb.exists(sub)),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
-                            );
-            predicates.add(predicateExclude);
-        }
-
         if (deleted != null) {
             predicates.add(cb.equal(from.get(NameStructure.FIELD_DELETED), deleted));
         }
@@ -264,7 +195,7 @@ public class DeviceTypeRepository {
             predicates.add(cb.and(cb.equal(from.get(NameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
         }
         if (!StringUtils.isEmpty(parentUuid)) {
-            predicates.add(cb.and(cb.equal(from.get(DeviceType.FIELD_PARENT_UUID), RepositoryUtil.preparePattern(parentUuid))));
+            predicates.add(cb.and(cb.equal(cb.function(DeviceType.FUNCTION_GET_PARENT_UUID_DEVICETYPE, String.class, from.get(Persistable.FIELD_ID)), RepositoryUtil.preparePattern(parentUuid))));
         }
         if (!StringUtils.isEmpty(mnemonic)) {
             predicates.add(cb.and(cb.like(from.get(Structure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
@@ -273,7 +204,7 @@ public class DeviceTypeRepository {
             predicates.add(cb.and(cb.like(from.get(Structure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
         }
         if (!StringUtils.isEmpty(mnemonicPath)) {
-            predicates.add(cb.and(cb.like(cb.function(DeviceType.FUNCTION_GET_MNEMONIC_PATH_DEVICETYPE, String.class, from.get(NameStructure.FIELD_UUID)), RepositoryUtil.preparePattern(mnemonicPath))));
+            predicates.add(cb.and(cb.like(cb.function(DeviceType.FUNCTION_GET_MNEMONIC_PATH_DEVICETYPE, String.class, from.get(Persistable.FIELD_ID)), RepositoryUtil.preparePattern(mnemonicPath))));
         }
         if (!StringUtils.isEmpty(description)) {
             predicates.add(cb.and(cb.like(from.get(NameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
@@ -296,7 +227,7 @@ public class DeviceTypeRepository {
         if (FieldStructure.UUID.equals(orderBy)) {
             return root.get(NameStructure.FIELD_UUID);
         } else if (FieldStructure.PARENT.equals(orderBy)) {
-            return root.get(DeviceType.FIELD_PARENT_UUID);
+            return root.get(DeviceType.FIELD_PARENT_ID);
         } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
             return root.get(Structure.FIELD_MNEMONIC);
         } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
@@ -312,100 +243,6 @@ public class DeviceTypeRepository {
         }
     }
 
-    /**
-     * Count device types history.
-     *
-     * @param uuid uuid
-     * @param parentUuid parent uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @return count of device types
-     */
-    public Long countDeviceTypesHistory(
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
-        Root<DeviceType> from = cq.from(DeviceType.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<DeviceType> fromSub = sub.from(DeviceType.class);
-        sub.where(cb.and(preparePredicatesDeviceTypes(cb, cq, fromSub, null,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(cb.count(from));
-
-        return em.createQuery(cq).getSingleResult();
-    }
-
-    /**
-     * Find device types history.
-     *
-     * @param uuid uuid
-     * @param parentUuid parent uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @param orderBy order by
-     * @param isAsc is ascending
-     * @return list of device types
-     */
-    public List<DeviceType> readDeviceTypesHistory(
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            FieldStructure orderBy, Boolean isAsc) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-        // order
-        //     orderBy, isAsc
-        // paging
-        //     outside of method
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<DeviceType> cq = cb.createQuery(DeviceType.class);
-        Root<DeviceType> from = cq.from(DeviceType.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<DeviceType> fromSub = sub.from(DeviceType.class);
-        sub.where(cb.and(preparePredicatesDeviceTypes(cb, cq, fromSub, null,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(from);
-
-        if (orderBy != null) {
-            Expression<String> exp = orderBy(from, orderBy);
-            if (BooleanUtils.toBoolean(isAsc)) {
-                cq.orderBy(cb.asc(exp));
-            } else {
-                cq.orderBy(cb.desc(exp));
-            }
-        }
-
-        return em.createQuery(cq).getResultList();
-    }
-
     /**
      * Persist device type into persistence context.
      *
diff --git a/src/main/java/org/openepics/names/repository/DisciplineRepository.java b/src/main/java/org/openepics/names/repository/DisciplineRepository.java
index 546de456de6b57f41ff27aeaab5a78afb7a55cf6..ba0c9b0f80568263d95e4aad75df5d8e69819e19 100644
--- a/src/main/java/org/openepics/names/repository/DisciplineRepository.java
+++ b/src/main/java/org/openepics/names/repository/DisciplineRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -29,16 +29,13 @@ import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
-import javax.persistence.criteria.Subquery;
 
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.openepics.names.repository.model.Discipline;
 import org.openepics.names.repository.model.NameStructure;
-import org.openepics.names.repository.model.Persistable;
 import org.openepics.names.repository.model.Structure;
 import org.openepics.names.rest.beans.FieldStructure;
-import org.openepics.names.rest.beans.Status;
 import org.openepics.names.util.RepositoryUtil;
 import org.springframework.stereotype.Repository;
 
@@ -63,12 +60,10 @@ public class DisciplineRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return count of disciplines
      */
     public Long countDisciplines(Boolean deleted,
-            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         // note
         //     use of function for mnemonic path
@@ -81,8 +76,7 @@ public class DisciplineRepository {
         Root<Discipline> from = cq.from(Discipline.class);
 
         cq.where(cb.and(preparePredicatesDisciplines(cb, cq, from, deleted,
-                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(cb.count(from));
 
         return em.createQuery(cq).getSingleResult();
@@ -105,7 +99,7 @@ public class DisciplineRepository {
 
         return readDisciplines(deleted,
                 uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.FALSE, null, null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -118,7 +112,6 @@ public class DisciplineRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @param orderBy order by
      * @param isAsc is ascending
      * @param offset offset
@@ -127,12 +120,12 @@ public class DisciplineRepository {
      */
     public List<Discipline> readDisciplines(Boolean deleted,
             String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+            FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
         // note
         //     use of function for mnemonic path
         // where
-        //     latest, deleted
+        //     deleted
         //     queryFields, queryValues
         // order
         //     orderBy, isAsc
@@ -144,8 +137,7 @@ public class DisciplineRepository {
         Root<Discipline> from = cq.from(Discipline.class);
 
         cq.where(cb.and(preparePredicatesDisciplines(cb, cq, from, deleted,
-                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(from);
 
         if (orderBy != null) {
@@ -179,75 +171,13 @@ public class DisciplineRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return list of predicates
      */
     private List<Predicate> preparePredicatesDisciplines(CriteriaBuilder cb, CriteriaQuery cq, Root<Discipline> from, Boolean deleted,
-            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         List<Predicate> predicates = new ArrayList<>();
 
-        if (!Boolean.TRUE.equals(includeHistory)) {
-            // purpose of Naming to show valid entries
-            //     therefore
-            //         exclude some values unless history requested
-            //         make sure to not exclude present and future values (latest approved and pending)
-            //
-            // condition(s)
-            //     exclude content (with latest) before latest
-            //     exclude content (with latest) after  latest (cancelled, rejected)
-            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
-            //         <-->
-            //         select * from structure s
-            //         where (
-            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
-            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
-            //         )
-            //         <-->
-            //                     not (exists (subquery id) and s.id < (subquery id))
-            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (subquery id) and s.id < (subquery 2))
-            //
-            // note
-            //     persistence libraries may optimize query
-            //         e.g. change (!a and !b) to !(a or b)
-
-            Subquery<Long> sub = cq.subquery(Long.class);
-            Root<Discipline> fromSub = sub.from(Discipline.class);
-            sub.where(cb.and(
-                    cb.equal(fromSub.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub.get(NameStructure.FIELD_LATEST), Boolean.TRUE)
-                    ));
-            sub.select(fromSub.get(Persistable.FIELD_ID));
-
-            Subquery<Long> sub2 = cq.subquery(Long.class);
-            Root<Discipline> fromSub2 = sub2.from(Discipline.class);
-            sub2.where(cb.and(
-                    cb.equal(fromSub2.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub2.get(NameStructure.FIELD_LATEST), Boolean.FALSE)
-                    ));
-            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
-
-            Predicate predicateExclude =
-                    cb.and(
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
-                                    cb.or(
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.CANCELLED),
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.REJECTED)))),
-                            cb.not(cb.and(
-                                    cb.not(cb.exists(sub)),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
-                            );
-            predicates.add(predicateExclude);
-        }
-
         if (deleted != null) {
             predicates.add(cb.equal(from.get(NameStructure.FIELD_DELETED), deleted));
         }
@@ -305,96 +235,6 @@ public class DisciplineRepository {
         }
     }
 
-    /**
-     * Count disciplines history.
-     *
-     * @param uuid uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @return count of disciplines
-     */
-    public Long countDisciplinesHistory(
-            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
-
-        // note
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
-        Root<Discipline> from = cq.from(Discipline.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<Discipline> fromSub = sub.from(Discipline.class);
-        sub.where(cb.and(preparePredicatesDisciplines(cb, cq, fromSub, null,
-                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(cb.count(from));
-
-        return em.createQuery(cq).getSingleResult();
-    }
-
-    /**
-     * Find disciplines history.
-     *
-     * @param uuid uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @param orderBy order by
-     * @param isAsc is ascending
-     * @return list of disciplines
-     */
-    public List<Discipline> readDisciplinesHistory(
-            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            FieldStructure orderBy, Boolean isAsc) {
-
-        // note
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-        // order
-        //     orderBy, isAsc
-        // paging
-        //     outside of method
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Discipline> cq = cb.createQuery(Discipline.class);
-        Root<Discipline> from = cq.from(Discipline.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<Discipline> fromSub = sub.from(Discipline.class);
-        sub.where(cb.and(preparePredicatesDisciplines(cb, cq, fromSub, null,
-                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(from);
-
-        if (orderBy != null) {
-            Expression<String> exp = orderBy(from, orderBy);
-            if (BooleanUtils.toBoolean(isAsc)) {
-                cq.orderBy(cb.asc(exp));
-            } else {
-                cq.orderBy(cb.desc(exp));
-            }
-        }
-
-        return em.createQuery(cq).getResultList();
-    }
-
     /**
      * Persist discipline into persistence context.
      *
diff --git a/src/main/java/org/openepics/names/repository/IAuditNameRepository.java b/src/main/java/org/openepics/names/repository/IAuditNameRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..f4844dcbe5aed8f9110cb485178c16fc332eeb05
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/IAuditNameRepository.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 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.repository;
+
+import java.util.Date;
+import java.util.List;
+
+import org.openepics.names.repository.model.AuditName;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find audit name (device) information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IAuditNameRepository extends JpaRepository<AuditName, Long> {
+
+    @Query("SELECT aun FROM AuditName aun "
+            + "WHERE aun.uuid = ?1 "
+            + "AND aun.status = 'APPROVED' "
+            + "AND aun.auditId = (select max(aun2.auditId) from AuditName aun2 where aun2.uuid = aun.uuid and aun2.auditId < ?2)")
+    AuditName findPreviousByUuidAndAuditId(String uuid, Long id);
+
+    @Query("FROM AuditName aun WHERE aun.requested >= ?1 AND aun.requested <= ?2")
+    List<AuditName> findByRequestedBetween(Date from, Date to);
+
+    @Query("FROM AuditName aun WHERE aun.uuid = ?1")
+    List<AuditName> findByUuid(String uuid);
+
+}
diff --git a/src/main/java/org/openepics/names/repository/IAuditStructureRepository.java b/src/main/java/org/openepics/names/repository/IAuditStructureRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..23cba4b455732fba034596a2e878c5fd4f0e8ffa
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/IAuditStructureRepository.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 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.repository;
+
+import org.openepics.names.repository.model.AuditStructure;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find audit structure (name part) information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IAuditStructureRepository extends JpaRepository<AuditStructure, Long> {
+
+    @Query("SELECT aus FROM AuditStructure aus "
+            + "WHERE aus.auditTable = ?1 "
+            + "AND aus.uuid = ?2 "
+            + "AND aus.status = 'APPROVED' "
+            + "AND aus.auditId = (select max(aus2.auditId) from AuditStructure aus2 where aus2.uuid = aus.uuid and aus2.auditId < ?3)")
+    AuditStructure findPreviousByAuditTableAndUuidAndAuditId(String auditTable, String uuid, Long id);
+
+}
diff --git a/src/main/java/org/openepics/names/repository/IDeviceGroupRepository.java b/src/main/java/org/openepics/names/repository/IDeviceGroupRepository.java
index c6946bf2d51a12ba49a1e53490e246b920a89d19..f848d2250dea38f232fdba01b9fd3ffabba8370a 100644
--- a/src/main/java/org/openepics/names/repository/IDeviceGroupRepository.java
+++ b/src/main/java/org/openepics/names/repository/IDeviceGroupRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -33,26 +33,13 @@ import org.springframework.stereotype.Repository;
 @Repository
 public interface IDeviceGroupRepository extends JpaRepository<DeviceGroup, Long> {
 
-    // old + verification
-
-    @Query("FROM DeviceGroup dg WHERE dg.latest = true AND dg.uuid = ?1")
-    DeviceGroup findLatestByUuid(String uuid);
-
     @Query("FROM DeviceGroup dg WHERE dg.uuid = ?1")
-    List<DeviceGroup> findByUuid(String uuid);
-
-    // ----------------------------------------------------------------------------------------------------
-
-    @Query("FROM DeviceGroup dg WHERE dg.latest = true")
-    List<DeviceGroup> findLatest();
-
-    @Query("FROM DeviceGroup dg WHERE dg.latest = true AND dg.deleted = false")
-    List<DeviceGroup> findLatestNotDeleted();
+    DeviceGroup findByUuid(String uuid);
 
-    @Query("FROM DeviceGroup dg WHERE dg.latest = true AND dg.deleted = false AND dg.parentUuid = ?1")
-    List<DeviceGroup> findLatestNotDeletedByParent(String uuid);
+    @Query("FROM DeviceGroup dg WHERE dg.deleted = false")
+    List<DeviceGroup> findNotDeleted();
 
-    @Query("FROM DeviceGroup dg WHERE dg.uuid = ?1 AND dg.id < ?2 ORDER BY dg.id DESC")
-    List<DeviceGroup> findPreviousByUuidAndId(String uuid, Long id);
+    @Query("FROM DeviceGroup dg WHERE dg.deleted = false AND dg.parentId = ?1")
+    List<DeviceGroup> findNotDeletedByParent(Long id);
 
 }
diff --git a/src/main/java/org/openepics/names/repository/IDeviceTypeRepository.java b/src/main/java/org/openepics/names/repository/IDeviceTypeRepository.java
index 40fe081a9dbfb533accca88980e4adb02841a349..cdfd310b71c0ef1aecad6137c313088008c5cde2 100644
--- a/src/main/java/org/openepics/names/repository/IDeviceTypeRepository.java
+++ b/src/main/java/org/openepics/names/repository/IDeviceTypeRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -33,29 +33,13 @@ import org.springframework.stereotype.Repository;
 @Repository
 public interface IDeviceTypeRepository extends JpaRepository<DeviceType, Long> {
 
-    // old + verification
-
     @Query("FROM DeviceType dt WHERE dt.uuid = ?1")
-    List<DeviceType> findByUuid(String uuid);
-
-    @Query("FROM DeviceType dt WHERE dt.latest = true AND dt.mnemonic = ?1")
-    List<DeviceType> findLatestByMnemonic(String mnemonic);
-
-    // ----------------------------------------------------------------------------------------------------
-
-    @Query("FROM DeviceType dt WHERE dt.latest = true AND dt.uuid = ?1")
-    DeviceType findLatestByUuid(String uuid);
-
-    @Query("FROM DeviceType dt WHERE dt.latest = true")
-    List<DeviceType> findLatest();
-
-    @Query("FROM DeviceType dt WHERE dt.latest = true AND dt.deleted = false")
-    List<DeviceType> findLatestNotDeleted();
+    DeviceType findByUuid(String uuid);
 
-    @Query("FROM DeviceType dt WHERE dt.latest = true AND dt.deleted = false AND dt.parentUuid = ?1")
-    List<DeviceType> findLatestNotDeletedByParent(String uuid);
+    @Query("FROM DeviceType dt WHERE dt.deleted = false")
+    List<DeviceType> findNotDeleted();
 
-    @Query("FROM DeviceType dt WHERE dt.uuid = ?1 AND dt.id < ?2 ORDER BY dt.id DESC")
-    List<DeviceType> findPreviousByUuidAndId(String uuid, Long id);
+    @Query("FROM DeviceType dt WHERE dt.deleted = false AND dt.parentId = ?1")
+    List<DeviceType> findNotDeletedByParent(Long id);
 
 }
diff --git a/src/main/java/org/openepics/names/repository/IDisciplineRepository.java b/src/main/java/org/openepics/names/repository/IDisciplineRepository.java
index e6da1e52637945ecad41bbf862c49df76b5c0658..0ccabb581c88ef3751c868871e8418389c65b3aa 100644
--- a/src/main/java/org/openepics/names/repository/IDisciplineRepository.java
+++ b/src/main/java/org/openepics/names/repository/IDisciplineRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -33,29 +33,13 @@ import org.springframework.stereotype.Repository;
 @Repository
 public interface IDisciplineRepository extends JpaRepository<Discipline, Long> {
 
-    // old + verification
-
-    @Query("FROM Discipline di WHERE di.latest = true AND di.uuid = ?1")
-    Discipline findLatestByUuid(String uuid);
-
     @Query("FROM Discipline di WHERE di.uuid = ?1")
-    List<Discipline> findByUuid(String uuid);
-
-    @Query("FROM Discipline di WHERE di.latest = true AND di.mnemonic = ?1")
-    List<Discipline> findLatestByMnemonic(String mnemonic);
-
-    // ----------------------------------------------------------------------------------------------------
-
-    @Query("FROM Discipline di WHERE di.latest = true AND di.deleted = false AND di.mnemonic = ?1")
-    Discipline findLatestNotDeletedByMnemonic(String mnemonic);
-
-    @Query("FROM Discipline di WHERE di.latest = true")
-    List<Discipline> findLatest();
+    Discipline findByUuid(String uuid);
 
-    @Query("FROM Discipline di WHERE di.latest = true AND di.deleted = false")
-    List<Discipline> findLatestNotDeleted();
+    @Query("FROM Discipline di WHERE di.deleted = false AND di.mnemonic = ?1")
+    Discipline findNotDeletedByMnemonic(String mnemonic);
 
-    @Query("FROM Discipline di WHERE di.uuid = ?1 AND di.id < ?2 ORDER BY di.id DESC")
-    List<Discipline> findPreviousByUuidAndId(String uuid, Long id);
+    @Query("FROM Discipline di WHERE di.deleted = false")
+    List<Discipline> findNotDeleted();
 
 }
diff --git a/src/main/java/org/openepics/names/repository/INameRepository.java b/src/main/java/org/openepics/names/repository/INameRepository.java
index 0358dace0d7710041a2229d5750ded76a64ee0c3..ee408b045f2af6d2141511554b89cd3ecddf733f 100644
--- a/src/main/java/org/openepics/names/repository/INameRepository.java
+++ b/src/main/java/org/openepics/names/repository/INameRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -18,7 +18,6 @@
 
 package org.openepics.names.repository;
 
-import java.util.Date;
 import java.util.List;
 
 import org.openepics.names.repository.model.Name;
@@ -27,139 +26,53 @@ import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 
 /**
- * Find name information in JPA.
+ * Find name (device) information in JPA.
  *
  * @author Lars Johansson
  */
 @Repository
 public interface INameRepository extends JpaRepository<Name, Long> {
 
-    // old + verification
-
-    @Query("FROM Name n WHERE n.latest = true AND n.conventionName = ?1")
-    Name findLatestByConventionName(String conventionName);
-
-    @Query("FROM Name n WHERE n.latest = true")
-    List<Name> findLatest();
-
-    @Query("FROM Name n WHERE n.latest = true AND n.deleted = false")
-    List<Name> findLatestNotDeleted();
-
-    @Query("SELECT n FROM Name n, SystemGroup sg "
-            + "WHERE n.latest = true "
-            + "AND sg.uuid = n.systemGroupUuid "
-            + "AND sg.latest = true "
-            + "AND sg.mnemonic = ?1")
-    List<Name> findLatestBySystemGroupMnemonic(String mnemonic);
-
-    @Query("SELECT n FROM Name n, System sys "
-            + "WHERE n.latest = true "
-            + "AND sys.uuid = n.systemUuid "
-            + "AND sys.latest = true "
-            + "AND sys.mnemonic = ?1")
-    List<Name> findLatestBySystemMnemonic(String mnemonic);
-
-    @Query("SELECT n FROM Name n, Subsystem sub, System sys "
-            + "WHERE n.latest = true "
-            + "AND sub.uuid = n.subsystemUuid "
-            + "AND sub.latest = true "
-            + "AND sys.uuid = sub.parentUuid  "
-            + "AND sys.latest = true "
-            + "AND sys.mnemonic = ?1")
-    List<Name> findLatestBySystemMnemonicThroughSubsystem(String mnemonic);
-
-    @Query("SELECT n FROM Name n, Subsystem sub "
-            + "WHERE n.latest = true "
-            + "AND sub.uuid = n.subsystemUuid "
-            + "AND sub.latest = true "
-            + "AND sub.mnemonic = ?1")
-    List<Name> findLatestBySubsystemMnemonic(String mnemonic);
-
-    @Query("SELECT n FROM Name n, DeviceType dt, DeviceGroup dg, Discipline di "
-            + "WHERE n.latest = true "
-            + "AND dt.uuid = n.deviceTypeUuid "
-            + "AND dt.latest = true "
-            + "AND dg.uuid = dt.parentUuid "
-            + "AND dg.latest = true "
-            + "AND di.uuid = dg.parentUuid "
-            + "AND di.latest = true "
-            + "AND di.mnemonic = ?1")
-    List<Name> findLatestByDisciplineMnemonicThroughDeviceType(String mnemonic);
-
-    @Query("SELECT n FROM Name n, DeviceType dt "
-            + "WHERE n.latest = true "
-            + "AND dt.uuid = n.deviceTypeUuid "
-            + "AND dt.latest = true "
-            + "AND dt.mnemonic = ?1")
-    List<Name> findLatestByDeviceTypeMnemonic(String mnemonic);
-
-    // ----------------------------------------------------------------------------------------------------
-
-    @Query("FROM Name n WHERE n.latest = true AND n.uuid = ?1")
-    Name findLatestByUuid(String uuid);
-
     @Query("FROM Name n WHERE n.uuid = ?1")
-    List<Name> findByUuid(String uuid);
-
-    // ----------------------------------------------------------------------------------------------------
+    Name findByUuid(String uuid);
 
     @Query("SELECT n FROM Name n, SystemGroup sg "
-            + "WHERE n.latest = true "
-            + "AND n.deleted = false "
-            + "AND sg.uuid = n.systemGroupUuid "
-            + "AND sg.latest = true "
+            + "WHERE n.deleted = false "
+            + "AND sg.id = n.systemGroupId "
             + "AND sg.uuid = ?1")
-    List<Name> findLatestNotDeletedBySystemGroupUuid(String uuid);
+    List<Name> findNotDeletedBySystemGroupUuid(String uuid);
 
     @Query("SELECT n FROM Name n, System sys "
-            + "WHERE n.latest = true "
-            + "AND n.deleted = false "
-            + "AND sys.uuid = n.systemUuid "
-            + "AND sys.latest = true "
+            + "WHERE n.deleted = false "
+            + "AND sys.id = n.systemId "
             + "AND sys.uuid = ?1")
-    List<Name> findLatestNotDeletedBySystemUuid(String uuid);
+    List<Name> findNotDeletedBySystemUuid(String uuid);
 
     @Query("SELECT n FROM Name n, Subsystem sub, System sys "
-            + "WHERE n.latest = true "
-            + "AND n.deleted = false "
-            + "AND sub.uuid = n.subsystemUuid "
-            + "AND sub.latest = true "
-            + "AND sys.uuid = sub.parentUuid  "
-            + "AND sys.latest = true "
+            + "WHERE n.deleted = false "
+            + "AND sub.id = n.subsystemId "
+            + "AND sys.id = sub.parentId  "
             + "AND sys.uuid = ?1")
-    List<Name> findLatestNotDeletedBySystemUuidThroughSubsystem(String uuid);
+    List<Name> findNotDeletedBySystemUuidThroughSubsystem(String uuid);
 
     @Query("SELECT n FROM Name n, Subsystem sub "
-            + "WHERE n.latest = true "
-            + "AND n.deleted = false "
-            + "AND sub.uuid = n.subsystemUuid "
-            + "AND sub.latest = true "
+            + "WHERE n.deleted = false "
+            + "AND sub.id = n.subsystemId "
             + "AND sub.uuid = ?1")
-    List<Name> findLatestNotDeletedBySubsystemUuid(String uuid);
+    List<Name> findNotDeletedBySubsystemUuid(String uuid);
 
     @Query("SELECT n FROM Name n, DeviceType dt, DeviceGroup dg, Discipline di "
-            + "WHERE n.latest = true "
-            + "AND n.deleted = false "
-            + "AND dt.uuid = n.deviceTypeUuid "
-            + "AND dt.latest = true "
-            + "AND dg.uuid = dt.parentUuid "
-            + "AND dg.latest = true "
-            + "AND di.uuid = dg.parentUuid "
-            + "AND di.latest = true "
+            + "WHERE n.deleted = false "
+            + "AND dt.id = n.deviceTypeId "
+            + "AND dg.id = dt.parentId "
+            + "AND di.id = dg.parentId "
             + "AND di.uuid = ?1")
-    List<Name> findLatestNotDeletedByDisciplineUuidThroughDeviceType(String uuid);
+    List<Name> findNotDeletedByDisciplineUuidThroughDeviceType(String uuid);
 
     @Query("SELECT n FROM Name n, DeviceType dt "
-            + "WHERE n.latest = true "
-            + "AND n.deleted = false "
-            + "AND dt.uuid = n.deviceTypeUuid "
-            + "AND dt.latest = true "
+            + "WHERE n.deleted = false "
+            + "AND dt.id = n.deviceTypeId "
             + "AND dt.uuid = ?1")
-    List<Name> findLatestNotDeletedByDeviceTypeUuid(String uuid);
-
-    // ----------------------------------------------------------------------------------------------------
-
-    @Query("FROM Name n WHERE n.requested >= ?1 AND n.requested <= ?2")
-    List<Name> findByRequestedBetween(Date from, Date to);
+    List<Name> findNotDeletedByDeviceTypeUuid(String uuid);
 
 }
diff --git a/src/main/java/org/openepics/names/repository/ISubsystemRepository.java b/src/main/java/org/openepics/names/repository/ISubsystemRepository.java
index 7d8fadb99548f6992c7d8dc15291ad66de3a58f0..745ea0f9341b6839ff7c9739d3c2be4fcce7cbc4 100644
--- a/src/main/java/org/openepics/names/repository/ISubsystemRepository.java
+++ b/src/main/java/org/openepics/names/repository/ISubsystemRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -26,36 +26,20 @@ import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 
 /**
- * Find subsystem structure (name part)information in JPA.
+ * Find subsystem structure (name part) information in JPA.
  *
  * @author Lars Johansson
  */
 @Repository
 public interface ISubsystemRepository extends JpaRepository<Subsystem, Long> {
 
-    // old + verification
-
     @Query("FROM Subsystem sub WHERE sub.uuid = ?1")
-    List<Subsystem> findByUuid(String uuid);
-
-    @Query("FROM Subsystem sub WHERE sub.latest = true AND sub.mnemonic = ?1")
-    List<Subsystem> findLatestByMnemonic(String mnemonic);
-
-    // ----------------------------------------------------------------------------------------------------
-
-    @Query("FROM Subsystem sub WHERE sub.latest = true AND sub.uuid = ?1")
-    Subsystem findLatestByUuid(String uuid);
-
-    @Query("FROM Subsystem sub WHERE sub.latest = true")
-    List<Subsystem> findLatest();
-
-    @Query("FROM Subsystem sub WHERE sub.latest = true AND sub.deleted = false")
-    List<Subsystem> findLatestNotDeleted();
+    Subsystem findByUuid(String uuid);
 
-    @Query("FROM Subsystem sub WHERE sub.latest = true AND sub.deleted = false AND sub.parentUuid = ?1")
-    List<Subsystem> findLatestNotDeletedByParent(String uuid);
+    @Query("FROM Subsystem sub WHERE sub.deleted = false")
+    List<Subsystem> findNotDeleted();
 
-    @Query("FROM Subsystem sub WHERE sub.uuid = ?1 AND sub.id < ?2 ORDER BY sub.id DESC")
-    List<Subsystem> findPreviousByUuidAndId(String uuid, Long id);
+    @Query("FROM Subsystem sub WHERE sub.deleted = false AND sub.parentId = ?1")
+    List<Subsystem> findNotDeletedByParent(Long id);
 
 }
diff --git a/src/main/java/org/openepics/names/repository/ISystemGroupRepository.java b/src/main/java/org/openepics/names/repository/ISystemGroupRepository.java
index 8ea653b569a2ba51dc9fa33fb93bf15faded3da1..e241125bfb035f57cf6543a4d34a790383ba3503 100644
--- a/src/main/java/org/openepics/names/repository/ISystemGroupRepository.java
+++ b/src/main/java/org/openepics/names/repository/ISystemGroupRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -33,32 +33,16 @@ import org.springframework.stereotype.Repository;
 @Repository
 public interface ISystemGroupRepository extends JpaRepository<SystemGroup, Long> {
 
-    // old + verification
-
     @Query("FROM SystemGroup sg WHERE sg.uuid = ?1")
-    List<SystemGroup> findByUuid(String uuid);
-
-    @Query("FROM SystemGroup sg WHERE sg.latest = true AND sg.mnemonic = ?1")
-    List<SystemGroup> findLatestByMnemonic(String mnemonic);
-
-    // ----------------------------------------------------------------------------------------------------
-
-    @Query("FROM SystemGroup sg WHERE sg.latest = true AND sg.uuid = ?1")
-    SystemGroup findLatestByUuid(String uuid);
-
-    @Query("FROM SystemGroup sg WHERE sg.latest = true AND sg.deleted = false AND sg.mnemonic = ?1")
-    SystemGroup findLatestNotDeletedByMnemonic(String mnemonic);
-
-    @Query("FROM SystemGroup sg WHERE sg.latest = true AND sg.deleted = false AND sg.uuid = ?1")
-    SystemGroup findLatestNotDeletedByUuid(String uuid);
+    SystemGroup findByUuid(String uuid);
 
-    @Query("FROM SystemGroup sg WHERE sg.latest = true")
-    List<SystemGroup> findLatest();
+    @Query("FROM SystemGroup sg WHERE sg.deleted = false AND sg.mnemonic = ?1")
+    SystemGroup findNotDeletedByMnemonic(String mnemonic);
 
-    @Query("FROM SystemGroup sg WHERE sg.latest = true AND sg.deleted = false")
-    List<SystemGroup> findLatestNotDeleted();
+    @Query("FROM SystemGroup sg WHERE sg.deleted = false AND sg.id = ?1")
+    SystemGroup findNotDeletedById(Long id);
 
-    @Query("FROM SystemGroup sg WHERE sg.uuid = ?1 AND sg.id < ?2 ORDER BY sg.id DESC")
-    List<SystemGroup> findPreviousByUuidAndId(String uuid, Long id);
+    @Query("FROM SystemGroup sg WHERE sg.deleted = false")
+    List<SystemGroup> findNotDeleted();
 
 }
diff --git a/src/main/java/org/openepics/names/repository/ISystemRepository.java b/src/main/java/org/openepics/names/repository/ISystemRepository.java
index 9b5d1591a0dfeffc72eb4ac6ca22c8b6a7e8379d..3a9db5cce00bf40704579cd72f1c9dcc86a0c63a 100644
--- a/src/main/java/org/openepics/names/repository/ISystemRepository.java
+++ b/src/main/java/org/openepics/names/repository/ISystemRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -33,32 +33,16 @@ import org.springframework.stereotype.Repository;
 @Repository
 public interface ISystemRepository extends JpaRepository<System, Long> {
 
-    // old + verification
-
     @Query("FROM System sys WHERE sys.uuid = ?1")
-    List<System> findByUuid(String uuid);
-
-    @Query("FROM System sys WHERE sys.latest = true AND sys.mnemonic = ?1")
-    List<System> findLatestByMnemonic(String mnemonic);
-
-    // ----------------------------------------------------------------------------------------------------
-
-    @Query("FROM System sys WHERE sys.latest = true AND sys.uuid = ?1")
-    System findLatestByUuid(String uuid);
-
-    @Query("FROM System sys WHERE sys.latest = true AND sys.deleted = false AND sys.mnemonic = ?1")
-    System findLatestNotDeletedByMnemonic(String mnemonic);
-
-    @Query("FROM System sys WHERE sys.latest = true")
-    List<System> findLatest();
+    System findByUuid(String uuid);
 
-    @Query("FROM System sys WHERE sys.latest = true AND sys.deleted = false")
-    List<System> findLatestNotDeleted();
+    @Query("FROM System sys WHERE sys.deleted = false AND sys.mnemonic = ?1")
+    System findNotDeletedByMnemonic(String mnemonic);
 
-    @Query("FROM System sys WHERE sys.latest = true AND sys.deleted = false AND sys.parentUuid = ?1")
-    List<System> findLatestNotDeletedByParent(String uuid);
+    @Query("FROM System sys WHERE sys.deleted = false")
+    List<System> findNotDeleted();
 
-    @Query("FROM System sys WHERE sys.uuid = ?1 AND sys.id < ?2 ORDER BY sys.id DESC")
-    List<System> findPreviousByUuidAndId(String uuid, Long id);
+    @Query("FROM System sys WHERE sys.deleted = false AND sys.parentId = ?1")
+    List<System> findNotDeletedByParent(Long id);
 
 }
diff --git a/src/main/java/org/openepics/names/repository/NameRepository.java b/src/main/java/org/openepics/names/repository/NameRepository.java
index a5866568ec13b651322d317938195f8d1faea74c..e2952e5c9305186522c3af1b631fbe48c80277dd 100644
--- a/src/main/java/org/openepics/names/repository/NameRepository.java
+++ b/src/main/java/org/openepics/names/repository/NameRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -30,7 +30,6 @@ import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
-import javax.persistence.criteria.Subquery;
 
 import org.apache.commons.compress.utils.Lists;
 import org.apache.commons.lang3.BooleanUtils;
@@ -79,17 +78,15 @@ public class NameRepository {
      * @param index index
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return count of names
      */
     public Long countNames(Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who) {
 
         // note
         //     use of function for mnemonic path
         // where
-        //     latest, deleted
+        //     deleted
         //     queryFields, queryValues
 
         CriteriaBuilder cb = em.getCriteriaBuilder();
@@ -97,8 +94,7 @@ public class NameRepository {
         Root<Name> from = cq.from(Name.class);
 
         cq.where(cb.and(preparePredicatesNames(cb, from, deleted,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who).toArray(new Predicate[0])));
         cq.select(cb.count(from));
 
         return em.createQuery(cq).getSingleResult();
@@ -123,7 +119,7 @@ public class NameRepository {
 
         return readNames(deleted,
                 uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
-                Boolean.FALSE, null, null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -138,7 +134,6 @@ public class NameRepository {
      * @param index index
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @param orderBy order by
      * @param isAsc is ascending
      * @param offset offset
@@ -147,12 +142,12 @@ public class NameRepository {
      */
     public List<Name> readNames(Boolean deleted,
             String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
-            Boolean includeHistory, FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
+            FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
         // note
         //     use of function for mnemonic path
         // where
-        //     latest, deleted
+        //     deleted
         //     queryFields, queryValues
         // order
         //     orderBy, isAsc
@@ -164,8 +159,7 @@ public class NameRepository {
         Root<Name> from = cq.from(Name.class);
 
         cq.where(cb.and(preparePredicatesNames(cb, from, deleted,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who).toArray(new Predicate[0])));
         cq.select(from);
 
         if (orderBy != null) {
@@ -200,30 +194,13 @@ public class NameRepository {
      * @param index index
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return list of predicates
      */
     private List<Predicate> preparePredicatesNames(CriteriaBuilder cb, Root<Name> from, Boolean deleted,
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who) {
 
         List<Predicate> predicates = new ArrayList<>();
 
-        if (!Boolean.TRUE.equals(includeHistory)) {
-            // purpose of Naming to show valid entries
-            //     therefore
-            //         exclude some values unless history requested
-            //         make sure to not exclude present and future values
-            //
-            // exclude not latest
-            //     select * from Name n where
-            //         not(n.latest = false)
-
-            Predicate predicateNotLatest = cb.equal(from.get(NameStructure.FIELD_LATEST), Boolean.FALSE);
-            Predicate predicateExclude   = cb.not(cb.and(predicateNotLatest));
-            predicates.add(predicateExclude);
-        }
-
         if (deleted != null) {
             predicates.add(cb.equal(from.get(NameStructure.FIELD_DELETED), deleted));
         }
@@ -286,110 +263,6 @@ public class NameRepository {
         }
     }
 
-    /**
-     * Count names history.
-     *
-     * @param uuid uuid
-     * @param name name
-     * @param nameEquivalence name equivalence
-     * @param systemStructure system structure mnemonic
-     * @param deviceStructure device structure mnemonic
-     * @param index index
-     * @param description description
-     * @param who who
-     * @return count of names
-     */
-    public Long countNamesHistory(
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
-        Root<Name> from = cq.from(Name.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<Name> fromSub = sub.from(Name.class);
-        sub.where(cb.and(preparePredicatesNames(cb, fromSub, null,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(cb.count(from));
-
-        return em.createQuery(cq).getSingleResult();
-    }
-
-    /**
-     * Find names history.
-     *
-     * @param uuid uuid
-     * @param name name
-     * @param nameEquivalence name equivalence
-     * @param systemStructure system structure mnemonic
-     * @param deviceStructure device structure mnemonic
-     * @param index index
-     * @param description description
-     * @param who who
-     * @param orderBy order by
-     * @param isAsc is ascending
-     * @param offset offset
-     * @param limit limit
-     * @return list of names
-     */
-    public List<Name> readNamesHistory(
-            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
-            FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-        // order
-        //     orderBy, isAsc
-        // paging
-        //     offset, limit
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Name> cq = cb.createQuery(Name.class);
-        Root<Name> from = cq.from(Name.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<Name> fromSub = sub.from(Name.class);
-        sub.where(cb.and(preparePredicatesNames(cb, fromSub, null,
-                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(from);
-
-        if (orderBy != null) {
-            Expression<String> exp = orderBy(cb, from, orderBy);
-            if (BooleanUtils.toBoolean(isAsc)) {
-                cq.orderBy(cb.asc(exp));
-            } else {
-                cq.orderBy(cb.desc(exp));
-            }
-        }
-
-        TypedQuery<Name> query = em.createQuery(cq);
-        if (offset != null && limit != null) {
-            query.setFirstResult(offset * limit);
-            query.setMaxResults(limit);
-        }
-
-        return query.getResultList();
-    }
-
     /**
      * Find names by structure uuid.
      *
@@ -401,7 +274,7 @@ public class NameRepository {
      * @return list of names
      */
     @SuppressWarnings("unchecked")
-    public List<Name> readNamesLatestByStructure(NameByStructure nameByStructure, String uuid, Boolean deleted,
+    public List<Name> readNamesByStructure(NameByStructure nameByStructure, String uuid, Boolean deleted,
             FieldName orderBy, Boolean isAsc) {
 
         // must have NameByStructure
@@ -413,80 +286,55 @@ public class NameRepository {
         switch (nameByStructure) {
         case NAME_BY_SYSTEMGROUP:
             sql.append("SELECT n FROM Name n, SystemGroup sg "
-                    + "WHERE n.latest = true "
-                    + "AND sg.uuid = n.systemGroupUuid "
-                    + "AND sg.latest = true "
-                    + "AND sg.uuid = :sUuid");
+                    + "WHERE sg.id = n.systemGroupId "
+                    + "  AND sg.uuid = :sUuid");
             break;
         case NAME_BY_SYSTEMGROUP_THROUGH_SYSTEM:
             sql.append("SELECT n FROM Name n, System sys, SystemGroup sg "
-                    + "WHERE n.latest = true "
-                    + "AND sys.uuid = n.systemUuid "
-                    + "AND sys.latest = true "
-                    + "AND sg.uuid = sys.parentUuid  "
-                    + "AND sg.latest = true "
-                    + "AND sg.uuid = :sUuid");
+                    + "WHERE sys.id = n.systemId "
+                    + "  AND sg.id = sys.parentId  "
+                    + "  AND sg.uuid = :sUuid");
             break;
         case NAME_BY_SYSTEMGROUP_THROUGH_SUBSYSTEM:
             sql.append("SELECT n FROM Name n, Subsystem sub, System sys, SystemGroup sg "
-                    + "WHERE n.latest = true "
-                    + "AND sub.uuid = n.subsystemUuid "
-                    + "AND sub.latest = true "
-                    + "AND sys.uuid = sub.parentUuid  "
-                    + "AND sys.latest = true "
-                    + "AND sg.uuid = sys.parentUuid  "
-                    + "AND sg.latest = true "
-                    + "AND sg.uuid = :sUuid");
+                    + "WHERE sub.id = n.subsystemId "
+                    + "  AND sys.id = sub.parentId  "
+                    + "  AND sg.id = sys.parentId  "
+                    + "  AND sg.uuid = :sUuid");
             break;
         case NAME_BY_SYSTEM:
             sql.append("SELECT n FROM Name n, System sys "
-                    + "WHERE n.latest = true "
-                    + "AND sys.uuid = n.systemUuid "
-                    + "AND sys.latest = true "
-                    + "AND sys.uuid = :sUuid");
+                    + "WHERE sys.id = n.systemId "
+                    + "  AND sys.uuid = :sUuid");
             break;
         case NAME_BY_SYSTEM_THROUGH_SUBSYSTEM:
             sql.append("SELECT n FROM Name n, Subsystem sub, System sys "
-                    + "WHERE n.latest = true "
-                    + "AND sub.uuid = n.subsystemUuid "
-                    + "AND sub.latest = true "
-                    + "AND sys.uuid = sub.parentUuid  "
-                    + "AND sys.latest = true "
-                    + "AND sys.uuid = :sUuid");
+                    + "WHERE sub.id = n.subsystemId "
+                    + "  AND sys.id = sub.parentId  "
+                    + "  AND sys.uuid = :sUuid");
             break;
         case NAME_BY_SUBSYSTEM:
             sql.append("SELECT n FROM Name n, Subsystem sub "
-                    + "WHERE n.latest = true "
-                    + "AND sub.uuid = n.subsystemUuid "
-                    + "AND sub.latest = true "
-                    + "AND sub.uuid = :sUuid");
+                    + "WHERE sub.id = n.subsystemId "
+                    + "  AND sub.uuid = :sUuid");
             break;
         case NAME_BY_DISCIPLINE_THROUGH_DEVICETYPE:
             sql.append("SELECT n FROM Name n, DeviceType dt, DeviceGroup dg, Discipline di "
-                    + "WHERE n.latest = true "
-                    + "AND dt.uuid = n.deviceTypeUuid "
-                    + "AND dt.latest = true "
-                    + "AND dg.uuid = dt.parentUuid "
-                    + "AND dg.latest = true "
-                    + "AND di.uuid = dg.parentUuid "
-                    + "AND di.latest = true "
-                    + "AND di.uuid = :sUuid");
+                    + "WHERE dt.id = n.deviceTypeId "
+                    + "  AND dg.id = dt.parentId "
+                    + "  AND di.id = dg.parentId "
+                    + "  AND di.uuid = :sUuid");
             break;
         case NAME_BY_DEVICEGROUP_THROUGH_DEVICETYPE:
             sql.append("SELECT n FROM Name n, DeviceType dt, DeviceGroup dg "
-                    + "WHERE n.latest = true "
-                    + "AND dt.uuid = n.deviceTypeUuid "
-                    + "AND dt.latest = true "
-                    + "AND dg.uuid = dt.parentUuid "
-                    + "AND dg.latest = true "
-                    + "AND dg.uuid = :sUuid");
+                    + "WHERE dt.id = n.deviceTypeId "
+                    + "  AND dg.id = dt.parentId "
+                    + "  AND dg.uuid = :sUuid");
             break;
         case NAME_BY_DEVICETYPE:
             sql.append("SELECT n FROM Name n, DeviceType dt "
-                    + "WHERE n.latest = true "
-                    + "AND dt.uuid = n.deviceTypeUuid "
-                    + "AND dt.latest = true "
-                    + "AND dt.uuid = :sUuid");
+                    + "WHERE dt.id = n.deviceTypeId "
+                    + "  AND dt.uuid = :sUuid");
             break;
         default: return Lists.newArrayList();
         }
diff --git a/src/main/java/org/openepics/names/repository/SubsystemRepository.java b/src/main/java/org/openepics/names/repository/SubsystemRepository.java
index 3ad59f3daeb3fd366374bc0eb021ea6bb52bc7cf..597482c43169baa555e6ce76005ee96f7d1502d5 100644
--- a/src/main/java/org/openepics/names/repository/SubsystemRepository.java
+++ b/src/main/java/org/openepics/names/repository/SubsystemRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -29,7 +29,6 @@ import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
-import javax.persistence.criteria.Subquery;
 
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -38,7 +37,6 @@ import org.openepics.names.repository.model.Persistable;
 import org.openepics.names.repository.model.Structure;
 import org.openepics.names.repository.model.Subsystem;
 import org.openepics.names.rest.beans.FieldStructure;
-import org.openepics.names.rest.beans.Status;
 import org.openepics.names.util.RepositoryUtil;
 import org.springframework.stereotype.Repository;
 
@@ -64,12 +62,10 @@ public class SubsystemRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return count of subsystems
      */
     public Long countSubsystems(Boolean deleted,
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         // note
         //     use of function for mnemonic path
@@ -82,8 +78,7 @@ public class SubsystemRepository {
         Root<Subsystem> from = cq.from(Subsystem.class);
 
         cq.where(cb.and(preparePredicatesSubsystems(cb, cq, from, deleted,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(cb.count(from));
 
         return em.createQuery(cq).getSingleResult();
@@ -107,7 +102,7 @@ public class SubsystemRepository {
 
         return readSubsystems(deleted,
                 uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.FALSE, null, null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -121,7 +116,6 @@ public class SubsystemRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @param orderBy order by
      * @param isAsc is ascending
      * @param offset offset
@@ -130,7 +124,7 @@ public class SubsystemRepository {
      */
     public List<Subsystem> readSubsystems(Boolean deleted,
             String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+            FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
         // note
         //     use of function for mnemonic path
@@ -147,8 +141,7 @@ public class SubsystemRepository {
         Root<Subsystem> from = cq.from(Subsystem.class);
 
         cq.where(cb.and(preparePredicatesSubsystems(cb, cq, from, deleted,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(from);
 
         if (orderBy != null) {
@@ -183,75 +176,13 @@ public class SubsystemRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return list of predicates
      */
     private List<Predicate> preparePredicatesSubsystems(CriteriaBuilder cb, CriteriaQuery cq, Root<Subsystem> from, Boolean deleted,
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         List<Predicate> predicates = new ArrayList<>();
 
-        if (!Boolean.TRUE.equals(includeHistory)) {
-            // purpose of Naming to show valid entries
-            //     therefore
-            //         exclude some values unless history requested
-            //         make sure to not exclude present and future values (latest approved and pending)
-            //
-            // condition(s)
-            //     exclude content (with latest) before latest
-            //     exclude content (with latest) after  latest (cancelled, rejected)
-            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
-            //         <-->
-            //         select * from structure s
-            //         where (
-            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
-            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
-            //         )
-            //         <-->
-            //                     not (exists (subquery id) and s.id < (subquery id))
-            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (subquery id) and s.id < (subquery 2))
-            //
-            // note
-            //     persistence libraries may optimize query
-            //         e.g. change (!a and !b) to !(a or b)
-
-            Subquery<Long> sub = cq.subquery(Long.class);
-            Root<Subsystem> fromSub = sub.from(Subsystem.class);
-            sub.where(cb.and(
-                    cb.equal(fromSub.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub.get(NameStructure.FIELD_LATEST), Boolean.TRUE)
-                    ));
-            sub.select(fromSub.get(Persistable.FIELD_ID));
-
-            Subquery<Long> sub2 = cq.subquery(Long.class);
-            Root<Subsystem> fromSub2 = sub2.from(Subsystem.class);
-            sub2.where(cb.and(
-                    cb.equal(fromSub2.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub2.get(NameStructure.FIELD_LATEST), Boolean.FALSE)
-                    ));
-            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
-
-            Predicate predicateExclude =
-                    cb.and(
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
-                                    cb.or(
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.CANCELLED),
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.REJECTED)))),
-                            cb.not(cb.and(
-                                    cb.not(cb.exists(sub)),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
-                            );
-            predicates.add(predicateExclude);
-        }
-
         if (deleted != null) {
             predicates.add(cb.equal(from.get(NameStructure.FIELD_DELETED), deleted));
         }
@@ -264,7 +195,7 @@ public class SubsystemRepository {
             predicates.add(cb.and(cb.equal(from.get(NameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
         }
         if (!StringUtils.isEmpty(parentUuid)) {
-            predicates.add(cb.and(cb.equal(from.get(Subsystem.FIELD_PARENT_UUID), RepositoryUtil.preparePattern(parentUuid))));
+            predicates.add(cb.and(cb.equal(cb.function(Subsystem.FUNCTION_GET_PARENT_UUID_SUBSYSTEM, String.class, from.get(Persistable.FIELD_ID)), RepositoryUtil.preparePattern(parentUuid))));
         }
         if (!StringUtils.isEmpty(mnemonic)) {
             predicates.add(cb.and(cb.like(from.get(Structure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
@@ -273,7 +204,7 @@ public class SubsystemRepository {
             predicates.add(cb.and(cb.like(from.get(Structure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
         }
         if (!StringUtils.isEmpty(mnemonicPath)) {
-            predicates.add(cb.and(cb.like(cb.function(Subsystem.FUNCTION_GET_MNEMONIC_PATH_SUBSYSTEM, String.class, from.get(NameStructure.FIELD_UUID)), RepositoryUtil.preparePattern(mnemonicPath))));
+            predicates.add(cb.and(cb.like(cb.function(Subsystem.FUNCTION_GET_MNEMONIC_PATH_SUBSYSTEM, String.class, from.get(Persistable.FIELD_ID)), RepositoryUtil.preparePattern(mnemonicPath))));
         }
         if (!StringUtils.isEmpty(description)) {
             predicates.add(cb.and(cb.like(from.get(NameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
@@ -296,7 +227,7 @@ public class SubsystemRepository {
         if (FieldStructure.UUID.equals(orderBy)) {
             return root.get(NameStructure.FIELD_UUID);
         } else if (FieldStructure.PARENT.equals(orderBy)) {
-            return root.get(Subsystem.FIELD_PARENT_UUID);
+            return root.get(Subsystem.FIELD_PARENT_ID);
         } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
             return root.get(Structure.FIELD_MNEMONIC);
         } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
@@ -312,100 +243,6 @@ public class SubsystemRepository {
         }
     }
 
-    /**
-     * Count subsystems history.
-     *
-     * @param uuid uuid
-     * @param parentUuid parent uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @return count of subsystems
-     */
-    public Long countSubsystemsHistory(
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
-        Root<Subsystem> from = cq.from(Subsystem.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<Subsystem> fromSub = sub.from(Subsystem.class);
-        sub.where(cb.and(preparePredicatesSubsystems(cb, cq, fromSub, null,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(cb.count(from));
-
-        return em.createQuery(cq).getSingleResult();
-    }
-
-    /**
-     * Find subsystems history.
-     *
-     * @param uuid uuid
-     * @param parentUuid parent uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @param orderBy order by
-     * @param isAsc is ascending
-     * @return list of subsystems
-     */
-    public List<Subsystem> readSubsystemsHistory(
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            FieldStructure orderBy, Boolean isAsc) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-        // order
-        //     orderBy, isAsc
-        // paging
-        //     outside of method
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Subsystem> cq = cb.createQuery(Subsystem.class);
-        Root<Subsystem> from = cq.from(Subsystem.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<Subsystem> fromSub = sub.from(Subsystem.class);
-        sub.where(cb.and(preparePredicatesSubsystems(cb, cq, fromSub, null,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(from);
-
-        if (orderBy != null) {
-            Expression<String> exp = orderBy(from, orderBy);
-            if (BooleanUtils.toBoolean(isAsc)) {
-                cq.orderBy(cb.asc(exp));
-            } else {
-                cq.orderBy(cb.desc(exp));
-            }
-        }
-
-        return em.createQuery(cq).getResultList();
-    }
-
     /**
      * Persist subsystem into persistence context.
      *
diff --git a/src/main/java/org/openepics/names/repository/SystemGroupRepository.java b/src/main/java/org/openepics/names/repository/SystemGroupRepository.java
index 53ee2440a85907838cd9157f20051ddd0fa52f82..1a6764b7cdfd221226938e7be361163cb897873f 100644
--- a/src/main/java/org/openepics/names/repository/SystemGroupRepository.java
+++ b/src/main/java/org/openepics/names/repository/SystemGroupRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -29,16 +29,13 @@ import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
-import javax.persistence.criteria.Subquery;
 
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.openepics.names.repository.model.NameStructure;
-import org.openepics.names.repository.model.Persistable;
 import org.openepics.names.repository.model.Structure;
 import org.openepics.names.repository.model.SystemGroup;
 import org.openepics.names.rest.beans.FieldStructure;
-import org.openepics.names.rest.beans.Status;
 import org.openepics.names.util.RepositoryUtil;
 import org.springframework.stereotype.Repository;
 
@@ -63,12 +60,10 @@ public class SystemGroupRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return count of system groups
      */
     public Long countSystemGroups(Boolean deleted,
-            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         // where
         //     deleted
@@ -79,8 +74,7 @@ public class SystemGroupRepository {
         Root<SystemGroup> from = cq.from(SystemGroup.class);
 
         cq.where(cb.and(preparePredicatesSystemGroups(cb, cq, from, deleted,
-                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(cb.count(from));
 
         return em.createQuery(cq).getSingleResult();
@@ -103,7 +97,7 @@ public class SystemGroupRepository {
 
         return readSystemGroups(deleted,
                 uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.FALSE, null, null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -116,7 +110,6 @@ public class SystemGroupRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @param orderBy order by
      * @param isAsc is ascending
      * @param offset offset
@@ -125,7 +118,7 @@ public class SystemGroupRepository {
      */
     public List<SystemGroup> readSystemGroups(Boolean deleted,
             String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+            FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
         // where
         //     deleted
@@ -140,8 +133,7 @@ public class SystemGroupRepository {
         Root<SystemGroup> from = cq.from(SystemGroup.class);
 
         cq.where(cb.and(preparePredicatesSystemGroups(cb, cq, from, deleted,
-                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(from);
 
         if (orderBy != null) {
@@ -175,75 +167,13 @@ public class SystemGroupRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return list of predicates
      */
     private List<Predicate> preparePredicatesSystemGroups(CriteriaBuilder cb, CriteriaQuery cq, Root<SystemGroup> from, Boolean deleted,
-            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         List<Predicate> predicates = new ArrayList<>();
 
-        if (!Boolean.TRUE.equals(includeHistory)) {
-            // purpose of Naming to show valid entries
-            //     therefore
-            //         exclude obsolete values unless history requested
-            //         make sure to not exclude present and future values (latest approved and pending)
-            //
-            // condition(s)
-            //     exclude content (with latest) before latest
-            //     exclude content (with latest) after  latest (cancelled, rejected)
-            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
-            //         <-->
-            //         select * from structure s
-            //         where (
-            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
-            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
-            //         )
-            //         <-->
-            //                     not (exists (subquery id) and s.id < (subquery id))
-            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (subquery id) and s.id < (subquery 2))
-            //
-            // note
-            //     persistence libraries may optimize query
-            //         e.g. change (!a and !b) to !(a or b)
-
-            Subquery<Long> sub = cq.subquery(Long.class);
-            Root<SystemGroup> fromSub = sub.from(SystemGroup.class);
-            sub.where(cb.and(
-                    cb.equal(fromSub.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub.get(NameStructure.FIELD_LATEST), Boolean.TRUE)
-                    ));
-            sub.select(fromSub.get(Persistable.FIELD_ID));
-
-            Subquery<Long> sub2 = cq.subquery(Long.class);
-            Root<SystemGroup> fromSub2 = sub2.from(SystemGroup.class);
-            sub2.where(cb.and(
-                    cb.equal(fromSub2.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub2.get(NameStructure.FIELD_LATEST), Boolean.FALSE)
-                    ));
-            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
-
-            Predicate predicateExclude =
-                    cb.and(
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
-                                    cb.or(
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.CANCELLED),
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.REJECTED)))),
-                            cb.not(cb.and(
-                                    cb.not(cb.exists(sub)),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
-                            );
-            predicates.add(predicateExclude);
-        }
-
         if (deleted != null) {
             predicates.add(cb.equal(from.get(NameStructure.FIELD_DELETED), deleted));
         }
@@ -301,96 +231,6 @@ public class SystemGroupRepository {
         }
     }
 
-    /**
-     * Count system groups history.
-     *
-     * @param uuid uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @return count of system groups
-     */
-    public Long countSystemGroupsHistory(
-            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
-
-        // note
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
-        Root<SystemGroup> from = cq.from(SystemGroup.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<SystemGroup> fromSub = sub.from(SystemGroup.class);
-        sub.where(cb.and(preparePredicatesSystemGroups(cb, cq, fromSub, null,
-                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(cb.count(from));
-
-        return em.createQuery(cq).getSingleResult();
-    }
-
-    /**
-     * Find system groups history.
-     *
-     * @param uuid uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @param orderBy order by
-     * @param isAsc is ascending
-     * @return list of system groups
-     */
-    public List<SystemGroup> readSystemGroupsHistory(
-            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            FieldStructure orderBy, Boolean isAsc) {
-
-        // note
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-        // order
-        //     orderBy, isAsc
-        // paging
-        //     outside of method
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<SystemGroup> cq = cb.createQuery(SystemGroup.class);
-        Root<SystemGroup> from = cq.from(SystemGroup.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<SystemGroup> fromSub = sub.from(SystemGroup.class);
-        sub.where(cb.and(preparePredicatesSystemGroups(cb, cq, fromSub, null,
-                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(from);
-
-        if (orderBy != null) {
-            Expression<String> exp = orderBy(from, orderBy);
-            if (BooleanUtils.toBoolean(isAsc)) {
-                cq.orderBy(cb.asc(exp));
-            } else {
-                cq.orderBy(cb.desc(exp));
-            }
-        }
-
-        return em.createQuery(cq).getResultList();
-    }
-
     /**
      * Persist system group into persistence context.
      *
diff --git a/src/main/java/org/openepics/names/repository/SystemRepository.java b/src/main/java/org/openepics/names/repository/SystemRepository.java
index ce1e949dad2bf8810cda262cff0e479084becffe..874f47a2d4e1b4df91478c911e482eab3c9a7105 100644
--- a/src/main/java/org/openepics/names/repository/SystemRepository.java
+++ b/src/main/java/org/openepics/names/repository/SystemRepository.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -29,7 +29,6 @@ import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Expression;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
-import javax.persistence.criteria.Subquery;
 
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -38,7 +37,6 @@ import org.openepics.names.repository.model.Persistable;
 import org.openepics.names.repository.model.Structure;
 import org.openepics.names.repository.model.System;
 import org.openepics.names.rest.beans.FieldStructure;
-import org.openepics.names.rest.beans.Status;
 import org.openepics.names.util.RepositoryUtil;
 import org.springframework.stereotype.Repository;
 
@@ -64,12 +62,10 @@ public class SystemRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return count of systems
      */
     public Long countSystems(Boolean deleted,
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         // note
         //     use of function for mnemonic path
@@ -82,8 +78,7 @@ public class SystemRepository {
         Root<System> from = cq.from(System.class);
 
         cq.where(cb.and(preparePredicatesSystems(cb, cq, from, deleted,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(cb.count(from));
 
         return em.createQuery(cq).getSingleResult();
@@ -107,7 +102,7 @@ public class SystemRepository {
 
         return readSystems(deleted,
                 uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.FALSE, null, null, null, null);
+                null, null, null, null);
     }
 
     /**
@@ -121,7 +116,6 @@ public class SystemRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @param orderBy order by
      * @param isAsc is ascending
      * @param offset offset
@@ -130,7 +124,7 @@ public class SystemRepository {
      */
     public List<System> readSystems(Boolean deleted,
             String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+            FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
 
         // note
         //     use of function for mnemonic path
@@ -147,8 +141,7 @@ public class SystemRepository {
         Root<System> from = cq.from(System.class);
 
         cq.where(cb.and(preparePredicatesSystems(cb, cq, from, deleted,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                includeHistory).toArray(new Predicate[0])));
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who).toArray(new Predicate[0])));
         cq.select(from);
 
         if (orderBy != null) {
@@ -183,75 +176,13 @@ public class SystemRepository {
      * @param mnemonicPath mnemonic path
      * @param description description
      * @param who who
-     * @param includeHistory include history
      * @return list of predicates
      */
     private List<Predicate> preparePredicatesSystems(CriteriaBuilder cb, CriteriaQuery cq, Root<System> from, Boolean deleted,
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            Boolean includeHistory) {
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
 
         List<Predicate> predicates = new ArrayList<>();
 
-        if (!Boolean.TRUE.equals(includeHistory)) {
-            // purpose of Naming to show valid entries
-            //     therefore
-            //         exclude some values unless history requested
-            //         make sure to not exclude present and future values (latest approved and pending)
-            //
-            // condition(s)
-            //     exclude content (with latest) before latest
-            //     exclude content (with latest) after  latest (cancelled, rejected)
-            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
-            //         <-->
-            //         select * from structure s
-            //         where (
-            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
-            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
-            //         )
-            //         <-->
-            //                     not (exists (subquery id) and s.id < (subquery id))
-            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
-            //                 and not (not exists (subquery id) and s.id < (subquery 2))
-            //
-            // note
-            //     persistence libraries may optimize query
-            //         e.g. change (!a and !b) to !(a or b)
-
-            Subquery<Long> sub = cq.subquery(Long.class);
-            Root<System> fromSub = sub.from(System.class);
-            sub.where(cb.and(
-                    cb.equal(fromSub.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub.get(NameStructure.FIELD_LATEST), Boolean.TRUE)
-                    ));
-            sub.select(fromSub.get(Persistable.FIELD_ID));
-
-            Subquery<Long> sub2 = cq.subquery(Long.class);
-            Root<System> fromSub2 = sub2.from(System.class);
-            sub2.where(cb.and(
-                    cb.equal(fromSub2.get(NameStructure.FIELD_UUID),   from.get(NameStructure.FIELD_UUID)),
-                    cb.equal(fromSub2.get(NameStructure.FIELD_LATEST), Boolean.FALSE)
-                    ));
-            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
-
-            Predicate predicateExclude =
-                    cb.and(
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
-                            cb.not(cb.and(
-                                    cb.exists(sub),
-                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
-                                    cb.or(
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.CANCELLED),
-                                            cb.equal(from.get(NameStructure.FIELD_STATUS), Status.REJECTED)))),
-                            cb.not(cb.and(
-                                    cb.not(cb.exists(sub)),
-                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
-                            );
-            predicates.add(predicateExclude);
-        }
-
         if (deleted != null) {
             predicates.add(cb.equal(from.get(NameStructure.FIELD_DELETED), deleted));
         }
@@ -264,7 +195,7 @@ public class SystemRepository {
             predicates.add(cb.and(cb.equal(from.get(NameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
         }
         if (!StringUtils.isEmpty(parentUuid)) {
-            predicates.add(cb.and(cb.equal(from.get(System.FIELD_PARENT_UUID), RepositoryUtil.preparePattern(parentUuid))));
+            predicates.add(cb.and(cb.equal(cb.function(System.FUNCTION_GET_PARENT_UUID_SYSTEM, String.class, from.get(Persistable.FIELD_ID)), RepositoryUtil.preparePattern(parentUuid))));
         }
         if (!StringUtils.isEmpty(mnemonic)) {
             predicates.add(cb.and(cb.like(from.get(Structure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
@@ -273,7 +204,7 @@ public class SystemRepository {
             predicates.add(cb.and(cb.like(from.get(Structure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
         }
         if (!StringUtils.isEmpty(mnemonicPath)) {
-            predicates.add(cb.and(cb.like(cb.function(System.FUNCTION_GET_MNEMONIC_PATH_SYSTEM, String.class, from.get(NameStructure.FIELD_UUID)), RepositoryUtil.preparePattern(mnemonicPath))));
+            predicates.add(cb.and(cb.like(cb.function(System.FUNCTION_GET_MNEMONIC_PATH_SYSTEM, String.class, from.get(Persistable.FIELD_ID)), RepositoryUtil.preparePattern(mnemonicPath))));
         }
         if (!StringUtils.isEmpty(description)) {
             predicates.add(cb.and(cb.like(from.get(NameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
@@ -296,7 +227,7 @@ public class SystemRepository {
         if (FieldStructure.UUID.equals(orderBy)) {
             return root.get(NameStructure.FIELD_UUID);
         } else if (FieldStructure.PARENT.equals(orderBy)) {
-            return root.get(System.FIELD_PARENT_UUID);
+            return root.get(System.FIELD_PARENT_ID);
         } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
             return root.get(Structure.FIELD_MNEMONIC);
         } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
@@ -312,100 +243,6 @@ public class SystemRepository {
         }
     }
 
-    /**
-     * Count systems history.
-     *
-     * @param uuid uuid
-     * @param parentUuid parent uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @return count of systems
-     */
-    public Long countSystemsHistory(
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
-        Root<System> from = cq.from(System.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<System> fromSub = sub.from(System.class);
-        sub.where(cb.and(preparePredicatesSystems(cb, cq, fromSub, null,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(cb.count(from));
-
-        return em.createQuery(cq).getSingleResult();
-    }
-
-    /**
-     * Find systems history.
-     *
-     * @param uuid uuid
-     * @param parentUuid parent uuid
-     * @param mnemonic mnemonic
-     * @param mnemonicEquivalence mnemonic equivalence
-     * @param mnemonicPath mnemonic path
-     * @param description description
-     * @param who who
-     * @param orderBy order by
-     * @param isAsc is ascending
-     * @return list of systems
-     */
-    public List<System> readSystemsHistory(
-            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
-            FieldStructure orderBy, Boolean isAsc) {
-
-        // note
-        //     use of function for mnemonic path
-        //     deleted - null
-        //     includeHistory - true
-        // where
-        //     queryFields, queryValues
-        // order
-        //     orderBy, isAsc
-        // paging
-        //     outside of method
-
-        CriteriaBuilder cb = em.getCriteriaBuilder();
-        CriteriaQuery<System> cq = cb.createQuery(System.class);
-        Root<System> from = cq.from(System.class);
-
-        Subquery<String> sub = cq.subquery(String.class);
-        Root<System> fromSub = sub.from(System.class);
-        sub.where(cb.and(preparePredicatesSystems(cb, cq, fromSub, null,
-                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
-                Boolean.TRUE).toArray(new Predicate[0])));
-        sub.select(fromSub.get(NameStructure.FIELD_UUID));
-
-        cq.where(cb.and(cb.in(from.get(NameStructure.FIELD_UUID)).value(sub)));
-        cq.select(from);
-
-        if (orderBy != null) {
-            Expression<String> exp = orderBy(from, orderBy);
-            if (BooleanUtils.toBoolean(isAsc)) {
-                cq.orderBy(cb.asc(exp));
-            } else {
-                cq.orderBy(cb.desc(exp));
-            }
-        }
-
-        return em.createQuery(cq).getResultList();
-    }
-
     /**
      * Persist system into persistence context.
      *
diff --git a/src/main/java/org/openepics/names/repository/model/AuditName.java b/src/main/java/org/openepics/names/repository/model/AuditName.java
new file mode 100644
index 0000000000000000000000000000000000000000..1233843adc507c7a56ecabcef4fe2a25b4152824
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/AuditName.java
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2024 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.repository.model;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+import org.openepics.names.rest.beans.Status;
+import org.openepics.names.util.TextUtil;
+
+/**
+ * This entity represents an audit name entry.
+ *
+ * @author Lars Johansson
+ */
+@Entity
+@Table(name = "audit_name")
+public class AuditName implements Serializable {
+
+    /**
+    *
+    */
+    private static final long serialVersionUID = 8375398737473867004L;
+
+    public static final String FIELD_AUDIT_ID                    = "audit_id";
+    public static final String FIELD_AUDIT_VERSION               = "audit_version";
+    public static final String FIELD_AUDIT_TABLE                 = "audit_table";
+    public static final String FIELD_AUDIT_OPERATION             = "audit_operation";
+
+    public static final String FIELD_ID                          = "id";
+    public static final String FIELD_VERSION                     = "version";
+    public static final String FIELD_UUID                        = "uuid";
+    public static final String FIELD_SYSTEM_GROUP_ID             = "systemgroupId";
+    public static final String FIELD_SYSTEM_ID                   = "systemId";
+    public static final String FIELD_SUBSYSTEM_ID                = "subsystemId";
+    public static final String FIELD_DEVICETYPE_ID               = "devicetypeId";
+    public static final String FIELD_INSTANCE_INDEX              = "instanceIndex";
+    public static final String FIELD_CONVENTION_NAME             = "conventionName";
+    public static final String FIELD_CONVENTION_NAME_EQUIVALENCE = "conventionNameEquivalence";
+    public static final String FIELD_DESCRIPTION                 = "description";
+    public static final String FIELD_STATUS                      = "status";
+    public static final String FIELD_DELETED                     = "deleted";
+    public static final String FIELD_REQUESTED                   = "requested";
+    public static final String FIELD_REQUESTED_BY                = "requestedBy";
+    public static final String FIELD_REQUESTED_COMMENT           = "requestedComment";
+    public static final String FIELD_PROCESSED                   = "processed";
+    public static final String FIELD_PROCESSED_BY                = "processedBy";
+    public static final String FIELD_PROCESSED_COMMENT           = "processedComment";
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "audit_id")
+    protected @Nullable Long auditId;
+    @Version
+    @Column(name = "audit_version")
+    private @Nullable Integer auditVersion;
+    @Column(name = "audit_table")
+    private String auditTable;
+    @Column(name = "audit_operation")
+    private String auditOperation;
+
+    private Long id;
+    private Integer version;
+    private String uuid;
+    @Column(name = "systemgroup_id")
+    private Long systemGroupId;
+    @Column(name = "system_id")
+    private Long systemId;
+    @Column(name = "subsystem_id")
+    private Long subsystemId;
+    @Column(name = "devicetype_id")
+    private Long deviceTypeId;
+    @Column(name = "instance_index")
+    private String instanceIndex;
+    @Column(name = "convention_name")
+    private String conventionName;
+    @Column(name = "convention_name_equivalence")
+    private String conventionNameEquivalence;
+    private String description;
+    @Enumerated(EnumType.STRING)
+    private Status status;
+    private Boolean deleted;
+    private Date requested;
+    @Column(name = "requested_by")
+    private String requestedBy;
+    @Column(name = "requested_comment")
+    private String requestedComment;
+    private Date processed;
+    @Column(name = "processed_by")
+    private String processedBy;
+    @Column(name = "processed_comment")
+    private String processedComment;
+
+    /**
+     * Constructor for audit name.
+     */
+    public AuditName() {
+    }
+
+    /**
+     * Constructor for audit name.
+     *
+     * @param auditOperation audit operation
+     * @param name name
+     */
+    public AuditName(String auditOperation, Name name) {
+        this(TextUtil.NAME, auditOperation,
+                name.getId(), name.getVersion(),
+                name.getUuid(), name.getSystemGroupId(), name.getSystemId(), name.getSubsystemId(), name.getDeviceTypeId(),
+                name.getInstanceIndex(), name.getConventionName(), name.getConventionNameEquivalence(), name.getDescription(),
+                name.getStatus(), name.isDeleted(),
+                name.getRequested(), name.getRequestedBy(), name.getRequestedComment(), null, null, null);
+    }
+
+    /**
+     * Constructor for audit name.
+     *
+     * @param auditTable audit table
+     * @param auditOperation audit operation
+     * @param id id
+     * @param version version
+     * @param uuid uuid
+     * @param systemGroupId system group id
+     * @param systemId system id
+     * @param subsystemId subsystem id
+     * @param deviceTypeId device type id
+     * @param index index
+     * @param conventionName convention name
+     * @param conventionNameEquivalence convention name equivalence
+     * @param description description
+     * @param status status
+     * @param deleted deleted
+     * @param requested requested
+     * @param requestedBy requested by
+     * @param requestedComment requested comment
+     * @param processed processed
+     * @param processedBy processedBy
+     * @param processedComment processedComment
+     */
+    public AuditName(String auditTable, String auditOperation,
+            Long id, Integer version,
+            UUID uuid, Long systemGroupId, Long systemId, Long subsystemId, Long deviceTypeId,
+            String instanceIndex, String conventionName, String conventionNameEquivalence, String description,
+            Status status, Boolean deleted,
+            Date requested, String requestedBy, String requestedComment, Date processed, String processedBy, String processedComment) {
+        super();
+        setAuditTable(auditTable);
+        setAuditOperation(auditOperation);
+        setId(id);
+        setVersion(version);
+        setUuid(uuid);
+        setSystemGroupId(systemGroupId);
+        setSystemId(systemId);
+        setSubsystemId(subsystemId);
+        setDeviceTypeId(deviceTypeId);
+        setInstanceIndex(instanceIndex);
+        setConventionName(conventionName);
+        setConventionNameEquivalence(conventionNameEquivalence);
+        setDescription(description);
+        setStatus(status);
+        setDeleted(deleted);
+        setRequested(requested);
+        setRequestedBy(requestedBy);
+        setRequestedComment(requestedComment);
+        setProcessed(processed);
+        setProcessedBy(processedBy);
+        setProcessedComment(processedComment);
+    }
+
+    public Long getAuditId() {
+        return auditId;
+    }
+    public Integer getAuditVersion() {
+        return auditVersion;
+    }
+
+    public String getAuditTable() {
+        return auditTable;
+    }
+    public void setAuditTable(String auditTable) {
+        this.auditTable = auditTable;
+    }
+    public String getAuditOperation() {
+        return auditOperation;
+    }
+    public void setAuditOperation(String auditOperation) {
+        this.auditOperation = auditOperation;
+    }
+
+    public Long getId() {
+        return id;
+    }
+    public void setId(Long id) {
+        this.id = id;
+    }
+    public Integer getVersion() {
+        return version;
+    }
+    public void setVersion(Integer version) {
+        this.version = version;
+    }
+    public UUID getUuid() {
+        return uuid != null ? UUID.fromString(uuid) : null;
+    }
+    public void setUuid(UUID uuid) {
+        this.uuid = uuid != null ? uuid.toString() : null;
+    }
+    public Long getSystemGroupId() {
+        return systemGroupId;
+    }
+    public void setSystemGroupId(Long systemGroupId) {
+        this.systemGroupId = systemGroupId;
+    }
+    public Long getSystemId() {
+        return systemId;
+    }
+    public void setSystemId(Long systemId) {
+        this.systemId = systemId;
+    }
+    public Long getSubsystemId() {
+        return subsystemId;
+    }
+    public void setSubsystemId(Long subsystemId) {
+        this.subsystemId = subsystemId;
+    }
+    public Long getDeviceTypeId() {
+        return deviceTypeId;
+    }
+    public void setDeviceTypeId(Long deviceTypeId) {
+        this.deviceTypeId = deviceTypeId;
+    }
+    public String getInstanceIndex() {
+        return instanceIndex;
+    }
+    public void setInstanceIndex(String instanceIndex) {
+        this.instanceIndex = instanceIndex;
+    }
+    public String getConventionName() {
+        return conventionName;
+    }
+    public void setConventionName(String conventionName) {
+        this.conventionName = conventionName;
+    }
+    public String getConventionNameEquivalence() {
+        return conventionNameEquivalence;
+    }
+    public void setConventionNameEquivalence(String conventionNameEquivalence) {
+        this.conventionNameEquivalence = conventionNameEquivalence;
+    }
+    public String getDescription() {
+        return description;
+    }
+    public void setDescription(String description) {
+        this.description = description;
+    }
+    public Status getStatus() {
+        return status;
+    }
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+    public Boolean isDeleted() {
+        return deleted;
+    }
+    public void setDeleted(Boolean deleted) {
+        this.deleted = deleted;
+    }
+    public Date getRequested() {
+        return requested;
+    }
+    public void setRequested(Date requested) {
+        this.requested = requested;
+    }
+    public String getRequestedBy() {
+        return requestedBy;
+    }
+    public void setRequestedBy(String requestedBy) {
+        this.requestedBy = requestedBy;
+    }
+    public String getRequestedComment() {
+        return requestedComment;
+    }
+    public void setRequestedComment(String requestedComment) {
+        this.requestedComment = requestedComment;
+    }
+    public Date getProcessed() {
+        return processed;
+    }
+    public void setProcessed(Date processed) {
+        this.processed = processed;
+    }
+    public String getProcessedBy() {
+        return processedBy;
+    }
+    public void setProcessedBy(String processedBy) {
+        this.processedBy = processedBy;
+    }
+    public String getProcessedComment() {
+        return processedComment;
+    }
+    public void setProcessedComment(String processedComment) {
+        this.processedComment = processedComment;
+    }
+
+    /**
+     * Return name given audit name.
+     *
+     * @return name
+     */
+    public Name getNonAuditName() {
+        return new Name(getUuid(), getSystemGroupId(), getSystemId(), getSubsystemId(), getDeviceTypeId(),
+                getInstanceIndex(), getConventionName(), getConventionNameEquivalence(), getDescription(),
+                getStatus(), isDeleted(),
+                getRequested(), getRequestedBy(), getRequestedComment());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals ((AuditName) obj);
+    }
+
+    public boolean equals(AuditName other) {
+        if (other == null)
+            return false;
+
+        if (getAuditId() == null) {
+            if (other.getAuditId() != null)
+                return false;
+        } else if (!getAuditId().equals(other.getAuditId()))
+            return false;
+        if (getAuditVersion() == null) {
+            if (other.getAuditVersion() != null)
+                return false;
+        } else if (!getAuditVersion().equals(other.getAuditVersion()))
+            return false;
+        if (getAuditTable() == null) {
+            if (other.getAuditTable() != null)
+                return false;
+        } else if (!getAuditTable().equals(other.getAuditTable()))
+            return false;
+        if (getAuditOperation() == null) {
+            if (other.getAuditOperation() != null)
+                return false;
+        } else if (!getAuditOperation().equals(other.getAuditOperation()))
+            return false;
+
+        if (getId() == null) {
+            if (other.getId() != null)
+                return false;
+        } else if (!getId().equals(other.getId()))
+            return false;
+        if (getVersion() == null) {
+            if (other.getVersion() != null)
+                return false;
+        } else if (!getVersion().equals(other.getVersion()))
+            return false;
+        if (getUuid() == null) {
+            if (other.getUuid() != null)
+                return false;
+        } else if (!getUuid().equals(other.getUuid()))
+            return false;
+        if (getSystemGroupId() == null) {
+            if (other.getSystemGroupId() != null)
+                return false;
+        } else if (!getSystemGroupId().equals(other.getSystemGroupId()))
+            return false;
+        if (getSystemId() == null) {
+            if (other.getSystemId() != null)
+                return false;
+        } else if (!getSystemId().equals(other.getSystemId()))
+            return false;
+        if (getSubsystemId() == null) {
+            if (other.getSubsystemId() != null)
+                return false;
+        } else if (!getSubsystemId().equals(other.getSubsystemId()))
+            return false;
+        if (getDeviceTypeId() == null) {
+            if (other.getDeviceTypeId() != null)
+                return false;
+        } else if (!getDeviceTypeId().equals(other.getDeviceTypeId()))
+            return false;
+        if (getInstanceIndex() == null) {
+            if (other.getInstanceIndex() != null)
+                return false;
+        } else if (!getInstanceIndex().equals(other.getInstanceIndex()))
+            return false;
+        if (getConventionName() == null) {
+            if (other.getConventionName() != null)
+                return false;
+        } else if (!getConventionName().equals(other.getConventionName()))
+            return false;
+        if (getConventionNameEquivalence() == null) {
+            if (other.getConventionNameEquivalence() != null)
+                return false;
+        } else if (!getConventionNameEquivalence().equals(other.getConventionNameEquivalence()))
+            return false;
+        if (getDescription() == null) {
+            if (other.getDescription() != null)
+                return false;
+        } else if (!getDescription().equals(other.getDescription()))
+            return false;
+        if (getStatus() == null) {
+            if (other.getStatus() != null)
+                return false;
+        } else if (!getStatus().equals(other.getStatus()))
+            return false;
+        if (isDeleted() == null) {
+            if (other.isDeleted() != null)
+                return false;
+        } else if (!isDeleted().equals(other.isDeleted()))
+            return false;
+        if (getRequested() == null) {
+            if (other.getRequested() != null)
+                return false;
+        } else if (!getRequested().equals(other.getRequested()))
+            return false;
+        if (getRequestedBy() == null) {
+            if (other.getRequestedBy() != null)
+                return false;
+        } else if (!getRequestedBy().equals(other.getRequestedBy()))
+            return false;
+        if (getRequestedComment() == null) {
+            if (other.getRequestedComment() != null)
+                return false;
+        } else if (!getRequestedComment().equals(other.getRequestedComment()))
+            return false;
+        if (getProcessed() == null) {
+            if (other.getProcessed() != null)
+                return false;
+        } else if (!getProcessed().equals(other.getProcessed()))
+            return false;
+        if (getProcessedBy() == null) {
+            if (other.getProcessedBy() != null)
+                return false;
+        } else if (!getProcessedBy().equals(other.getProcessedBy()))
+            return false;
+        if (getProcessedComment() == null) {
+            if (other.getProcessedComment() != null)
+                return false;
+        } else if (!getProcessedComment().equals(other.getProcessedComment()))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getAuditId(), getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"audit_id\": "                      + getAuditId());
+        sb.append(", \"audit_version\": "               + getAuditVersion());
+        sb.append(", \"audit_table\": "                 + getAuditTable());
+        sb.append(", \"audit_operation\": "             + getAuditOperation());
+        sb.append(", \"id\": "                          + getId());
+        sb.append(", \"version\": "                     + getVersion());
+        sb.append(", \"uuid\": "                        + getUuid());
+        sb.append(", \"systemgroup_id\": "              + getSystemGroupId());
+        sb.append(", \"system_id\": "                   + getSystemId());
+        sb.append(", \"subsystem_id\": "                + getSubsystemId());
+        sb.append(", \"devicetype_id\": "               + getDeviceTypeId());
+        sb.append(", \"instance_index\": "              + getInstanceIndex());
+        sb.append(", \"convention_name\": "             + getConventionName());
+        sb.append(", \"convention_name_equivalence\": " + getConventionNameEquivalence());
+        sb.append(", \"description\": "                 + getDescription());
+        sb.append(", \"status\": "                      + getStatus());
+        sb.append(", \"deleted\": "                     + isDeleted());
+        sb.append(", \"requested\": "                   + getRequested());
+        sb.append(", \"requested_by\": "                + getRequestedBy());
+        sb.append(", \"requested_comment\": "           + getRequestedComment());
+        sb.append(", \"processed\": "                   + getProcessed());
+        sb.append(", \"processed_by\": "                + getProcessedBy());
+        sb.append(", \"processed_comment\": "           + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/AuditStructure.java b/src/main/java/org/openepics/names/repository/model/AuditStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef39bab1944e78cac4ebedb617188b53c47bb417
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/AuditStructure.java
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2024 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.repository.model;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+import org.openepics.names.rest.beans.Status;
+import org.openepics.names.util.TextUtil;
+
+/**
+ * This entity represents an audit structure entry.
+ *
+ * @author Lars Johansson
+ */
+@Entity
+@Table(name = "audit_structure")
+public class AuditStructure implements Serializable {
+
+    /**
+    *
+    */
+    private static final long serialVersionUID = 8891654664461832903L;
+
+    public static final String FIELD_AUDIT_ID             = "auditId";
+    public static final String FIELD_AUDIT_VERSION        = "auditVersion";
+    public static final String FIELD_AUDIT_TABLE          = "auditTable";
+    public static final String FIELD_AUDIT_OPERATION      = "auditOperation";
+
+    public static final String FIELD_ID                   = "id";
+    public static final String FIELD_VERSION              = "version";
+    public static final String FIELD_UUID                 = "uuid";
+    public static final String FIELD_PARENT_ID            = "parentId";
+    public static final String FIELD_MNEMONIC             = "mnemonic";
+    public static final String FIELD_MNEMONIC_EQUIVALENCE = "mnemonicEquivalence";
+    public static final String FIELD_ORDERING             = "ordering";
+    public static final String FIELD_DESCRIPTION          = "description";
+    public static final String FIELD_STATUS               = "status";
+    public static final String FIELD_DELETED              = "deleted";
+    public static final String FIELD_REQUESTED            = "requested";
+    public static final String FIELD_REQUESTED_BY         = "requestedBy";
+    public static final String FIELD_REQUESTED_COMMENT    = "requestedComment";
+    public static final String FIELD_PROCESSED            = "processed";
+    public static final String FIELD_PROCESSED_BY         = "processedBy";
+    public static final String FIELD_PROCESSED_COMMENT    = "processedComment";
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "audit_id")
+    protected @Nullable Long auditId;
+    @Version
+    @Column(name = "audit_version")
+    private @Nullable Integer auditVersion;
+    @Column(name = "audit_table")
+    private String auditTable;
+    @Column(name = "audit_operation")
+    private String auditOperation;
+
+    private Long id;
+    private Integer version;
+    private String uuid;
+    @Column(name = "parent_id")
+    private Long parentId;
+    private String mnemonic;
+    @Column(name = "mnemonic_equivalence")
+    private String mnemonicEquivalence;
+    private Integer ordering;
+    private String description;
+    @Enumerated(EnumType.STRING)
+    private Status status;
+    private Boolean deleted;
+    private Date requested;
+    @Column(name = "requested_by")
+    private String requestedBy;
+    @Column(name = "requested_comment")
+    private String requestedComment;
+    private Date processed;
+    @Column(name = "processed_by")
+    private String processedBy;
+    @Column(name = "processed_comment")
+    private String processedComment;
+
+    /**
+     * Constructor for audit structure.
+     */
+    public AuditStructure() {
+    }
+
+    /**
+     * Constructor for audit structure.
+     *
+     * @param auditOperation audit operation
+     * @param structure structure
+     */
+    public AuditStructure(String auditOperation, SystemGroup structure) {
+            this(TextUtil.SYSTEMGROUP, auditOperation,
+                structure.getId(), structure.getVersion(),
+                structure.getUuid(), null, structure.getMnemonic(), structure.getMnemonicEquivalence(), structure.getOrdering(), structure.getDescription(),
+                structure.getStatus(), structure.isDeleted(),
+                null, null, null, structure.getProcessed(), structure.getProcessedBy(), structure.getProcessedComment());
+    }
+    /**
+     * Constructor for audit structure.
+     *
+     * @param auditOperation audit operation
+     * @param structure structure
+     */
+    public AuditStructure(String auditOperation, System structure) {
+        this(TextUtil.SYSTEM, auditOperation,
+                structure.getId(), structure.getVersion(),
+                structure.getUuid(), structure.getParentId(), structure.getMnemonic(), structure.getMnemonicEquivalence(), structure.getOrdering(), structure.getDescription(),
+                structure.getStatus(), structure.isDeleted(),
+                null, null, null, structure.getProcessed(), structure.getProcessedBy(), structure.getProcessedComment());
+    }
+    /**
+     * Constructor for audit structure.
+     *
+     * @param auditOperation audit operation
+     * @param structure structure
+     */
+    public AuditStructure(String auditOperation, Subsystem structure) {
+        this(TextUtil.SUBSYSTEM, auditOperation,
+                structure.getId(), structure.getVersion(),
+                structure.getUuid(), structure.getParentId(), structure.getMnemonic(), structure.getMnemonicEquivalence(), structure.getOrdering(), structure.getDescription(),
+                structure.getStatus(), structure.isDeleted(),
+                null, null, null, structure.getProcessed(), structure.getProcessedBy(), structure.getProcessedComment());
+    }
+    /**
+     * Constructor for audit structure.
+     *
+     * @param auditOperation audit operation
+     * @param structure structure
+     */
+    public AuditStructure(String auditOperation, Discipline structure) {
+        this(TextUtil.DISCIPLINE, auditOperation,
+                structure.getId(), structure.getVersion(),
+                structure.getUuid(), null, structure.getMnemonic(), structure.getMnemonicEquivalence(), structure.getOrdering(), structure.getDescription(),
+                structure.getStatus(), structure.isDeleted(),
+                null, null, null, structure.getProcessed(), structure.getProcessedBy(), structure.getProcessedComment());
+    }
+    /**
+     * Constructor for audit structure.
+     *
+     * @param auditOperation audit operation
+     * @param structure structure
+     */
+    public AuditStructure(String auditOperation, DeviceGroup structure) {
+        this(TextUtil.DEVICEGROUP, auditOperation,
+                structure.getId(), structure.getVersion(),
+                structure.getUuid(), structure.getParentId(), structure.getMnemonic(), structure.getMnemonicEquivalence(), structure.getOrdering(), structure.getDescription(),
+                structure.getStatus(), structure.isDeleted(),
+                null, null, null, structure.getProcessed(), structure.getProcessedBy(), structure.getProcessedComment());
+    }
+    /**
+     * Constructor for audit structure.
+     *
+     * @param auditOperation audit operation
+     * @param structure structure
+     */
+    public AuditStructure(String auditOperation, DeviceType structure) {
+        this(TextUtil.DEVICETYPE, auditOperation,
+                structure.getId(), structure.getVersion(),
+                structure.getUuid(), structure.getParentId(), structure.getMnemonic(), structure.getMnemonicEquivalence(), structure.getOrdering(), structure.getDescription(),
+                structure.getStatus(), structure.isDeleted(),
+                null, null, null, structure.getProcessed(), structure.getProcessedBy(), structure.getProcessedComment());
+    }
+
+    /**
+     * Constructor for audit structure.
+     *
+     * @param auditTable audit table
+     * @param auditOperation audit operation
+     * @param id id
+     * @param version version
+     * @param uuid uuid
+     * @param parentId parent id
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param ordering
+     * @param description description
+     * @param status status
+     * @param deleted deleted
+     * @param requested requested
+     * @param requestedBy requested by
+     * @param requestedComment requested comment
+     * @param processed processed
+     * @param processedBy processedBy
+     * @param processedComment processedComment
+     */
+    public AuditStructure(String auditTable, String auditOperation,
+            Long id, Integer version,
+            UUID uuid, Long parentId, String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean deleted,
+            Date requested, String requestedBy, String requestedComment, Date processed, String processedBy, String processedComment) {
+        super();
+        setAuditTable(auditTable);
+        setAuditOperation(auditOperation);
+        setId(id);
+        setVersion(version);
+        setUuid(uuid);
+        setParentId(parentId);
+        setMnemonic(mnemonic);
+        setMnemonicEquivalence(mnemonicEquivalence);
+        setOrdering(ordering);
+        setDescription(description);
+        setStatus(status);
+        setDeleted(deleted);
+        setRequested(requested);
+        setRequestedBy(requestedBy);
+        setRequestedComment(requestedComment);
+        setProcessed(processed);
+        setProcessedBy(processedBy);
+        setProcessedComment(processedComment);
+    }
+
+    public Long getAuditId() {
+        return auditId;
+    }
+    public Integer getAuditVersion() {
+        return auditVersion;
+    }
+
+    public String getAuditTable() {
+        return auditTable;
+    }
+    public void setAuditTable(String auditTable) {
+        this.auditTable = auditTable;
+    }
+    public String getAuditOperation() {
+        return auditOperation;
+    }
+    public void setAuditOperation(String auditOperation) {
+        this.auditOperation = auditOperation;
+    }
+
+    public Long getId() {
+        return id;
+    }
+    public void setId(Long id) {
+        this.id = id;
+    }
+    public Integer getVersion() {
+        return version;
+    }
+    public void setVersion(Integer version) {
+        this.version = version;
+    }
+    public UUID getUuid() {
+        return uuid != null ? UUID.fromString(uuid) : null;
+    }
+    public void setUuid(UUID uuid) {
+        this.uuid = uuid != null ? uuid.toString() : null;
+    }
+    public Long getParentId() {
+        return parentId;
+    }
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
+    }
+    public String getMnemonic() {
+        return mnemonic;
+    }
+    public void setMnemonic(String mnemonic) {
+        this.mnemonic = mnemonic;
+    }
+    public String getMnemonicEquivalence() {
+        return mnemonicEquivalence;
+    }
+    public void setMnemonicEquivalence(String mnemonicEquivalence) {
+        this.mnemonicEquivalence = mnemonicEquivalence;
+    }
+    public Integer getOrdering() {
+        return ordering;
+    }
+    public void setOrdering(Integer ordering) {
+        this.ordering = ordering;
+    }
+    public String getDescription() {
+        return description;
+    }
+    public void setDescription(String description) {
+        this.description = description;
+    }
+    public Status getStatus() {
+        return status;
+    }
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+    public Boolean isDeleted() {
+        return deleted;
+    }
+    public void setDeleted(Boolean deleted) {
+        this.deleted = deleted;
+    }
+    public Date getRequested() {
+        return requested;
+    }
+    public void setRequested(Date requested) {
+        this.requested = requested;
+    }
+    public String getRequestedBy() {
+        return requestedBy;
+    }
+    public void setRequestedBy(String requestedBy) {
+        this.requestedBy = requestedBy;
+    }
+    public String getRequestedComment() {
+        return requestedComment;
+    }
+    public void setRequestedComment(String requestedComment) {
+        this.requestedComment = requestedComment;
+    }
+    public Date getProcessed() {
+        return processed;
+    }
+    public void setProcessed(Date processed) {
+        this.processed = processed;
+    }
+    public String getProcessedBy() {
+        return processedBy;
+    }
+    public void setProcessedBy(String processedBy) {
+        this.processedBy = processedBy;
+    }
+    public String getProcessedComment() {
+        return processedComment;
+    }
+    public void setProcessedComment(String processedComment) {
+        this.processedComment = processedComment;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals ((AuditStructure) obj);
+    }
+
+    public boolean equals(AuditStructure other) {
+        if (other == null)
+            return false;
+
+        if (getAuditId() == null) {
+            if (other.getAuditId() != null)
+                return false;
+        } else if (!getAuditId().equals(other.getAuditId()))
+            return false;
+        if (getAuditVersion() == null) {
+            if (other.getAuditVersion() != null)
+                return false;
+        } else if (!getAuditVersion().equals(other.getAuditVersion()))
+            return false;
+        if (getAuditTable() == null) {
+            if (other.getAuditTable() != null)
+                return false;
+        } else if (!getAuditTable().equals(other.getAuditTable()))
+            return false;
+        if (getAuditOperation() == null) {
+            if (other.getAuditOperation() != null)
+                return false;
+        } else if (!getAuditOperation().equals(other.getAuditOperation()))
+            return false;
+
+        if (getId() == null) {
+            if (other.getId() != null)
+                return false;
+        } else if (!getId().equals(other.getId()))
+            return false;
+        if (getVersion() == null) {
+            if (other.getVersion() != null)
+                return false;
+        } else if (!getVersion().equals(other.getVersion()))
+            return false;
+        if (getUuid() == null) {
+            if (other.getUuid() != null)
+                return false;
+        } else if (!getUuid().equals(other.getUuid()))
+            return false;
+        if (getParentId() == null) {
+            if (other.getParentId() != null)
+                return false;
+        } else if (!getParentId().equals(other.getParentId()))
+            return false;
+        if (getMnemonic() == null) {
+            if (other.getMnemonic() != null)
+                return false;
+        } else if (!getMnemonic().equals(other.getMnemonic()))
+            return false;
+        if (getMnemonicEquivalence() == null) {
+            if (other.getMnemonicEquivalence() != null)
+                return false;
+        } else if (!getMnemonicEquivalence().equals(other.getMnemonicEquivalence()))
+            return false;
+        if (getOrdering() == null) {
+            if (other.getOrdering() != null)
+                return false;
+        } else if (!getOrdering().equals(other.getOrdering()))
+            return false;
+        if (getDescription() == null) {
+            if (other.getDescription() != null)
+                return false;
+        } else if (!getDescription().equals(other.getDescription()))
+            return false;
+        if (getStatus() == null) {
+            if (other.getStatus() != null)
+                return false;
+        } else if (!getStatus().equals(other.getStatus()))
+            return false;
+        if (isDeleted() == null) {
+            if (other.isDeleted() != null)
+                return false;
+        } else if (!isDeleted().equals(other.isDeleted()))
+            return false;
+        if (getRequested() == null) {
+            if (other.getRequested() != null)
+                return false;
+        } else if (!getRequested().equals(other.getRequested()))
+            return false;
+        if (getRequestedBy() == null) {
+            if (other.getRequestedBy() != null)
+                return false;
+        } else if (!getRequestedBy().equals(other.getRequestedBy()))
+            return false;
+        if (getRequestedComment() == null) {
+            if (other.getRequestedComment() != null)
+                return false;
+        } else if (!getRequestedComment().equals(other.getRequestedComment()))
+            return false;
+        if (getProcessed() == null) {
+            if (other.getProcessed() != null)
+                return false;
+        } else if (!getProcessed().equals(other.getProcessed()))
+            return false;
+        if (getProcessedBy() == null) {
+            if (other.getProcessedBy() != null)
+                return false;
+        } else if (!getProcessedBy().equals(other.getProcessedBy()))
+            return false;
+        if (getProcessedComment() == null) {
+            if (other.getProcessedComment() != null)
+                return false;
+        } else if (!getProcessedComment().equals(other.getProcessedComment()))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getAuditId(), getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"audit_id\": "               + getAuditId());
+        sb.append(", \"audit_version\": "        + getAuditVersion());
+        sb.append(", \"audit_table\": "          + getAuditTable());
+        sb.append(", \"audit_operation\": "      + getAuditOperation());
+        sb.append(", \"id\": "                   + getId());
+        sb.append(", \"version\": "              + getVersion());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"parent_id\": "            + getParentId());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
+        sb.append(", \"ordering\": "             + getOrdering());
+        sb.append(", \"description\": "          + getDescription());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append(", \"requested\": "            + getRequested());
+        sb.append(", \"requested_by\": "         + getRequestedBy());
+        sb.append(", \"requested_comment\": "    + getRequestedComment());
+        sb.append(", \"processed\": "            + getProcessed());
+        sb.append(", \"processed_by\": "         + getProcessedBy());
+        sb.append(", \"processed_comment\": "    + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/DeviceGroup.java b/src/main/java/org/openepics/names/repository/model/DeviceGroup.java
index a75133e299fdad8579c56d870399d8f17c744bb5..b1b1f331166c55e5127fa82a67a6db1559064abd 100644
--- a/src/main/java/org/openepics/names/repository/model/DeviceGroup.java
+++ b/src/main/java/org/openepics/names/repository/model/DeviceGroup.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -42,50 +42,64 @@ public class DeviceGroup extends Structure {
      */
     private static final long serialVersionUID = -8762287473417706804L;
 
-    public static final String FIELD_PARENT_UUID = "parentUuid";
+    public static final String FIELD_PARENT_ID = "parentId";
 
+    public static final String FUNCTION_GET_PARENT_UUID_DEVICEGROUP   = "get_parent_uuid_devicegroup";
     public static final String FUNCTION_GET_MNEMONIC_PATH_DEVICEGROUP = "get_mnemonic_path_devicegroup";
 
-    @Column(name = "parent_uuid")
-    private String parentUuid;
+    @Column(name = "parent_id")
+    private Long parentId;
 
     /**
-     * Constructor for DeviceGroup.
+     * Constructor for device group.
      */
     public DeviceGroup() {
     }
 
     /**
-     * Constructor for DeviceGroup.
+     * Constructor for device group.
      *
      * @param uuid uuid
-     * @param parentUuid parent uuid
+     * @param parentId parent id
      * @param mnemonic mnemonic
      * @param mnemonicEquivalence mnemonic equivalence
      * @param ordering ordering
      * @param description description
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param processed processed
      * @param processedBy processed by
      * @param processedComment processed comment
      */
-    public DeviceGroup(UUID uuid, UUID parentUuid,
-            String mnemonic, String mnemonicEquivalence, Integer ordering,
-            String description, Status status, Boolean latest, Boolean deleted,
+    public DeviceGroup(UUID uuid, Long parentId,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean deleted,
             Date processed, String processedBy, String processedComment) {
         super(uuid, mnemonic, mnemonicEquivalence, ordering,
-                description, status, latest, deleted,
+                description, status, deleted,
                 processed, processedBy, processedComment);
-        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+        setParentId(parentId);
     }
 
-    public UUID getParentUuid() {
-        return parentUuid != null ? UUID.fromString(parentUuid) : null;
+    /**
+     * Constructor for device group.
+     *
+     * @param auditStructure audit structure
+     */
+    public DeviceGroup(AuditStructure auditStructure) {
+        super(auditStructure.getUuid(),
+                auditStructure.getMnemonic(), auditStructure.getMnemonicEquivalence(), auditStructure.getOrdering(), auditStructure.getDescription(),
+                auditStructure.getStatus(), auditStructure.isDeleted(),
+                auditStructure.getProcessed(), auditStructure.getProcessedBy(), auditStructure.getProcessedComment());
+        setParentId(auditStructure.getParentId());
+        this.id = auditStructure.getId();
+    }
+
+    public Long getParentId() {
+        return parentId;
     }
-    public void setParentUuid(UUID parentUuid) {
-        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
     }
 
     @Override
@@ -108,10 +122,10 @@ public class DeviceGroup extends Structure {
             return false;
         }
 
-        if (getParentUuid() == null) {
-            if (other.getParentUuid() != null)
+        if (getParentId() == null) {
+            if (other.getParentId() != null)
                 return false;
-        } else if (!getParentUuid().equals(other.getParentUuid()))
+        } else if (!getParentId().equals(other.getParentId()))
             return false;
 
         return true;
@@ -129,13 +143,12 @@ public class DeviceGroup extends Structure {
         sb.append("\"id\": "                     + getId());
         sb.append(", \"version\": "              + getVersion());
         sb.append(", \"uuid\": "                 + getUuid());
-        sb.append(", \"parent_uuid\": "          + getParentUuid());
+        sb.append(", \"parent_id\": "            + getParentId());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
         sb.append(", \"ordering\": "             + getOrdering());
         sb.append(", \"description\": "          + getDescription());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append(", \"requested\": "            + getRequested());
         sb.append(", \"requested_by\": "         + getRequestedBy());
@@ -155,7 +168,6 @@ public class DeviceGroup extends Structure {
         sb.append(", \"uuid\": "                 + getUuid());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/repository/model/DeviceType.java b/src/main/java/org/openepics/names/repository/model/DeviceType.java
index a7ca0ba4f126b3b88d56b6d9da53759e07f13f04..85b5b2339117a27ac275c8c514df4c3ef10a987a 100644
--- a/src/main/java/org/openepics/names/repository/model/DeviceType.java
+++ b/src/main/java/org/openepics/names/repository/model/DeviceType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -42,50 +42,64 @@ public class DeviceType extends Structure {
      */
     private static final long serialVersionUID = 2061731870402041740L;
 
-    public static final String FIELD_PARENT_UUID = "parentUuid";
+    public static final String FIELD_PARENT_ID = "parentId";
 
+    public static final String FUNCTION_GET_PARENT_UUID_DEVICETYPE   = "get_parent_uuid_devicetype";
     public static final String FUNCTION_GET_MNEMONIC_PATH_DEVICETYPE = "get_mnemonic_path_devicetype";
 
-    @Column(name = "parent_uuid")
-    private String parentUuid;
+    @Column(name = "parent_id")
+    private Long parentId;
 
     /**
-     * Constructor for DeviceType.
+     * Constructor for device type.
      */
     public DeviceType() {
     }
 
     /**
-     * Constructor for DeviceType.
+     * Constructor for device type.
      *
      * @param uuid uuid
-     * @param parentUuid parent uuid
+     * @param parentId parent id
      * @param mnemonic mnemonic
      * @param mnemonicEquivalence mnemonic equivalence
      * @param ordering ordering
      * @param description description
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param processed processed
      * @param processedBy processed by
      * @param processedComment processed comment
      */
-    public DeviceType(UUID uuid, UUID parentUuid,
-            String mnemonic, String mnemonicEquivalence, Integer ordering,
-            String description, Status status, Boolean latest, Boolean deleted,
+    public DeviceType(UUID uuid, Long parentId,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean deleted,
             Date processed, String processedBy, String processedComment) {
         super(uuid, mnemonic, mnemonicEquivalence, ordering,
-                description, status, latest, deleted,
+                description, status, deleted,
                 processed, processedBy, processedComment);
-        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+        setParentId(parentId);
     }
 
-    public UUID getParentUuid() {
-        return parentUuid != null ? UUID.fromString(parentUuid) : null;
+    /**
+     * Constructor for device type.
+     *
+     * @param auditStructure audit structure
+     */
+    public DeviceType(AuditStructure auditStructure) {
+        super(auditStructure.getUuid(),
+                auditStructure.getMnemonic(), auditStructure.getMnemonicEquivalence(), auditStructure.getOrdering(), auditStructure.getDescription(),
+                auditStructure.getStatus(), auditStructure.isDeleted(),
+                auditStructure.getProcessed(), auditStructure.getProcessedBy(), auditStructure.getProcessedComment());
+        setParentId(auditStructure.getParentId());
+        this.id = auditStructure.getId();
+    }
+
+    public Long getParentId() {
+        return parentId;
     }
-    public void setParentUuid(UUID parentUuid) {
-        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
     }
 
     @Override
@@ -108,10 +122,10 @@ public class DeviceType extends Structure {
             return false;
         }
 
-        if (getParentUuid() == null) {
-            if (other.getParentUuid() != null)
+        if (getParentId() == null) {
+            if (other.getParentId() != null)
                 return false;
-        } else if (!getParentUuid().equals(other.getParentUuid()))
+        } else if (!getParentId().equals(other.getParentId()))
             return false;
 
         return true;
@@ -129,13 +143,12 @@ public class DeviceType extends Structure {
         sb.append("\"id\": "                     + getId());
         sb.append(", \"version\": "              + getVersion());
         sb.append(", \"uuid\": "                 + getUuid());
-        sb.append(", \"parent_uuid\": "          + getParentUuid());
+        sb.append(", \"parent_id\": "            + getParentId());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
         sb.append(", \"ordering\": "             + getOrdering());
         sb.append(", \"description\": "          + getDescription());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append(", \"requested\": "            + getRequested());
         sb.append(", \"requested_by\": "         + getRequestedBy());
@@ -155,7 +168,6 @@ public class DeviceType extends Structure {
         sb.append(", \"uuid\": "                 + getUuid());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/repository/model/Discipline.java b/src/main/java/org/openepics/names/repository/model/Discipline.java
index 8d399c9fcc0e6d46d9a67974c465d209033e7588..86cdec21a189fa39e4e6c9a5e2b1bebbfef733af 100644
--- a/src/main/java/org/openepics/names/repository/model/Discipline.java
+++ b/src/main/java/org/openepics/names/repository/model/Discipline.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -42,13 +42,13 @@ public class Discipline extends Structure {
     private static final long serialVersionUID = 8729921221024362502L;
 
     /**
-     * Constructor for Discipline.
+     * Constructor for discipline.
      */
     public Discipline() {
     }
 
     /**
-     * Constructor for Discipline.
+     * Constructor for discipline.
      *
      * @param uuid uuid
      * @param mnemonic mnemonic
@@ -56,21 +56,33 @@ public class Discipline extends Structure {
      * @param ordering ordering
      * @param description description
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param processed processed
      * @param processedBy processed by
      * @param processedComment processed comment
      */
     public Discipline(UUID uuid,
-            String mnemonic, String mnemonicEquivalence, Integer ordering,
-            String description, Status status, Boolean latest, Boolean deleted,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean deleted,
             Date processed, String processedBy, String processedComment) {
         super(uuid, mnemonic, mnemonicEquivalence, ordering,
-                description, status, latest, deleted,
+                description, status, deleted,
                 processed, processedBy, processedComment);
     }
 
+    /**
+     * Constructor for discipline.
+     *
+     * @param auditStructure audit structure
+     */
+    public Discipline(AuditStructure auditStructure) {
+        super(auditStructure.getUuid(),
+                auditStructure.getMnemonic(), auditStructure.getMnemonicEquivalence(), auditStructure.getOrdering(), auditStructure.getDescription(),
+                auditStructure.getStatus(), auditStructure.isDeleted(),
+                auditStructure.getProcessed(), auditStructure.getProcessedBy(), auditStructure.getProcessedComment());
+        this.id = auditStructure.getId();
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (this == obj)
@@ -111,7 +123,6 @@ public class Discipline extends Structure {
         sb.append(", \"ordering\": "             + getOrdering());
         sb.append(", \"description\": "          + getDescription());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append(", \"requested\": "            + getRequested());
         sb.append(", \"requested_by\": "         + getRequestedBy());
@@ -131,7 +142,6 @@ public class Discipline extends Structure {
         sb.append(", \"uuid\": "                 + getUuid());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/repository/model/Name.java b/src/main/java/org/openepics/names/repository/model/Name.java
index 68c8537a1b78668c38b9fadc2e5ae032d16589f0..6824ec657e35ed99a8c2f2a1b05de6b458344f08 100644
--- a/src/main/java/org/openepics/names/repository/model/Name.java
+++ b/src/main/java/org/openepics/names/repository/model/Name.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -43,22 +43,22 @@ public class Name extends NameStructure implements Serializable {
      */
     private static final long serialVersionUID = 7313392211143183879L;
 
-    public static final String FIELD_SYSTEM_GROUP_UUID           = "systemgroupUuid";
-    public static final String FIELD_SYSTEM_UUID                 = "systemUuid";
-    public static final String FIELD_SUBSYSTEM_UUID              = "subsystemUuid";
-    public static final String FIELD_DEVICETYPE_UUID             = "devicetypeUuid";
+    public static final String FIELD_SYSTEM_GROUP_ID             = "systemgroupId";
+    public static final String FIELD_SYSTEM_ID                   = "systemId";
+    public static final String FIELD_SUBSYSTEM_ID                = "subsystemId";
+    public static final String FIELD_DEVICETYPE_ID               = "devicetypeId";
     public static final String FIELD_INSTANCE_INDEX              = "instanceIndex";
     public static final String FIELD_CONVENTION_NAME             = "conventionName";
     public static final String FIELD_CONVENTION_NAME_EQUIVALENCE = "conventionNameEquivalence";
 
-    @Column(name = "systemgroup_uuid")
-    private String systemGroupUuid;
-    @Column(name = "system_uuid")
-    private String systemUuid;
-    @Column(name = "subsystem_uuid")
-    private String subsystemUuid;
-    @Column(name = "devicetype_uuid")
-    private String deviceTypeUuid;
+    @Column(name = "systemgroup_id")
+    private Long systemGroupId;
+    @Column(name = "system_id")
+    private Long systemId;
+    @Column(name = "subsystem_id")
+    private Long subsystemId;
+    @Column(name = "devicetype_id")
+    private Long deviceTypeId;
     @Column(name = "instance_index")
     private String instanceIndex;
     @Column(name = "convention_name")
@@ -67,74 +67,72 @@ public class Name extends NameStructure implements Serializable {
     private String conventionNameEquivalence;
 
     /**
-     * Constructor for Name.
+     * Constructor for name.
      */
     public Name() {
     }
 
     /**
-     * Constructor for Name.
+     * Constructor for name.
      *
      * @param uuid uuid
-     * @param systemGroupUuid system group uuid
-     * @param systemUuid system uuid
-     * @param subsystemUuid subsystem uuid
-     * @param deviceTypeUuid device type uuid
+     * @param systemGroupId system group id
+     * @param systemId system id
+     * @param subsystemId subsystem id
+     * @param deviceTypeId device type id
      * @param index index
      * @param conventionName convention name
      * @param conventionNameEquivalence convention name equivalence
      * @param description description
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param requested requested
      * @param requestedBy requested by
      * @param requestedComment requested comment
      */
-    public Name(UUID uuid, UUID systemGroupUuid, UUID systemUuid, UUID subsystemUuid, UUID deviceTypeUuid,
+    public Name(UUID uuid, Long systemGroupId, Long systemId, Long subsystemId, Long deviceTypeId,
             String index, String conventionName, String conventionNameEquivalence, String description,
-            Status status, Boolean latest, Boolean deleted,
+            Status status, Boolean deleted,
             Date requested, String requestedBy, String requestedComment) {
         setUuid(uuid);
-        setSystemGroupUuid(systemGroupUuid);
-        setSystemUuid(systemUuid);
-        setSubsystemUuid(subsystemUuid);
-        setDeviceTypeUuid(deviceTypeUuid);
+        setSystemGroupId(systemGroupId);
+        setSystemId(systemId);
+        setSubsystemId(subsystemId);
+        setDeviceTypeId(deviceTypeId);
         setInstanceIndex(index);
         setConventionName(conventionName);
         setConventionNameEquivalence(conventionNameEquivalence);
         setDescription(description);
-        setStatus(Status.APPROVED);
-        setLatest(latest);
+        setStatus(status);
         setDeleted(deleted);
         setRequested(requested);
         setRequestedBy(requestedBy);
         setRequestedComment(requestedComment);
     }
 
-    public UUID getSystemGroupUuid() {
-        return systemGroupUuid != null ? UUID.fromString(systemGroupUuid) : null;
+    public Long getSystemGroupId() {
+        return systemGroupId;
     }
-    public void setSystemGroupUuid(UUID systemGroupUuid) {
-        this.systemGroupUuid = systemGroupUuid != null ? systemGroupUuid.toString() : null;
+    public void setSystemGroupId(Long systemGroupId) {
+        this.systemGroupId = systemGroupId;
     }
-    public UUID getSystemUuid() {
-        return systemUuid != null ? UUID.fromString(systemUuid) : null;
+    public Long getSystemId() {
+        return systemId;
     }
-    public void setSystemUuid(UUID systemUuid) {
-        this.systemUuid = systemUuid != null ? systemUuid.toString() : null;
+    public void setSystemId(Long systemId) {
+        this.systemId = systemId;
     }
-    public UUID getSubsystemUuid() {
-        return subsystemUuid != null ? UUID.fromString(subsystemUuid) : null;
+    public Long getSubsystemId() {
+        return subsystemId;
     }
-    public void setSubsystemUuid(UUID subsystemUuid) {
-        this.subsystemUuid = subsystemUuid != null ? subsystemUuid.toString() : null;
+    public void setSubsystemId(Long subsystemId) {
+        this.subsystemId = subsystemId;
     }
-    public UUID getDeviceTypeUuid() {
-        return deviceTypeUuid != null ? UUID.fromString(deviceTypeUuid) : null;
+    public Long getDeviceTypeId() {
+        return deviceTypeId;
     }
-    public void setDeviceTypeUuid(UUID deviceTypeUuid) {
-        this.deviceTypeUuid = deviceTypeUuid != null ? deviceTypeUuid.toString() : null;
+    public void setDeviceTypeId(Long deviceTypeId) {
+        this.deviceTypeId = deviceTypeId;
     }
     public String getInstanceIndex() {
         return instanceIndex;
@@ -175,25 +173,25 @@ public class Name extends NameStructure implements Serializable {
             return false;
         }
 
-        if (getSystemGroupUuid() == null) {
-            if (other.getSystemGroupUuid() != null)
+        if (getSystemGroupId() == null) {
+            if (other.getSystemGroupId() != null)
                 return false;
-        } else if (!getSystemGroupUuid().equals(other.getSystemGroupUuid()))
+        } else if (!getSystemGroupId().equals(other.getSystemGroupId()))
             return false;
-        if (getSystemUuid() == null) {
-            if (other.getSystemUuid() != null)
+        if (getSystemId() == null) {
+            if (other.getSystemId() != null)
                 return false;
-        } else if (!getSystemUuid().equals(other.getSystemUuid()))
+        } else if (!getSystemId().equals(other.getSystemId()))
             return false;
-        if (getSubsystemUuid() == null) {
-            if (other.getSubsystemUuid() != null)
+        if (getSubsystemId() == null) {
+            if (other.getSubsystemId() != null)
                 return false;
-        } else if (!getSubsystemUuid().equals(other.getSubsystemUuid()))
+        } else if (!getSubsystemId().equals(other.getSubsystemId()))
             return false;
-        if (getDeviceTypeUuid() == null) {
-            if (other.getDeviceTypeUuid() != null)
+        if (getDeviceTypeId() == null) {
+            if (other.getDeviceTypeId() != null)
                 return false;
-        } else if (!getDeviceTypeUuid().equals(other.getDeviceTypeUuid()))
+        } else if (!getDeviceTypeId().equals(other.getDeviceTypeId()))
             return false;
         if (getInstanceIndex() == null) {
             if (other.getInstanceIndex() != null)
@@ -226,16 +224,15 @@ public class Name extends NameStructure implements Serializable {
         sb.append("\"id\": "                            + getId());
         sb.append(", \"version\": "                     + getVersion());
         sb.append(", \"uuid\": "                        + getUuid());
-        sb.append(", \"systemgroup_uuid\": "            + getSystemGroupUuid());
-        sb.append(", \"system_uuid\": "                 + getSystemUuid());
-        sb.append(", \"subsystem_uuid\": "              + getSubsystemUuid());
-        sb.append(", \"devicetype_uuid\": "             + getDeviceTypeUuid());
+        sb.append(", \"systemgroup_id\": "              + getSystemGroupId());
+        sb.append(", \"system_id\": "                   + getSystemId());
+        sb.append(", \"subsystem_id\": "                + getSubsystemId());
+        sb.append(", \"devicetype_id\": "               + getDeviceTypeId());
         sb.append(", \"instance_index\": "              + getInstanceIndex());
         sb.append(", \"convention_name\": "             + getConventionName());
         sb.append(", \"convention_name_equivalence\": " + getConventionNameEquivalence());
         sb.append(", \"description\": "                 + getDescription());
         sb.append(", \"status\": "                      + getStatus());
-        sb.append(", \"latest\": "                      + isLatest());
         sb.append(", \"deleted\": "                     + isDeleted());
         sb.append(", \"requested\": "                   + getRequested());
         sb.append(", \"requested_by\": "                + getRequestedBy());
@@ -254,7 +251,6 @@ public class Name extends NameStructure implements Serializable {
         sb.append(", \"uuid\": "                        + getUuid());
         sb.append(", \"convention_name\": "             + getConventionName());
         sb.append(", \"status\": "                      + getStatus());
-        sb.append(", \"latest\": "                      + isLatest());
         sb.append(", \"deleted\": "                     + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/repository/model/NameStructure.java b/src/main/java/org/openepics/names/repository/model/NameStructure.java
index 80b8c13735dd988dd8a2156a01b7a5fa616a15ad..78bb7bb839db1e6ac3cd70856b28e4027886a224 100644
--- a/src/main/java/org/openepics/names/repository/model/NameStructure.java
+++ b/src/main/java/org/openepics/names/repository/model/NameStructure.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -47,7 +47,6 @@ public class NameStructure extends Persistable implements Serializable {
     public static final String FIELD_UUID              = "uuid";
     public static final String FIELD_DESCRIPTION       = "description";
     public static final String FIELD_STATUS            = "status";
-    public static final String FIELD_LATEST            = "latest";
     public static final String FIELD_DELETED           = "deleted";
     public static final String FIELD_REQUESTED         = "requested";
     public static final String FIELD_REQUESTED_BY      = "requestedBy";
@@ -64,7 +63,6 @@ public class NameStructure extends Persistable implements Serializable {
     private String description;
     @Enumerated(EnumType.STRING)
     private Status status;
-    private Boolean latest;
     private Boolean deleted;
     private Date requested;
     @Column(name = "requested_by")
@@ -95,12 +93,6 @@ public class NameStructure extends Persistable implements Serializable {
     public void setStatus(Status status) {
         this.status = status;
     }
-    public Boolean isLatest() {
-        return latest;
-    }
-    public void setLatest(Boolean latest) {
-        this.latest = latest;
-    }
     public Boolean isDeleted() {
         return deleted;
     }
@@ -144,6 +136,32 @@ public class NameStructure extends Persistable implements Serializable {
         this.processedComment = processedComment;
     }
 
+    /**
+     * Utility method to help set attributes for structure class, which in practice is either of its sub classes.
+     *
+     * @param requested requested
+     * @param requestedBy requested by
+     * @param requestedComment requested comment
+     */
+    public void setAttributesRequested(Date requested, String requestedBy, String requestedComment) {
+        setRequested(requested);
+        setRequestedBy(requestedBy);
+        setRequestedComment(requestedComment);
+    }
+
+    /**
+     * Utility method to help set attributes for structure class, which in practice is either of its sub classes.
+     *
+     * @param processed processed
+     * @param processedBy processed by
+     * @param processedComment processed comment
+     */
+    public void setAttributesProcessed(Date processed, String processedBy, String processedComment) {
+        setProcessed(processed);
+        setProcessedBy(processedBy);
+        setProcessedComment(processedComment);
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (this == obj)
@@ -179,11 +197,6 @@ public class NameStructure extends Persistable implements Serializable {
                 return false;
         } else if (!getStatus().equals(other.getStatus()))
             return false;
-        if (isLatest() == null) {
-            if (other.isLatest() != null)
-                return false;
-        } else if (!isLatest().equals(other.isLatest()))
-            return false;
         if (isDeleted() == null) {
             if (other.isDeleted() != null)
                 return false;
diff --git a/src/main/java/org/openepics/names/repository/model/Structure.java b/src/main/java/org/openepics/names/repository/model/Structure.java
index 5834488de0d62a88ecbc28eb912bde598e8f4433..757c579aded583404bcb915b12f6eb2d7fbe8847 100644
--- a/src/main/java/org/openepics/names/repository/model/Structure.java
+++ b/src/main/java/org/openepics/names/repository/model/Structure.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -52,13 +52,13 @@ public class Structure extends NameStructure implements Serializable {
     private Integer ordering;
 
     /**
-     * Constructor for Structure.
+     * Constructor for structure.
      */
     public Structure() {
     }
 
     /**
-     * Constructor for Structure.
+     * Constructor for structure.
      *
      * @param uuid uuid
      * @param mnemonic mnemonic
@@ -66,14 +66,14 @@ public class Structure extends NameStructure implements Serializable {
      * @param ordering ordering
      * @param description description
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param processed processed
      * @param processedBy processed by
      * @param processedComment processed comment
      */
-    public Structure(UUID uuid, String mnemonic, String mnemonicEquivalence, Integer ordering,
-            String description, Status status, Boolean latest, Boolean deleted,
+    public Structure(UUID uuid,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean deleted,
             Date processed, String processedBy, String processedComment) {
         setUuid(uuid);
         setMnemonic(mnemonic);
@@ -81,7 +81,6 @@ public class Structure extends NameStructure implements Serializable {
         setOrdering(ordering);
         setDescription(description);
         setStatus(status);
-        setLatest(latest);
         setDeleted(deleted);
         setProcessed(processed);
         setProcessedBy(processedBy);
@@ -107,21 +106,6 @@ public class Structure extends NameStructure implements Serializable {
         this.ordering = ordering;
     }
 
-    /**
-     * Utility method to help set attributes for Structure class, which in practice is either of its sub classes.
-     *
-     * @param status status
-     * @param processed processed
-     * @param processedBy processed by
-     * @param processedComment processed comment
-     */
-    public void setAttributesStatusProcessed(Status status, Date processed, String processedBy, String processedComment) {
-        setStatus(status);
-        setProcessed(processed);
-        setProcessedBy(processedBy);
-        setProcessedComment(processedComment);
-    }
-
     @Override
     public boolean equals(Object obj) {
         if (this == obj)
@@ -178,7 +162,6 @@ public class Structure extends NameStructure implements Serializable {
         sb.append(", \"ordering\": "             + getOrdering());
         sb.append(", \"description\": "          + getDescription());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append(", \"requested\": "            + getRequested());
         sb.append(", \"requested_by\": "         + getRequestedBy());
@@ -197,7 +180,6 @@ public class Structure extends NameStructure implements Serializable {
         sb.append(", \"uuid\": "                 + getUuid());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/repository/model/Subsystem.java b/src/main/java/org/openepics/names/repository/model/Subsystem.java
index d2c7566f9c4a26381e25971e76f289c7bc73bacd..dc004f92fbcb733adbd2833e67023f2fc9d34365 100644
--- a/src/main/java/org/openepics/names/repository/model/Subsystem.java
+++ b/src/main/java/org/openepics/names/repository/model/Subsystem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -42,50 +42,64 @@ public class Subsystem extends Structure {
      */
     private static final long serialVersionUID = 5662135540008222500L;
 
-    public static final String FIELD_PARENT_UUID = "parentUuid";
+    public static final String FIELD_PARENT_ID = "parentId";
 
+    public static final String FUNCTION_GET_PARENT_UUID_SUBSYSTEM   = "get_parent_uuid_subsystem";
     public static final String FUNCTION_GET_MNEMONIC_PATH_SUBSYSTEM = "get_mnemonic_path_subsystem";
 
-    @Column(name = "parent_uuid")
-    private String parentUuid;
+    @Column(name = "parent_id")
+    private Long parentId;
 
     /**
-     * Constructor for Subsystem.
+     * Constructor for subsystem.
      */
     public Subsystem() {
     }
 
     /**
-     * Constructor for Subsystem.
+     * Constructor for subsystem.
      *
      * @param uuid uuid
-     * @param parentUuid parent uuid
+     * @param parentId parent id
      * @param mnemonic mnemonic
      * @param mnemonicEquivalence mnemonic equivalence
      * @param ordering ordering
      * @param description description
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param processed processed
      * @param processedBy processed by
      * @param processedComment processed comment
      */
-    public Subsystem(UUID uuid, UUID parentUuid,
-            String mnemonic, String mnemonicEquivalence, Integer ordering,
-            String description, Status status, Boolean latest, Boolean deleted,
+    public Subsystem(UUID uuid, Long parentId,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean deleted,
             Date processed, String processedBy, String processedComment) {
         super(uuid, mnemonic, mnemonicEquivalence, ordering,
-                description, status, latest, deleted,
+                description, status, deleted,
                 processed, processedBy, processedComment);
-        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+        setParentId(parentId);
     }
 
-    public UUID getParentUuid() {
-        return parentUuid != null ? UUID.fromString(parentUuid) : null;
+    /**
+     * Constructor for subsystem.
+     *
+     * @param auditStructure audit structure
+     */
+    public Subsystem(AuditStructure auditStructure) {
+        super(auditStructure.getUuid(),
+                auditStructure.getMnemonic(), auditStructure.getMnemonicEquivalence(), auditStructure.getOrdering(), auditStructure.getDescription(),
+                auditStructure.getStatus(), auditStructure.isDeleted(),
+                auditStructure.getProcessed(), auditStructure.getProcessedBy(), auditStructure.getProcessedComment());
+        setParentId(auditStructure.getParentId());
+        this.id = auditStructure.getId();
+    }
+
+    public Long getParentId() {
+        return parentId;
     }
-    public void setParentUuid(UUID parentUuid) {
-        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
     }
 
     @Override
@@ -108,10 +122,10 @@ public class Subsystem extends Structure {
             return false;
         }
 
-        if (getParentUuid() == null) {
-            if (other.getParentUuid() != null)
+        if (getParentId() == null) {
+            if (other.getParentId() != null)
                 return false;
-        } else if (!getParentUuid().equals(other.getParentUuid()))
+        } else if (!getParentId().equals(other.getParentId()))
             return false;
 
         return true;
@@ -129,13 +143,12 @@ public class Subsystem extends Structure {
         sb.append("\"id\": "                     + getId());
         sb.append(", \"version\": "              + getVersion());
         sb.append(", \"uuid\": "                 + getUuid());
-        sb.append(", \"parent_uuid\": "          + getParentUuid());
+        sb.append(", \"parent_id\": "            + getParentId());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
         sb.append(", \"ordering\": "             + getOrdering());
         sb.append(", \"description\": "          + getDescription());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append(", \"requested\": "            + getRequested());
         sb.append(", \"requested_by\": "         + getRequestedBy());
@@ -155,7 +168,6 @@ public class Subsystem extends Structure {
         sb.append(", \"uuid\": "                 + getUuid());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/repository/model/System.java b/src/main/java/org/openepics/names/repository/model/System.java
index 06fdd37705cf746d4c56f0c1ea2ad8f0a2bba68a..9a85ac044ce0500768b28f64eb432793d9505f0b 100644
--- a/src/main/java/org/openepics/names/repository/model/System.java
+++ b/src/main/java/org/openepics/names/repository/model/System.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -42,50 +42,65 @@ public class System extends Structure {
      */
     private static final long serialVersionUID = -4323438470765348486L;
 
-    public static final String FIELD_PARENT_UUID = "parentUuid";
+    public static final String FIELD_PARENT_ID = "parentId";
 
+    public static final String FUNCTION_GET_PARENT_UUID_SYSTEM   = "get_parent_uuid_system";
     public static final String FUNCTION_GET_MNEMONIC_PATH_SYSTEM = "get_mnemonic_path_system";
 
-    @Column(name = "parent_uuid")
-    private String parentUuid;
+    @Column(name = "parent_id")
+    private Long parentId;
 
     /**
-     * Constructor for System.
+     * Constructor for system.
      */
     public System() {
     }
 
     /**
-     * Constructor for System.
+     * Constructor for system.
      *
      * @param uuid uuid
-     * @param parentUuid parent uuid
+     * @param parentId parent id
      * @param mnemonic mnemonic
      * @param mnemonicEquivalence mnemonic equivalence
      * @param ordering ordering
      * @param description description
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param processed processed
      * @param processedBy processed by
      * @param processedComment processed comment
      */
-    public System(UUID uuid, UUID parentUuid,
-            String mnemonic, String mnemonicEquivalence, Integer ordering,
-            String description, Status status, Boolean latest, Boolean deleted,
+    public System(UUID uuid, Long parentId,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean deleted,
             Date processed, String processedBy, String processedComment) {
-        super(uuid, mnemonic, mnemonicEquivalence, ordering,
-                description, status, latest, deleted,
+        super(uuid,
+                mnemonic, mnemonicEquivalence, ordering, description,
+                status, deleted,
                 processed, processedBy, processedComment);
-        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+        setParentId(parentId);
     }
 
-    public UUID getParentUuid() {
-        return parentUuid != null ? UUID.fromString(parentUuid) : null;
+    /**
+     * Constructor for system.
+     *
+     * @param auditStructure audit structure
+     */
+    public System(AuditStructure auditStructure) {
+        super(auditStructure.getUuid(),
+                auditStructure.getMnemonic(), auditStructure.getMnemonicEquivalence(), auditStructure.getOrdering(), auditStructure.getDescription(),
+                auditStructure.getStatus(), auditStructure.isDeleted(),
+                auditStructure.getProcessed(), auditStructure.getProcessedBy(), auditStructure.getProcessedComment());
+        setParentId(auditStructure.getParentId());
+        this.id = auditStructure.getId();
+    }
+
+    public Long getParentId() {
+        return parentId;
     }
-    public void setParentUuid(UUID parentUuid) {
-        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+    public void setParentId(Long parentId) {
+        this.parentId = parentId;
     }
 
     @Override
@@ -108,10 +123,10 @@ public class System extends Structure {
             return false;
         }
 
-        if (getParentUuid() == null) {
-            if (other.getParentUuid() != null)
+        if (getParentId() == null) {
+            if (other.getParentId() != null)
                 return false;
-        } else if (!getParentUuid().equals(other.getParentUuid()))
+        } else if (!getParentId().equals(other.getParentId()))
             return false;
 
         return true;
@@ -129,13 +144,12 @@ public class System extends Structure {
         sb.append("\"id\": "                     + getId());
         sb.append(", \"version\": "              + getVersion());
         sb.append(", \"uuid\": "                 + getUuid());
-        sb.append(", \"parent_uuid\": "          + getParentUuid());
+        sb.append(", \"parent_id\": "            + getParentId());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
         sb.append(", \"ordering\": "             + getOrdering());
         sb.append(", \"description\": "          + getDescription());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append(", \"requested\": "            + getRequested());
         sb.append(", \"requested_by\": "         + getRequestedBy());
@@ -155,7 +169,6 @@ public class System extends Structure {
         sb.append(", \"uuid\": "                 + getUuid());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/repository/model/SystemGroup.java b/src/main/java/org/openepics/names/repository/model/SystemGroup.java
index 8ffa171fc73e18e68c035f553e24d681a68d05ef..3e4055728b7ea66920b394cbc27316305bb2bba6 100644
--- a/src/main/java/org/openepics/names/repository/model/SystemGroup.java
+++ b/src/main/java/org/openepics/names/repository/model/SystemGroup.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -42,13 +42,13 @@ public class SystemGroup extends Structure {
     private static final long serialVersionUID = 6298835206366539021L;
 
     /**
-     * Constructor for SystemGroup.
+     * Constructor for system group.
      */
     public SystemGroup() {
     }
 
     /**
-     * Constructor for SystemGroup.
+     * Constructor for system group.
      *
      * @param uuid uuid
      * @param mnemonic mnemonic
@@ -56,21 +56,34 @@ public class SystemGroup extends Structure {
      * @param ordering ordering
      * @param description description
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param processed processed
      * @param processedBy processed by
      * @param processedComment processed comment
      */
     public SystemGroup(UUID uuid,
-            String mnemonic, String mnemonicEquivalence, Integer ordering,
-            String description, Status status, Boolean latest, Boolean deleted,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean deleted,
             Date processed, String processedBy, String processedComment) {
-        super(uuid, mnemonic, mnemonicEquivalence, ordering,
-                description, status, latest, deleted,
+        super(uuid,
+                mnemonic, mnemonicEquivalence, ordering, description,
+                status, deleted,
                 processed, processedBy, processedComment);
     }
 
+    /**
+     * Constructor for system group.
+     *
+     * @param auditStructure audit structure
+     */
+    public SystemGroup(AuditStructure auditStructure) {
+        super(auditStructure.getUuid(),
+                auditStructure.getMnemonic(), auditStructure.getMnemonicEquivalence(), auditStructure.getOrdering(), auditStructure.getDescription(),
+                auditStructure.getStatus(), auditStructure.isDeleted(),
+                auditStructure.getProcessed(), auditStructure.getProcessedBy(), auditStructure.getProcessedComment());
+        this.id = auditStructure.getId();
+    }
+
     @Override
     public boolean equals(Object obj) {
         if (this == obj)
@@ -111,7 +124,6 @@ public class SystemGroup extends Structure {
         sb.append(", \"ordering\": "             + getOrdering());
         sb.append(", \"description\": "          + getDescription());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append(", \"requested\": "            + getRequested());
         sb.append(", \"requested_by\": "         + getRequestedBy());
@@ -131,7 +143,6 @@ public class SystemGroup extends Structure {
         sb.append(", \"uuid\": "                 + getUuid());
         sb.append(", \"mnemonic\": "             + getMnemonic());
         sb.append(", \"status\": "               + getStatus());
-        sb.append(", \"latest\": "               + isLatest());
         sb.append(", \"deleted\": "              + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/repository/model/wip/WipDeviceGroup.java b/src/main/java/org/openepics/names/repository/model/wip/WipDeviceGroup.java
new file mode 100644
index 0000000000000000000000000000000000000000..fcd603921462fbbc655912bb8faa83b9c0297716
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/wip/WipDeviceGroup.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2021 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.repository.model.wip;
+
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * This entity represents a device group name part.
+ *
+ * @author Lars Johansson
+ */
+@Entity
+@Table(name = "wip_devicegroup")
+public class WipDeviceGroup extends WipStructure {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8762287473417706804L;
+
+    public static final String FIELD_PARENT_UUID = "parentUuid";
+
+    public static final String FUNCTION_GET_MNEMONIC_PATH_DEVICEGROUP = "wip_get_mnemonic_path_devicegroup";
+
+    @Column(name = "parent_uuid")
+    private String parentUuid;
+
+    /**
+     * Constructor for DeviceGroup.
+     */
+    public WipDeviceGroup() {
+    }
+
+    /**
+     * Constructor for DeviceGroup.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param ordering ordering
+     * @param description description
+     * @param status status
+     * @param latest latest
+     * @param deleted deleted
+     * @param processed processed
+     * @param processedBy processed by
+     * @param processedComment processed comment
+     */
+    public WipDeviceGroup(UUID uuid, UUID parentUuid,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean latest, Boolean deleted,
+            Date processed, String processedBy, String processedComment) {
+        super(uuid, mnemonic, mnemonicEquivalence, ordering,
+                description, status, latest, deleted,
+                processed, processedBy, processedComment);
+        setParentUuid(parentUuid);
+    }
+
+    public UUID getParentUuid() {
+        return parentUuid != null ? UUID.fromString(parentUuid) : null;
+    }
+    public void setParentUuid(UUID parentUuid) {
+        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals ((WipDeviceGroup) obj);
+    }
+
+    public boolean equals(WipDeviceGroup other) {
+        if (other == null)
+            return false;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        if (getParentUuid() == null) {
+            if (other.getParentUuid() != null)
+                return false;
+        } else if (!getParentUuid().equals(other.getParentUuid()))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                     + getId());
+        sb.append(", \"version\": "              + getVersion());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"parent_uuid\": "          + getParentUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
+        sb.append(", \"ordering\": "             + getOrdering());
+        sb.append(", \"description\": "          + getDescription());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append(", \"requested\": "            + getRequested());
+        sb.append(", \"requested_by\": "         + getRequestedBy());
+        sb.append(", \"requested_comment\": "    + getRequestedComment());
+        sb.append(", \"processed\": "            + getProcessed());
+        sb.append(", \"processed_by\": "         + getProcessedBy());
+        sb.append(", \"processed_comment\": "    + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public String toStringSimple() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": " + getId());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/wip/WipDeviceType.java b/src/main/java/org/openepics/names/repository/model/wip/WipDeviceType.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac3bedf7f71bc5faf24dd16d83cf19aa93014a20
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/wip/WipDeviceType.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2021 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.repository.model.wip;
+
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * This entity represents a device type name part.
+ *
+ * @author Lars Johansson
+ */
+@Entity
+@Table(name = "wip_devicetype")
+public class WipDeviceType extends WipStructure {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 2061731870402041740L;
+
+    public static final String FIELD_PARENT_UUID = "parentUuid";
+
+    public static final String FUNCTION_GET_MNEMONIC_PATH_DEVICETYPE = "wip_get_mnemonic_path_devicetype";
+
+    @Column(name = "parent_uuid")
+    private String parentUuid;
+
+    /**
+     * Constructor for DeviceType.
+     */
+    public WipDeviceType() {
+    }
+
+    /**
+     * Constructor for DeviceType.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param ordering ordering
+     * @param description description
+     * @param status status
+     * @param latest latest
+     * @param deleted deleted
+     * @param processed processed
+     * @param processedBy processed by
+     * @param processedComment processed comment
+     */
+    public WipDeviceType(UUID uuid, UUID parentUuid,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean latest, Boolean deleted,
+            Date processed, String processedBy, String processedComment) {
+        super(uuid, mnemonic, mnemonicEquivalence, ordering,
+                description, status, latest, deleted,
+                processed, processedBy, processedComment);
+        setParentUuid(parentUuid);
+    }
+
+    public UUID getParentUuid() {
+        return parentUuid != null ? UUID.fromString(parentUuid) : null;
+    }
+    public void setParentUuid(UUID parentUuid) {
+        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals ((WipDeviceType) obj);
+    }
+
+    public boolean equals(WipDeviceType other) {
+        if (other == null)
+            return false;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        if (getParentUuid() == null) {
+            if (other.getParentUuid() != null)
+                return false;
+        } else if (!getParentUuid().equals(other.getParentUuid()))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                     + getId());
+        sb.append(", \"version\": "              + getVersion());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"parent_uuid\": "          + getParentUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
+        sb.append(", \"ordering\": "             + getOrdering());
+        sb.append(", \"description\": "          + getDescription());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append(", \"requested\": "            + getRequested());
+        sb.append(", \"requested_by\": "         + getRequestedBy());
+        sb.append(", \"requested_comment\": "    + getRequestedComment());
+        sb.append(", \"processed\": "            + getProcessed());
+        sb.append(", \"processed_by\": "         + getProcessedBy());
+        sb.append(", \"processed_comment\": "    + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public String toStringSimple() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": " + getId());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/wip/WipDiscipline.java b/src/main/java/org/openepics/names/repository/model/wip/WipDiscipline.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb42f45700e095de2ab3aecfe433d5e3e476c18e
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/wip/WipDiscipline.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2021 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.repository.model.wip;
+
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * This entity represents a discipline name part.
+ *
+ * @author Lars Johansson
+ */
+@Entity
+@Table(name = "wip_discipline")
+public class WipDiscipline extends WipStructure {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 8729921221024362502L;
+
+    /**
+     * Constructor for Discipline.
+     */
+    public WipDiscipline() {
+    }
+
+    /**
+     * Constructor for Discipline.
+     *
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param ordering ordering
+     * @param description description
+     * @param status status
+     * @param latest latest
+     * @param deleted deleted
+     * @param processed processed
+     * @param processedBy processed by
+     * @param processedComment processed comment
+     */
+    public WipDiscipline(UUID uuid,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean latest, Boolean deleted,
+            Date processed, String processedBy, String processedComment) {
+        super(uuid, mnemonic, mnemonicEquivalence, ordering,
+                description, status, latest, deleted,
+                processed, processedBy, processedComment);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals ((WipDiscipline) obj);
+    }
+
+    public boolean equals(WipDiscipline other) {
+        if (other == null)
+            return false;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                     + getId());
+        sb.append(", \"version\": "              + getVersion());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
+        sb.append(", \"ordering\": "             + getOrdering());
+        sb.append(", \"description\": "          + getDescription());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append(", \"requested\": "            + getRequested());
+        sb.append(", \"requested_by\": "         + getRequestedBy());
+        sb.append(", \"requested_comment\": "    + getRequestedComment());
+        sb.append(", \"processed\": "            + getProcessed());
+        sb.append(", \"processed_by\": "         + getProcessedBy());
+        sb.append(", \"processed_comment\": "    + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public String toStringSimple() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": " + getId());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/wip/WipName.java b/src/main/java/org/openepics/names/repository/model/wip/WipName.java
new file mode 100644
index 0000000000000000000000000000000000000000..49528e2f7f32aca880d1151ff53ca79daee7e1e4
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/wip/WipName.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2021 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.repository.model.wip;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * This entity represents a name.
+ *
+ * @author Lars Johansson
+ */
+@Entity
+@Table(name = "wip_name")
+public class WipName extends WipNameStructure implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 7313392211143183879L;
+
+    public static final String FIELD_SYSTEM_GROUP_UUID           = "systemgroupUuid";
+    public static final String FIELD_SYSTEM_UUID                 = "systemUuid";
+    public static final String FIELD_SUBSYSTEM_UUID              = "subsystemUuid";
+    public static final String FIELD_DEVICETYPE_UUID             = "devicetypeUuid";
+    public static final String FIELD_INSTANCE_INDEX              = "instanceIndex";
+    public static final String FIELD_CONVENTION_NAME             = "conventionName";
+    public static final String FIELD_CONVENTION_NAME_EQUIVALENCE = "conventionNameEquivalence";
+
+    @Column(name = "systemgroup_uuid")
+    private String systemGroupUuid;
+    @Column(name = "system_uuid")
+    private String systemUuid;
+    @Column(name = "subsystem_uuid")
+    private String subsystemUuid;
+    @Column(name = "devicetype_uuid")
+    private String deviceTypeUuid;
+    @Column(name = "instance_index")
+    private String instanceIndex;
+    @Column(name = "convention_name")
+    private String conventionName;
+    @Column(name = "convention_name_equivalence")
+    private String conventionNameEquivalence;
+
+    /**
+     * Constructor for Name.
+     */
+    public WipName() {
+    }
+
+    /**
+     * Constructor for Name.
+     *
+     * @param uuid uuid
+     * @param systemGroupUuid system group uuid
+     * @param systemUuid system uuid
+     * @param subsystemUuid subsystem uuid
+     * @param deviceTypeUuid device type uuid
+     * @param index index
+     * @param conventionName convention name
+     * @param conventionNameEquivalence convention name equivalence
+     * @param description description
+     * @param status status
+     * @param latest latest
+     * @param deleted deleted
+     * @param requested requested
+     * @param requestedBy requested by
+     * @param requestedComment requested comment
+     */
+    public WipName(UUID uuid, UUID systemGroupUuid, UUID systemUuid, UUID subsystemUuid, UUID deviceTypeUuid,
+            String index, String conventionName, String conventionNameEquivalence, String description,
+            Status status, Boolean latest, Boolean deleted,
+            Date requested, String requestedBy, String requestedComment) {
+        setUuid(uuid);
+        setSystemGroupUuid(systemGroupUuid);
+        setSystemUuid(systemUuid);
+        setSubsystemUuid(subsystemUuid);
+        setDeviceTypeUuid(deviceTypeUuid);
+        setInstanceIndex(index);
+        setConventionName(conventionName);
+        setConventionNameEquivalence(conventionNameEquivalence);
+        setDescription(description);
+        setStatus(status);
+        setLatest(latest);
+        setDeleted(deleted);
+        setRequested(requested);
+        setRequestedBy(requestedBy);
+        setRequestedComment(requestedComment);
+    }
+
+    public UUID getSystemGroupUuid() {
+        return systemGroupUuid != null ? UUID.fromString(systemGroupUuid) : null;
+    }
+    public void setSystemGroupUuid(UUID systemGroupUuid) {
+        this.systemGroupUuid = systemGroupUuid != null ? systemGroupUuid.toString() : null;
+    }
+    public UUID getSystemUuid() {
+        return systemUuid != null ? UUID.fromString(systemUuid) : null;
+    }
+    public void setSystemUuid(UUID systemUuid) {
+        this.systemUuid = systemUuid != null ? systemUuid.toString() : null;
+    }
+    public UUID getSubsystemUuid() {
+        return subsystemUuid != null ? UUID.fromString(subsystemUuid) : null;
+    }
+    public void setSubsystemUuid(UUID subsystemUuid) {
+        this.subsystemUuid = subsystemUuid != null ? subsystemUuid.toString() : null;
+    }
+    public UUID getDeviceTypeUuid() {
+        return deviceTypeUuid != null ? UUID.fromString(deviceTypeUuid) : null;
+    }
+    public void setDeviceTypeUuid(UUID deviceTypeUuid) {
+        this.deviceTypeUuid = deviceTypeUuid != null ? deviceTypeUuid.toString() : null;
+    }
+    public String getInstanceIndex() {
+        return instanceIndex;
+    }
+    public void setInstanceIndex(String instanceIndex) {
+        this.instanceIndex = instanceIndex;
+    }
+    public String getConventionName() {
+        return conventionName;
+    }
+    public void setConventionName(String conventionName) {
+        this.conventionName = conventionName;
+    }
+    public String getConventionNameEquivalence() {
+        return conventionNameEquivalence;
+    }
+    public void setConventionNameEquivalence(String conventionNameEquivalence) {
+        this.conventionNameEquivalence = conventionNameEquivalence;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals ((WipName) obj);
+    }
+
+    public boolean equals(WipName other) {
+        if (other == null)
+            return false;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        if (getSystemGroupUuid() == null) {
+            if (other.getSystemGroupUuid() != null)
+                return false;
+        } else if (!getSystemGroupUuid().equals(other.getSystemGroupUuid()))
+            return false;
+        if (getSystemUuid() == null) {
+            if (other.getSystemUuid() != null)
+                return false;
+        } else if (!getSystemUuid().equals(other.getSystemUuid()))
+            return false;
+        if (getSubsystemUuid() == null) {
+            if (other.getSubsystemUuid() != null)
+                return false;
+        } else if (!getSubsystemUuid().equals(other.getSubsystemUuid()))
+            return false;
+        if (getDeviceTypeUuid() == null) {
+            if (other.getDeviceTypeUuid() != null)
+                return false;
+        } else if (!getDeviceTypeUuid().equals(other.getDeviceTypeUuid()))
+            return false;
+        if (getInstanceIndex() == null) {
+            if (other.getInstanceIndex() != null)
+                return false;
+        } else if (!getInstanceIndex().equals(other.getInstanceIndex()))
+            return false;
+        if (getConventionName() == null) {
+            if (other.getConventionName() != null)
+                return false;
+        } else if (!getConventionName().equals(other.getConventionName()))
+            return false;
+        if (getConventionNameEquivalence() == null) {
+            if (other.getConventionNameEquivalence() != null)
+                return false;
+        } else if (!getConventionNameEquivalence().equals(other.getConventionNameEquivalence()))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                            + getId());
+        sb.append(", \"version\": "                     + getVersion());
+        sb.append(", \"uuid\": "                        + getUuid());
+        sb.append(", \"systemgroup_uuid\": "            + getSystemGroupUuid());
+        sb.append(", \"system_uuid\": "                 + getSystemUuid());
+        sb.append(", \"subsystem_uuid\": "              + getSubsystemUuid());
+        sb.append(", \"devicetype_uuid\": "             + getDeviceTypeUuid());
+        sb.append(", \"instance_index\": "              + getInstanceIndex());
+        sb.append(", \"convention_name\": "             + getConventionName());
+        sb.append(", \"convention_name_equivalence\": " + getConventionNameEquivalence());
+        sb.append(", \"description\": "                 + getDescription());
+        sb.append(", \"status\": "                      + getStatus());
+        sb.append(", \"latest\": "                      + isLatest());
+        sb.append(", \"deleted\": "                     + isDeleted());
+        sb.append(", \"requested\": "                   + getRequested());
+        sb.append(", \"requested_by\": "                + getRequestedBy());
+        sb.append(", \"requested_comment\": "           + getRequestedComment());
+        sb.append(", \"processed\": "                   + getProcessed());
+        sb.append(", \"processed_by\": "                + getProcessedBy());
+        sb.append(", \"processed_comment\": "           + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+    public String toStringSimple() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                            + getId());
+        sb.append(", \"uuid\": "                        + getUuid());
+        sb.append(", \"convention_name\": "             + getConventionName());
+        sb.append(", \"status\": "                      + getStatus());
+        sb.append(", \"latest\": "                      + isLatest());
+        sb.append(", \"deleted\": "                     + isDeleted());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/wip/WipNameStructure.java b/src/main/java/org/openepics/names/repository/model/wip/WipNameStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb2e1f0d1184299230a056fd75575978c9c33037
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/wip/WipNameStructure.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2021 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.repository.model.wip;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.MappedSuperclass;
+
+import org.openepics.names.repository.model.Persistable;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * A superclass implementing properties required by JPA. It should be extended by
+ * name and structure classes that need to be persisted to the database.
+ *
+ * @author Lars Johansson
+ */
+@MappedSuperclass
+public class WipNameStructure extends Persistable implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 736094142259082938L;
+
+    public static final String FIELD_UUID              = "uuid";
+    public static final String FIELD_DESCRIPTION       = "description";
+    public static final String FIELD_STATUS            = "status";
+    public static final String FIELD_LATEST            = "latest";
+    public static final String FIELD_DELETED           = "deleted";
+    public static final String FIELD_REQUESTED         = "requested";
+    public static final String FIELD_REQUESTED_BY      = "requestedBy";
+    public static final String FIELD_REQUESTED_COMMENT = "requestedComment";
+    public static final String FIELD_PROCESSED         = "processed";
+    public static final String FIELD_PROCESSED_BY      = "processedBy";
+    public static final String FIELD_PROCESSED_COMMENT = "processedComment";
+
+    public static final String FUNCTION_GET_MNEMONIC_PATH_DEVICE_STRUCTURE = "wip_get_mnemonic_path_device_structure";
+    public static final String FUNCTION_GET_MNEMONIC_PATH_SYSTEM_STRUCTURE = "wip_get_mnemonic_path_system_structure";
+    public static final String FUNCTION_GET_INSTANCE_INDEX                 = "wip_get_instance_index";
+
+    private String uuid;
+    private String description;
+    @Enumerated(EnumType.STRING)
+    private Status status;
+    private Boolean latest;
+    private Boolean deleted;
+    private Date requested;
+    @Column(name = "requested_by")
+    private String requestedBy;
+    @Column(name = "requested_comment")
+    private String requestedComment;
+    private Date processed;
+    @Column(name = "processed_by")
+    private String processedBy;
+    @Column(name = "processed_comment")
+    private String processedComment;
+
+    public UUID getUuid() {
+        return uuid != null ? UUID.fromString(uuid) : null;
+    }
+    public void setUuid(UUID uuid) {
+        this.uuid = uuid != null ? uuid.toString() : null;
+    }
+    public String getDescription() {
+        return description;
+    }
+    public void setDescription(String description) {
+        this.description = description;
+    }
+    public Status getStatus() {
+        return status;
+    }
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+    public Boolean isLatest() {
+        return latest;
+    }
+    public void setLatest(Boolean latest) {
+        this.latest = latest;
+    }
+    public Boolean isDeleted() {
+        return deleted;
+    }
+    public void setDeleted(Boolean deleted) {
+        this.deleted = deleted;
+    }
+    public Date getRequested() {
+        return requested;
+    }
+    public void setRequested(Date requested) {
+        this.requested = requested;
+    }
+    public String getRequestedBy() {
+        return requestedBy;
+    }
+    public void setRequestedBy(String requestedBy) {
+        this.requestedBy = requestedBy;
+    }
+    public String getRequestedComment() {
+        return requestedComment;
+    }
+    public void setRequestedComment(String requestedComment) {
+        this.requestedComment = requestedComment;
+    }
+    public Date getProcessed() {
+        return processed;
+    }
+    public void setProcessed(Date processed) {
+        this.processed = processed;
+    }
+    public String getProcessedBy() {
+        return processedBy;
+    }
+    public void setProcessedBy(String processedBy) {
+        this.processedBy = processedBy;
+    }
+    public String getProcessedComment() {
+        return processedComment;
+    }
+    public void setProcessedComment(String processedComment) {
+        this.processedComment = processedComment;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals((WipNameStructure) obj);
+    }
+
+    public boolean equals(WipNameStructure other) {
+        if (other == null)
+            return false;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        if (getUuid() == null) {
+            if (other.getUuid() != null)
+                return false;
+        } else if (!getUuid().equals(other.getUuid()))
+            return false;
+        if (getDescription() == null) {
+            if (other.getDescription() != null)
+                return false;
+        } else if (!getDescription().equals(other.getDescription()))
+            return false;
+        if (getStatus() == null) {
+            if (other.getStatus() != null)
+                return false;
+        } else if (!getStatus().equals(other.getStatus()))
+            return false;
+        if (isLatest() == null) {
+            if (other.isLatest() != null)
+                return false;
+        } else if (!isLatest().equals(other.isLatest()))
+            return false;
+        if (isDeleted() == null) {
+            if (other.isDeleted() != null)
+                return false;
+        } else if (!isDeleted().equals(other.isDeleted()))
+            return false;
+        if (getRequested() == null) {
+            if (other.getRequested() != null)
+                return false;
+        } else if (!getRequested().equals(other.getRequested()))
+            return false;
+        if (getRequestedBy() == null) {
+            if (other.getRequestedBy() != null)
+                return false;
+        } else if (!getRequestedBy().equals(other.getRequestedBy()))
+            return false;
+        if (getRequestedComment() == null) {
+            if (other.getRequestedComment() != null)
+                return false;
+        } else if (!getRequestedComment().equals(other.getRequestedComment()))
+            return false;
+        if (getProcessed() == null) {
+            if (other.getProcessed() != null)
+                return false;
+        } else if (!getProcessed().equals(other.getProcessed()))
+            return false;
+        if (getProcessedBy() == null) {
+            if (other.getProcessedBy() != null)
+                return false;
+        } else if (!getProcessedBy().equals(other.getProcessedBy()))
+            return false;
+        if (getProcessedComment() == null) {
+            if (other.getProcessedComment() != null)
+                return false;
+        } else if (!getProcessedComment().equals(other.getProcessedComment()))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getUuid());
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/wip/WipStructure.java b/src/main/java/org/openepics/names/repository/model/wip/WipStructure.java
new file mode 100644
index 0000000000000000000000000000000000000000..c62cb5ec7f76e43a48c3de73527d34c6622843a0
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/wip/WipStructure.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2021 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.repository.model.wip;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.MappedSuperclass;
+
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * A superclass implementing properties required by JPA. It should be extended by
+ * System structure and Device structure classes that need to be persisted to the database.
+ *
+ * @author Lars Johansson
+ */
+@MappedSuperclass
+public class WipStructure extends WipNameStructure implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -5980090194197159918L;
+
+    public static final String FIELD_MNEMONIC             = "mnemonic";
+    public static final String FIELD_MNEMONIC_EQUIVALENCE = "mnemonicEquivalence";
+    public static final String FIELD_ORDERING             = "ordering";
+
+    private String mnemonic;
+    @Column(name = "mnemonic_equivalence")
+    private String mnemonicEquivalence;
+    private Integer ordering;
+
+    /**
+     * Constructor for Structure.
+     */
+    public WipStructure() {
+    }
+
+    /**
+     * Constructor for Structure.
+     *
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param ordering ordering
+     * @param description description
+     * @param status status
+     * @param latest latest
+     * @param deleted deleted
+     * @param processed processed
+     * @param processedBy processed by
+     * @param processedComment processed comment
+     */
+    public WipStructure(UUID uuid,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean latest, Boolean deleted,
+            Date processed, String processedBy, String processedComment) {
+        setUuid(uuid);
+        setMnemonic(mnemonic);
+        setMnemonicEquivalence(mnemonicEquivalence);
+        setOrdering(ordering);
+        setDescription(description);
+        setStatus(status);
+        setLatest(latest);
+        setDeleted(deleted);
+        setProcessed(processed);
+        setProcessedBy(processedBy);
+        setProcessedComment(processedComment);
+    }
+
+    public String getMnemonic() {
+        return mnemonic;
+    }
+    public void setMnemonic(String mnemonic) {
+        this.mnemonic = mnemonic;
+    }
+    public String getMnemonicEquivalence() {
+        return mnemonicEquivalence;
+    }
+    public void setMnemonicEquivalence(String mnemonicEquivalence) {
+        this.mnemonicEquivalence = mnemonicEquivalence;
+    }
+    public Integer getOrdering() {
+        return ordering;
+    }
+    public void setOrdering(Integer ordering) {
+        this.ordering = ordering;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals((WipStructure) obj);
+    }
+
+    public boolean equals(WipStructure other) {
+        if (other == null)
+            return false;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        if (getMnemonic() == null) {
+            if (other.getMnemonic() != null)
+                return false;
+        } else if (!getMnemonic().equals(other.getMnemonic()))
+            return false;
+        if (getMnemonicEquivalence() == null) {
+            if (other.getMnemonicEquivalence() != null)
+                return false;
+        } else if (!getMnemonicEquivalence().equals(other.getMnemonicEquivalence()))
+            return false;
+        if (getOrdering() == null) {
+            if (other.getOrdering() != null)
+                return false;
+        } else if (!getOrdering().equals(other.getOrdering()))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                     + getId());
+        sb.append(", \"version\": "              + getVersion());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
+        sb.append(", \"ordering\": "             + getOrdering());
+        sb.append(", \"description\": "          + getDescription());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append(", \"requested\": "            + getRequested());
+        sb.append(", \"requested_by\": "         + getRequestedBy());
+        sb.append(", \"requested_comment\": "    + getRequestedComment());
+        sb.append(", \"processed\": "            + getProcessed());
+        sb.append(", \"processed_by\": "         + getProcessedBy());
+        sb.append(", \"processed_comment\": "    + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+    public String toStringSimple() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                     + getId());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/wip/WipSubsystem.java b/src/main/java/org/openepics/names/repository/model/wip/WipSubsystem.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b058e84f5cd8194cdc1f5661d9c7bbfd89f52da
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/wip/WipSubsystem.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2021 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.repository.model.wip;
+
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * This entity represents a subsystem name part.
+ *
+ * @author Lars Johansson
+ */
+@Entity
+@Table(name = "wip_subsystem")
+public class WipSubsystem extends WipStructure {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 5662135540008222500L;
+
+    public static final String FIELD_PARENT_UUID = "parentUuid";
+
+    public static final String FUNCTION_GET_MNEMONIC_PATH_SUBSYSTEM = "wip_get_mnemonic_path_subsystem";
+
+    @Column(name = "parent_uuid")
+    private String parentUuid;
+
+    /**
+     * Constructor for Subsystem.
+     */
+    public WipSubsystem() {
+    }
+
+    /**
+     * Constructor for Subsystem.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param ordering ordering
+     * @param description description
+     * @param status status
+     * @param latest latest
+     * @param deleted deleted
+     * @param processed processed
+     * @param processedBy processed by
+     * @param processedComment processed comment
+     */
+    public WipSubsystem(UUID uuid, UUID parentUuid,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean latest, Boolean deleted,
+            Date processed, String processedBy, String processedComment) {
+        super(uuid, mnemonic, mnemonicEquivalence, ordering,
+                description, status, latest, deleted,
+                processed, processedBy, processedComment);
+        setParentUuid(parentUuid);
+    }
+
+    public UUID getParentUuid() {
+        return parentUuid != null ? UUID.fromString(parentUuid) : null;
+    }
+    public void setParentUuid(UUID parentUuid) {
+        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals ((WipSubsystem) obj);
+    }
+
+    public boolean equals(WipSubsystem other) {
+        if (other == null)
+            return false;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        if (getParentUuid() == null) {
+            if (other.getParentUuid() != null)
+                return false;
+        } else if (!getParentUuid().equals(other.getParentUuid()))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                     + getId());
+        sb.append(", \"version\": "              + getVersion());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"parent_uuid\": "          + getParentUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
+        sb.append(", \"ordering\": "             + getOrdering());
+        sb.append(", \"description\": "          + getDescription());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append(", \"requested\": "            + getRequested());
+        sb.append(", \"requested_by\": "         + getRequestedBy());
+        sb.append(", \"requested_comment\": "    + getRequestedComment());
+        sb.append(", \"processed\": "            + getProcessed());
+        sb.append(", \"processed_by\": "         + getProcessedBy());
+        sb.append(", \"processed_comment\": "    + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public String toStringSimple() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": " + getId());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/wip/WipSystem.java b/src/main/java/org/openepics/names/repository/model/wip/WipSystem.java
new file mode 100644
index 0000000000000000000000000000000000000000..37ca08af4a349c2fcb48acad60c984ec470eaff6
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/wip/WipSystem.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2021 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.repository.model.wip;
+
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * This entity represents a system name part.
+ *
+ * @author Lars Johansson
+ */
+@Entity
+@Table(name = "wip_system")
+public class WipSystem extends WipStructure {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -4323438470765348486L;
+
+    public static final String FIELD_PARENT_UUID = "parentUuid";
+
+    public static final String FUNCTION_GET_MNEMONIC_PATH_SYSTEM = "wip_get_mnemonic_path_system";
+
+    @Column(name = "parent_uuid")
+    private String parentUuid;
+
+    /**
+     * Constructor for System.
+     */
+    public WipSystem() {
+    }
+
+    /**
+     * Constructor for System.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param ordering ordering
+     * @param description description
+     * @param status status
+     * @param latest latest
+     * @param deleted deleted
+     * @param processed processed
+     * @param processedBy processed by
+     * @param processedComment processed comment
+     */
+    public WipSystem(UUID uuid, UUID parentUuid,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean latest, Boolean deleted,
+            Date processed, String processedBy, String processedComment) {
+        super(uuid, mnemonic, mnemonicEquivalence, ordering,
+                description, status, latest, deleted,
+                processed, processedBy, processedComment);
+        setParentUuid(parentUuid);
+    }
+
+    public UUID getParentUuid() {
+        return parentUuid != null ? UUID.fromString(parentUuid) : null;
+    }
+    public void setParentUuid(UUID parentUuid) {
+        this.parentUuid = parentUuid != null ? parentUuid.toString() : null;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals ((WipSystem) obj);
+    }
+
+    public boolean equals(WipSystem other) {
+        if (other == null)
+            return false;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        if (getParentUuid() == null) {
+            if (other.getParentUuid() != null)
+                return false;
+        } else if (!getParentUuid().equals(other.getParentUuid()))
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                     + getId());
+        sb.append(", \"version\": "              + getVersion());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"parent_uuid\": "          + getParentUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
+        sb.append(", \"ordering\": "             + getOrdering());
+        sb.append(", \"description\": "          + getDescription());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append(", \"requested\": "            + getRequested());
+        sb.append(", \"requested_by\": "         + getRequestedBy());
+        sb.append(", \"requested_comment\": "    + getRequestedComment());
+        sb.append(", \"processed\": "            + getProcessed());
+        sb.append(", \"processed_by\": "         + getProcessedBy());
+        sb.append(", \"processed_comment\": "    + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public String toStringSimple() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": " + getId());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/model/wip/WipSystemGroup.java b/src/main/java/org/openepics/names/repository/model/wip/WipSystemGroup.java
new file mode 100644
index 0000000000000000000000000000000000000000..f6350a1dd5294b1701d0853dea1d2a0ea6686a0d
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/model/wip/WipSystemGroup.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2021 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.repository.model.wip;
+
+import java.util.Date;
+import java.util.Objects;
+import java.util.UUID;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * This entity represents a system group name part.
+ *
+ * @author Lars Johansson
+ */
+@Entity
+@Table(name = "wip_systemgroup")
+public class WipSystemGroup extends WipStructure {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 6298835206366539021L;
+
+    /**
+     * Constructor for SystemGroup.
+     */
+    public WipSystemGroup() {
+    }
+
+    /**
+     * Constructor for SystemGroup.
+     *
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param ordering ordering
+     * @param description description
+     * @param status status
+     * @param latest latest
+     * @param deleted deleted
+     * @param processed processed
+     * @param processedBy processed by
+     * @param processedComment processed comment
+     */
+    public WipSystemGroup(UUID uuid,
+            String mnemonic, String mnemonicEquivalence, Integer ordering, String description,
+            Status status, Boolean latest, Boolean deleted,
+            Date processed, String processedBy, String processedComment) {
+        super(uuid, mnemonic, mnemonicEquivalence, ordering,
+                description, status, latest, deleted,
+                processed, processedBy, processedComment);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        return equals ((WipSystemGroup) obj);
+    }
+
+    public boolean equals(WipSystemGroup other) {
+        if (other == null)
+            return false;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getId(), getUuid());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                     + getId());
+        sb.append(", \"version\": "              + getVersion());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"mnemonic_equivalence\": " + getMnemonicEquivalence());
+        sb.append(", \"ordering\": "             + getOrdering());
+        sb.append(", \"description\": "          + getDescription());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append(", \"requested\": "            + getRequested());
+        sb.append(", \"requested_by\": "         + getRequestedBy());
+        sb.append(", \"requested_comment\": "    + getRequestedComment());
+        sb.append(", \"processed\": "            + getProcessed());
+        sb.append(", \"processed_by\": "         + getProcessedBy());
+        sb.append(", \"processed_comment\": "    + getProcessedComment());
+        sb.append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public String toStringSimple() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append("\"id\": "                     + getId());
+        sb.append(", \"uuid\": "                 + getUuid());
+        sb.append(", \"mnemonic\": "             + getMnemonic());
+        sb.append(", \"status\": "               + getStatus());
+        sb.append(", \"latest\": "               + isLatest());
+        sb.append(", \"deleted\": "              + isDeleted());
+        sb.append("}");
+        return sb.toString();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/IWipDeviceGroupRepository.java b/src/main/java/org/openepics/names/repository/wip/IWipDeviceGroupRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..cff9533def55409fb8a033087a8428e8063d202d
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/IWipDeviceGroupRepository.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.List;
+
+import org.openepics.names.repository.model.wip.WipDeviceGroup;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find device group structure (name part) information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IWipDeviceGroupRepository extends JpaRepository<WipDeviceGroup, Long> {
+
+    // old + verification
+
+    @Query("FROM WipDeviceGroup dg WHERE dg.latest = true AND dg.uuid = ?1")
+    WipDeviceGroup findLatestByUuid(String uuid);
+
+    @Query("FROM WipDeviceGroup dg WHERE dg.uuid = ?1")
+    List<WipDeviceGroup> findByUuid(String uuid);
+
+    // ----------------------------------------------------------------------------------------------------
+
+    @Query("FROM WipDeviceGroup dg WHERE dg.latest = true AND dg.deleted = false AND dg.uuid = ?1")
+    WipDeviceGroup findLatestNotDeletedByUuid(String uuid);
+
+    @Query("FROM WipDeviceGroup dg WHERE dg.latest = true")
+    List<WipDeviceGroup> findLatest();
+
+    @Query("FROM WipDeviceGroup dg WHERE dg.latest = true AND dg.deleted = false")
+    List<WipDeviceGroup> findLatestNotDeleted();
+
+    @Query("FROM WipDeviceGroup dg WHERE dg.latest = true AND dg.deleted = false AND dg.parentUuid = ?1")
+    List<WipDeviceGroup> findLatestNotDeletedByParent(String uuid);
+
+    @Query("FROM WipDeviceGroup dg WHERE dg.uuid = ?1 AND dg.id < ?2 ORDER BY dg.id DESC")
+    List<WipDeviceGroup> findPreviousByUuidAndId(String uuid, Long id);
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/IWipDeviceTypeRepository.java b/src/main/java/org/openepics/names/repository/wip/IWipDeviceTypeRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..265d05be8c0796916b404ea6c7c92e7e6c26914e
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/IWipDeviceTypeRepository.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.List;
+
+import org.openepics.names.repository.model.wip.WipDeviceType;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find device type structure (name part) information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IWipDeviceTypeRepository extends JpaRepository<WipDeviceType, Long> {
+
+    // old + verification
+
+    @Query("FROM WipDeviceType dt WHERE dt.uuid = ?1")
+    List<WipDeviceType> findByUuid(String uuid);
+
+    @Query("FROM WipDeviceType dt WHERE dt.latest = true AND dt.mnemonic = ?1")
+    List<WipDeviceType> findLatestByMnemonic(String mnemonic);
+
+    // ----------------------------------------------------------------------------------------------------
+
+    @Query("FROM WipDeviceType dt WHERE dt.latest = true AND dt.uuid = ?1")
+    WipDeviceType findLatestByUuid(String uuid);
+
+    @Query("FROM WipDeviceType dt WHERE dt.latest = true AND dt.deleted = false AND dt.uuid = ?1")
+    WipDeviceType findLatestNotDeletedByUuid(String uuid);
+
+    @Query("FROM WipDeviceType dt WHERE dt.latest = true")
+    List<WipDeviceType> findLatest();
+
+    @Query("FROM WipDeviceType dt WHERE dt.latest = true AND dt.deleted = false")
+    List<WipDeviceType> findLatestNotDeleted();
+
+    @Query("FROM WipDeviceType dt WHERE dt.latest = true AND dt.deleted = false AND dt.parentUuid = ?1")
+    List<WipDeviceType> findLatestNotDeletedByParent(String uuid);
+
+    @Query("FROM WipDeviceType dt WHERE dt.uuid = ?1 AND dt.id < ?2 ORDER BY dt.id DESC")
+    List<WipDeviceType> findPreviousByUuidAndId(String uuid, Long id);
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/IWipDisciplineRepository.java b/src/main/java/org/openepics/names/repository/wip/IWipDisciplineRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a5826988616b28eb549ebbcbc58bb25351a8e66
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/IWipDisciplineRepository.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.List;
+
+import org.openepics.names.repository.model.wip.WipDiscipline;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find discipline structure (name part) information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IWipDisciplineRepository extends JpaRepository<WipDiscipline, Long> {
+
+    // old + verification
+
+    @Query("FROM WipDiscipline di WHERE di.latest = true AND di.uuid = ?1")
+    WipDiscipline findLatestByUuid(String uuid);
+
+    @Query("FROM WipDiscipline di WHERE di.uuid = ?1")
+    List<WipDiscipline> findByUuid(String uuid);
+
+    @Query("FROM WipDiscipline di WHERE di.latest = true AND di.mnemonic = ?1")
+    List<WipDiscipline> findLatestByMnemonic(String mnemonic);
+
+    // ----------------------------------------------------------------------------------------------------
+
+    @Query("FROM WipDiscipline di WHERE di.latest = true AND di.deleted = false AND di.mnemonic = ?1")
+    WipDiscipline findLatestNotDeletedByMnemonic(String mnemonic);
+
+    @Query("FROM WipDiscipline di WHERE di.latest = true AND di.deleted = false AND di.uuid = ?1")
+    WipDiscipline findLatestNotDeletedByUuid(String uuid);
+
+    @Query("FROM WipDiscipline di WHERE di.latest = true")
+    List<WipDiscipline> findLatest();
+
+    @Query("FROM WipDiscipline di WHERE di.latest = true AND di.deleted = false")
+    List<WipDiscipline> findLatestNotDeleted();
+
+    @Query("FROM WipDiscipline di WHERE di.uuid = ?1 AND di.id < ?2 ORDER BY di.id DESC")
+    List<WipDiscipline> findPreviousByUuidAndId(String uuid, Long id);
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/IWipNameRepository.java b/src/main/java/org/openepics/names/repository/wip/IWipNameRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..472d60492e94f5f85dd2adc5ddc4aa9a794d518b
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/IWipNameRepository.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.Date;
+import java.util.List;
+
+import org.openepics.names.repository.model.wip.WipName;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find name information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IWipNameRepository extends JpaRepository<WipName, Long> {
+
+    // old + verification
+
+    @Query("FROM WipName n WHERE n.latest = true AND n.conventionName = ?1")
+    WipName findLatestByConventionName(String conventionName);
+
+    @Query("FROM WipName n WHERE n.latest = true")
+    List<WipName> findLatest();
+
+    @Query("FROM WipName n WHERE n.latest = true AND n.deleted = false")
+    List<WipName> findLatestNotDeleted();
+
+    @Query("SELECT n FROM WipName n, WipSystemGroup sg "
+            + "WHERE n.latest = true "
+            + "AND sg.uuid = n.systemGroupUuid "
+            + "AND sg.latest = true "
+            + "AND sg.mnemonic = ?1")
+    List<WipName> findLatestBySystemGroupMnemonic(String mnemonic);
+
+    @Query("SELECT n FROM WipName n, WipSystem sys "
+            + "WHERE n.latest = true "
+            + "AND sys.uuid = n.systemUuid "
+            + "AND sys.latest = true "
+            + "AND sys.mnemonic = ?1")
+    List<WipName> findLatestBySystemMnemonic(String mnemonic);
+
+    @Query("SELECT n FROM WipName n, WipSubsystem sub, WipSystem sys "
+            + "WHERE n.latest = true "
+            + "AND sub.uuid = n.subsystemUuid "
+            + "AND sub.latest = true "
+            + "AND sys.uuid = sub.parentUuid  "
+            + "AND sys.latest = true "
+            + "AND sys.mnemonic = ?1")
+    List<WipName> findLatestBySystemMnemonicThroughSubsystem(String mnemonic);
+
+    @Query("SELECT n FROM WipName n, WipSubsystem sub "
+            + "WHERE n.latest = true "
+            + "AND sub.uuid = n.subsystemUuid "
+            + "AND sub.latest = true "
+            + "AND sub.mnemonic = ?1")
+    List<WipName> findLatestBySubsystemMnemonic(String mnemonic);
+
+    @Query("SELECT n FROM WipName n, WipDeviceType dt, WipDeviceGroup dg, WipDiscipline di "
+            + "WHERE n.latest = true "
+            + "AND dt.uuid = n.deviceTypeUuid "
+            + "AND dt.latest = true "
+            + "AND dg.uuid = dt.parentUuid "
+            + "AND dg.latest = true "
+            + "AND di.uuid = dg.parentUuid "
+            + "AND di.latest = true "
+            + "AND di.mnemonic = ?1")
+    List<WipName> findLatestByDisciplineMnemonicThroughDeviceType(String mnemonic);
+
+    @Query("SELECT n FROM WipName n, WipDeviceType dt "
+            + "WHERE n.latest = true "
+            + "AND dt.uuid = n.deviceTypeUuid "
+            + "AND dt.latest = true "
+            + "AND dt.mnemonic = ?1")
+    List<WipName> findLatestByDeviceTypeMnemonic(String mnemonic);
+
+    // ----------------------------------------------------------------------------------------------------
+
+    @Query("FROM WipName n WHERE n.latest = true AND n.uuid = ?1")
+    WipName findLatestByUuid(String uuid);
+
+    @Query("FROM WipName n WHERE n.uuid = ?1")
+    List<WipName> findByUuid(String uuid);
+
+    // ----------------------------------------------------------------------------------------------------
+
+    @Query("SELECT n FROM WipName n, WipSystemGroup sg "
+            + "WHERE n.latest = true "
+            + "AND n.deleted = false "
+            + "AND sg.uuid = n.systemGroupUuid "
+            + "AND sg.latest = true "
+            + "AND sg.uuid = ?1")
+    List<WipName> findLatestNotDeletedBySystemGroupUuid(String uuid);
+
+    @Query("SELECT n FROM WipName n, WipSystem sys "
+            + "WHERE n.latest = true "
+            + "AND n.deleted = false "
+            + "AND sys.uuid = n.systemUuid "
+            + "AND sys.latest = true "
+            + "AND sys.uuid = ?1")
+    List<WipName> findLatestNotDeletedBySystemUuid(String uuid);
+
+    @Query("SELECT n FROM WipName n, WipSubsystem sub, WipSystem sys "
+            + "WHERE n.latest = true "
+            + "AND n.deleted = false "
+            + "AND sub.uuid = n.subsystemUuid "
+            + "AND sub.latest = true "
+            + "AND sys.uuid = sub.parentUuid  "
+            + "AND sys.latest = true "
+            + "AND sys.uuid = ?1")
+    List<WipName> findLatestNotDeletedBySystemUuidThroughSubsystem(String uuid);
+
+    @Query("SELECT n FROM WipName n, WipSubsystem sub "
+            + "WHERE n.latest = true "
+            + "AND n.deleted = false "
+            + "AND sub.uuid = n.subsystemUuid "
+            + "AND sub.latest = true "
+            + "AND sub.uuid = ?1")
+    List<WipName> findLatestNotDeletedBySubsystemUuid(String uuid);
+
+    @Query("SELECT n FROM WipName n, WipDeviceType dt, WipDeviceGroup dg, WipDiscipline di "
+            + "WHERE n.latest = true "
+            + "AND n.deleted = false "
+            + "AND dt.uuid = n.deviceTypeUuid "
+            + "AND dt.latest = true "
+            + "AND dg.uuid = dt.parentUuid "
+            + "AND dg.latest = true "
+            + "AND di.uuid = dg.parentUuid "
+            + "AND di.latest = true "
+            + "AND di.uuid = ?1")
+    List<WipName> findLatestNotDeletedByDisciplineUuidThroughDeviceType(String uuid);
+
+    @Query("SELECT n FROM WipName n, WipDeviceType dt "
+            + "WHERE n.latest = true "
+            + "AND n.deleted = false "
+            + "AND dt.uuid = n.deviceTypeUuid "
+            + "AND dt.latest = true "
+            + "AND dt.uuid = ?1")
+    List<WipName> findLatestNotDeletedByDeviceTypeUuid(String uuid);
+
+    // ----------------------------------------------------------------------------------------------------
+
+    @Query("FROM WipName n WHERE n.requested >= ?1 AND n.requested <= ?2")
+    List<WipName> findByRequestedBetween(Date from, Date to);
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/IWipSubsystemRepository.java b/src/main/java/org/openepics/names/repository/wip/IWipSubsystemRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9658d3e0fa48a026ee413c4159fa031fd7738ba
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/IWipSubsystemRepository.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.List;
+
+import org.openepics.names.repository.model.wip.WipSubsystem;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find subsystem structure (name part)information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IWipSubsystemRepository extends JpaRepository<WipSubsystem, Long> {
+
+    // old + verification
+
+    @Query("FROM WipSubsystem sub WHERE sub.uuid = ?1")
+    List<WipSubsystem> findByUuid(String uuid);
+
+    @Query("FROM WipSubsystem sub WHERE sub.latest = true AND sub.mnemonic = ?1")
+    List<WipSubsystem> findLatestByMnemonic(String mnemonic);
+
+    // ----------------------------------------------------------------------------------------------------
+
+    @Query("FROM WipSubsystem sub WHERE sub.latest = true AND sub.uuid = ?1")
+    WipSubsystem findLatestByUuid(String uuid);
+
+    @Query("FROM WipSubsystem sub WHERE sub.latest = true AND sub.deleted = false AND sub.uuid = ?1")
+    WipSubsystem findLatestNotDeletedByUuid(String uuid);
+
+    @Query("FROM WipSubsystem sub WHERE sub.latest = true")
+    List<WipSubsystem> findLatest();
+
+    @Query("FROM WipSubsystem sub WHERE sub.latest = true AND sub.deleted = false")
+    List<WipSubsystem> findLatestNotDeleted();
+
+    @Query("FROM WipSubsystem sub WHERE sub.latest = true AND sub.deleted = false AND sub.parentUuid = ?1")
+    List<WipSubsystem> findLatestNotDeletedByParent(String uuid);
+
+    @Query("FROM WipSubsystem sub WHERE sub.uuid = ?1 AND sub.id < ?2 ORDER BY sub.id DESC")
+    List<WipSubsystem> findPreviousByUuidAndId(String uuid, Long id);
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/IWipSystemGroupRepository.java b/src/main/java/org/openepics/names/repository/wip/IWipSystemGroupRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..92333e25b17a05a74dd0f66ec04b1b64389c2991
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/IWipSystemGroupRepository.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.List;
+
+import org.openepics.names.repository.model.wip.WipSystemGroup;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find system group structure (name part) information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IWipSystemGroupRepository extends JpaRepository<WipSystemGroup, Long> {
+
+    // old + verification
+
+    @Query("FROM WipSystemGroup sg WHERE sg.uuid = ?1")
+    List<WipSystemGroup> findByUuid(String uuid);
+
+    @Query("FROM WipSystemGroup sg WHERE sg.latest = true AND sg.mnemonic = ?1")
+    List<WipSystemGroup> findLatestByMnemonic(String mnemonic);
+
+    // ----------------------------------------------------------------------------------------------------
+
+    @Query("FROM WipSystemGroup sg WHERE sg.latest = true AND sg.uuid = ?1")
+    WipSystemGroup findLatestByUuid(String uuid);
+
+    @Query("FROM WipSystemGroup sg WHERE sg.latest = true AND sg.deleted = false AND sg.mnemonic = ?1")
+    WipSystemGroup findLatestNotDeletedByMnemonic(String mnemonic);
+
+    @Query("FROM WipSystemGroup sg WHERE sg.latest = true AND sg.deleted = false AND sg.uuid = ?1")
+    WipSystemGroup findLatestNotDeletedByUuid(String uuid);
+
+    @Query("FROM WipSystemGroup sg WHERE sg.latest = true")
+    List<WipSystemGroup> findLatest();
+
+    @Query("FROM WipSystemGroup sg WHERE sg.latest = true AND sg.deleted = false")
+    List<WipSystemGroup> findLatestNotDeleted();
+
+    @Query("FROM WipSystemGroup sg WHERE sg.uuid = ?1 AND sg.id < ?2 ORDER BY sg.id DESC")
+    List<WipSystemGroup> findPreviousByUuidAndId(String uuid, Long id);
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/IWipSystemRepository.java b/src/main/java/org/openepics/names/repository/wip/IWipSystemRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..e67e078c98252298d286ee4d97bd106199797766
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/IWipSystemRepository.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.List;
+
+import org.openepics.names.repository.model.wip.WipSystem;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find system structure (name part) information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IWipSystemRepository extends JpaRepository<WipSystem, Long> {
+
+    // old + verification
+
+    @Query("FROM WipSystem sys WHERE sys.uuid = ?1")
+    List<WipSystem> findByUuid(String uuid);
+
+    @Query("FROM WipSystem sys WHERE sys.latest = true AND sys.mnemonic = ?1")
+    List<WipSystem> findLatestByMnemonic(String mnemonic);
+
+    // ----------------------------------------------------------------------------------------------------
+
+    @Query("FROM WipSystem sys WHERE sys.latest = true AND sys.uuid = ?1")
+    WipSystem findLatestByUuid(String uuid);
+
+    @Query("FROM WipSystem sys WHERE sys.latest = true AND sys.deleted = false AND sys.mnemonic = ?1")
+    WipSystem findLatestNotDeletedByMnemonic(String mnemonic);
+
+    @Query("FROM WipSystem sys WHERE sys.latest = true AND sys.deleted = false AND sys.uuid = ?1")
+    WipSystem findLatestNotDeletedByUuid(String uuid);
+
+    @Query("FROM WipSystem sys WHERE sys.latest = true")
+    List<WipSystem> findLatest();
+
+    @Query("FROM WipSystem sys WHERE sys.latest = true AND sys.deleted = false")
+    List<WipSystem> findLatestNotDeleted();
+
+    @Query("FROM WipSystem sys WHERE sys.latest = true AND sys.deleted = false AND sys.parentUuid = ?1")
+    List<WipSystem> findLatestNotDeletedByParent(String uuid);
+
+    @Query("FROM WipSystem sys WHERE sys.uuid = ?1 AND sys.id < ?2 ORDER BY sys.id DESC")
+    List<WipSystem> findPreviousByUuidAndId(String uuid, Long id);
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/WipDeviceGroupRepository.java b/src/main/java/org/openepics/names/repository/wip/WipDeviceGroupRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..86387228cb46e66c7bf0a00fb4f52694ef808ff3
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/WipDeviceGroupRepository.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Subquery;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.Persistable;
+import org.openepics.names.repository.model.wip.WipDeviceGroup;
+import org.openepics.names.repository.model.wip.WipNameStructure;
+import org.openepics.names.repository.model.wip.WipStructure;
+import org.openepics.names.rest.beans.FieldStructure;
+import org.openepics.names.rest.beans.Status;
+import org.openepics.names.util.RepositoryUtil;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Handle device group information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public class WipDeviceGroupRepository {
+
+    @PersistenceContext
+    private EntityManager em;
+
+    /**
+     * Count device groups.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return count of device groups
+     */
+    public Long countDeviceGroups(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     deleted
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipDeviceGroup> from = cq.from(WipDeviceGroup.class);
+
+        cq.where(cb.and(preparePredicatesDeviceGroups(cb, cq, from, deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find device groups.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return list of device groups
+     */
+    public List<WipDeviceGroup> readDeviceGroups(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        return readDeviceGroups(deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.FALSE, null, null, null, null);
+    }
+
+    /**
+     * Find device groups.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of device groups
+     */
+    public List<WipDeviceGroup> readDeviceGroups(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     deleted
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipDeviceGroup> cq = cb.createQuery(WipDeviceGroup.class);
+        Root<WipDeviceGroup> from = cq.from(WipDeviceGroup.class);
+
+        cq.where(cb.and(preparePredicatesDeviceGroups(cb, cq, from, deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        TypedQuery<WipDeviceGroup> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Prepare predicates for device groups.
+     *
+     * @param cb criteria builder
+     * @param cq criteria query
+     * @param from criteria query root
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesDeviceGroups(CriteriaBuilder cb, CriteriaQuery cq, Root<WipDeviceGroup> from, Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (!Boolean.TRUE.equals(includeHistory)) {
+            // purpose of Naming to show valid entries
+            //     therefore
+            //         exclude some values unless history requested
+            //         make sure to not exclude present and future values (latest approved and pending)
+            //
+            // condition(s)
+            //     exclude content (with latest) before latest
+            //     exclude content (with latest) after  latest (cancelled, rejected)
+            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
+            //         <-->
+            //         select * from structure s
+            //         where (
+            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
+            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
+            //         )
+            //         <-->
+            //                     not (exists (subquery id) and s.id < (subquery id))
+            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (subquery id) and s.id < (subquery 2))
+            //
+            // note
+            //     persistence libraries may optimize query
+            //         e.g. change (!a and !b) to !(a or b)
+
+            Subquery<Long> sub = cq.subquery(Long.class);
+            Root<WipDeviceGroup> fromSub = sub.from(WipDeviceGroup.class);
+            sub.where(cb.and(
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_LATEST), Boolean.TRUE)
+                    ));
+            sub.select(fromSub.get(Persistable.FIELD_ID));
+
+            Subquery<Long> sub2 = cq.subquery(Long.class);
+            Root<WipDeviceGroup> fromSub2 = sub2.from(WipDeviceGroup.class);
+            sub2.where(cb.and(
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_LATEST), Boolean.FALSE)
+                    ));
+            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
+
+            Predicate predicateExclude =
+                    cb.and(
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
+                                    cb.or(
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.CANCELLED),
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.REJECTED)))),
+                            cb.not(cb.and(
+                                    cb.not(cb.exists(sub)),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
+                            );
+            predicates.add(predicateExclude);
+        }
+
+        if (deleted != null) {
+            predicates.add(cb.equal(from.get(WipNameStructure.FIELD_DELETED), deleted));
+        }
+
+        // prepare pattern
+        //     jpa query characters % and _
+        //     remove excess % characters
+
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipNameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+        if (!StringUtils.isEmpty(parentUuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipDeviceGroup.FIELD_PARENT_UUID), RepositoryUtil.preparePattern(parentUuid))));
+        }
+        if (!StringUtils.isEmpty(mnemonic)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
+        }
+        if (!StringUtils.isEmpty(mnemonicEquivalence)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
+        }
+        if (!StringUtils.isEmpty(mnemonicPath)) {
+            predicates.add(cb.and(cb.like(cb.function(WipDeviceGroup.FUNCTION_GET_MNEMONIC_PATH_DEVICEGROUP, String.class, from.get(WipNameStructure.FIELD_UUID)), RepositoryUtil.preparePattern(mnemonicPath))));
+        }
+        if (!StringUtils.isEmpty(description)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
+        }
+        if (!StringUtils.isEmpty(who)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_PROCESSED_BY), RepositoryUtil.preparePattern(who))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Prepare order by query expression.
+     *
+     * @param root root type in the from clause
+     * @param orderBy field on which to order by
+     * @return order by query expression
+     */
+    private Expression<String> orderBy(Root<WipDeviceGroup> root, FieldStructure orderBy) {
+        if (FieldStructure.UUID.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_UUID);
+        } else if (FieldStructure.PARENT.equals(orderBy)) {
+            return root.get(WipDeviceGroup.FIELD_PARENT_UUID);
+        } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.ORDERING.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_ORDERING);
+        } else if (FieldStructure.DESCRIPTION.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_DESCRIPTION);
+        } else if (FieldStructure.WHEN.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_PROCESSED);
+        } else {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        }
+    }
+
+    /**
+     * Count device groups history.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return count of device groups
+     */
+    public Long countDeviceGroupsHistory(
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipDeviceGroup> from = cq.from(WipDeviceGroup.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipDeviceGroup> fromSub = sub.from(WipDeviceGroup.class);
+        sub.where(cb.and(preparePredicatesDeviceGroups(cb, cq, fromSub, null,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find device groups history.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @return list of device groups
+     */
+    public List<WipDeviceGroup> readDeviceGroupsHistory(
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            FieldStructure orderBy, Boolean isAsc) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     outside of method
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipDeviceGroup> cq = cb.createQuery(WipDeviceGroup.class);
+        Root<WipDeviceGroup> from = cq.from(WipDeviceGroup.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipDeviceGroup> fromSub = sub.from(WipDeviceGroup.class);
+        sub.where(cb.and(preparePredicatesDeviceGroups(cb, cq, fromSub, null,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        return em.createQuery(cq).getResultList();
+    }
+
+    /**
+     * Persist device group into persistence context.
+     *
+     * @param deviceGroup device group
+     */
+    public void createDeviceGroup(WipDeviceGroup deviceGroup) {
+        em.persist(deviceGroup);
+    }
+
+    /**
+     * Merge device group into persistence context.
+     *
+     * @param deviceGroup device group
+     */
+    public void updateDeviceGroup(WipDeviceGroup deviceGroup) {
+        em.merge(deviceGroup);
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/WipDeviceTypeRepository.java b/src/main/java/org/openepics/names/repository/wip/WipDeviceTypeRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..32eb4e095b28a50d8951285e2b29e682e41661eb
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/WipDeviceTypeRepository.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Subquery;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.Persistable;
+import org.openepics.names.repository.model.wip.WipDeviceType;
+import org.openepics.names.repository.model.wip.WipNameStructure;
+import org.openepics.names.repository.model.wip.WipStructure;
+import org.openepics.names.rest.beans.FieldStructure;
+import org.openepics.names.rest.beans.Status;
+import org.openepics.names.util.RepositoryUtil;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Handle device type information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public class WipDeviceTypeRepository {
+
+    @PersistenceContext
+    private EntityManager em;
+
+    /**
+     * Count device types.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return count of device types
+     */
+    public Long countDeviceTypes(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     deleted
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipDeviceType> from = cq.from(WipDeviceType.class);
+
+        cq.where(cb.and(preparePredicatesDeviceTypes(cb, cq, from, deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find device types.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return list of device types
+     */
+    public List<WipDeviceType> readDeviceTypes(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        return readDeviceTypes(deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.FALSE, null, null, null, null);
+    }
+
+    /**
+     * Find device types.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of device types
+     */
+    public List<WipDeviceType> readDeviceTypes(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     deleted
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipDeviceType> cq = cb.createQuery(WipDeviceType.class);
+        Root<WipDeviceType> from = cq.from(WipDeviceType.class);
+
+        cq.where(cb.and(preparePredicatesDeviceTypes(cb, cq, from, deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        TypedQuery<WipDeviceType> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Prepare predicates for device types.
+     *
+     * @param cb criteria builder
+     * @param cq criteria query
+     * @param from criteria query root
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesDeviceTypes(CriteriaBuilder cb, CriteriaQuery cq, Root<WipDeviceType> from, Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (!Boolean.TRUE.equals(includeHistory)) {
+            // purpose of Naming to show valid entries
+            //     therefore
+            //         exclude some values unless history requested
+            //         make sure to not exclude present and future values (latest approved and pending)
+            //
+            // condition(s)
+            //     exclude content (with latest) before latest
+            //     exclude content (with latest) after  latest (cancelled, rejected)
+            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
+            //         <-->
+            //         select * from structure s
+            //         where (
+            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
+            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
+            //         )
+            //         <-->
+            //                     not (exists (subquery id) and s.id < (subquery id))
+            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (subquery id) and s.id < (subquery 2))
+            //
+            // note
+            //     persistence libraries may optimize query
+            //         e.g. change (!a and !b) to !(a or b)
+
+            Subquery<Long> sub = cq.subquery(Long.class);
+            Root<WipDeviceType> fromSub = sub.from(WipDeviceType.class);
+            sub.where(cb.and(
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_LATEST), Boolean.TRUE)
+                    ));
+            sub.select(fromSub.get(Persistable.FIELD_ID));
+
+            Subquery<Long> sub2 = cq.subquery(Long.class);
+            Root<WipDeviceType> fromSub2 = sub2.from(WipDeviceType.class);
+            sub2.where(cb.and(
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_LATEST), Boolean.FALSE)
+                    ));
+            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
+
+            Predicate predicateExclude =
+                    cb.and(
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
+                                    cb.or(
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.CANCELLED),
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.REJECTED)))),
+                            cb.not(cb.and(
+                                    cb.not(cb.exists(sub)),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
+                            );
+            predicates.add(predicateExclude);
+        }
+
+        if (deleted != null) {
+            predicates.add(cb.equal(from.get(WipNameStructure.FIELD_DELETED), deleted));
+        }
+
+        // prepare pattern
+        //     jpa query characters % and _
+        //     remove excess % characters
+
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipNameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+        if (!StringUtils.isEmpty(parentUuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipDeviceType.FIELD_PARENT_UUID), RepositoryUtil.preparePattern(parentUuid))));
+        }
+        if (!StringUtils.isEmpty(mnemonic)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
+        }
+        if (!StringUtils.isEmpty(mnemonicEquivalence)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
+        }
+        if (!StringUtils.isEmpty(mnemonicPath)) {
+            predicates.add(cb.and(cb.like(cb.function(WipDeviceType.FUNCTION_GET_MNEMONIC_PATH_DEVICETYPE, String.class, from.get(WipNameStructure.FIELD_UUID)), RepositoryUtil.preparePattern(mnemonicPath))));
+        }
+        if (!StringUtils.isEmpty(description)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
+        }
+        if (!StringUtils.isEmpty(who)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_PROCESSED_BY), RepositoryUtil.preparePattern(who))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Prepare order by query expression.
+     *
+     * @param root root type in the from clause
+     * @param orderBy field on which to order by
+     * @return order by query expression
+     */
+    private Expression<String> orderBy(Root<WipDeviceType> root, FieldStructure orderBy) {
+        if (FieldStructure.UUID.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_UUID);
+        } else if (FieldStructure.PARENT.equals(orderBy)) {
+            return root.get(WipDeviceType.FIELD_PARENT_UUID);
+        } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.ORDERING.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_ORDERING);
+        } else if (FieldStructure.DESCRIPTION.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_DESCRIPTION);
+        } else if (FieldStructure.WHEN.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_PROCESSED);
+        } else {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        }
+    }
+
+    /**
+     * Count device types history.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return count of device types
+     */
+    public Long countDeviceTypesHistory(
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipDeviceType> from = cq.from(WipDeviceType.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipDeviceType> fromSub = sub.from(WipDeviceType.class);
+        sub.where(cb.and(preparePredicatesDeviceTypes(cb, cq, fromSub, null,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find device types history.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @return list of device types
+     */
+    public List<WipDeviceType> readDeviceTypesHistory(
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            FieldStructure orderBy, Boolean isAsc) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     outside of method
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipDeviceType> cq = cb.createQuery(WipDeviceType.class);
+        Root<WipDeviceType> from = cq.from(WipDeviceType.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipDeviceType> fromSub = sub.from(WipDeviceType.class);
+        sub.where(cb.and(preparePredicatesDeviceTypes(cb, cq, fromSub, null,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        return em.createQuery(cq).getResultList();
+    }
+
+    /**
+     * Persist device type into persistence context.
+     *
+     * @param deviceType device type
+     */
+    public void createDeviceType(WipDeviceType deviceType) {
+        em.persist(deviceType);
+    }
+
+    /**
+     * Merge device type into persistence context.
+     *
+     * @param deviceType device type
+     */
+    public void updateDeviceType(WipDeviceType deviceType) {
+        em.merge(deviceType);
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/WipDisciplineRepository.java b/src/main/java/org/openepics/names/repository/wip/WipDisciplineRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..ef92aee255f2c347109a1697786f10292e5b6b76
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/WipDisciplineRepository.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Subquery;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.Persistable;
+import org.openepics.names.repository.model.wip.WipDiscipline;
+import org.openepics.names.repository.model.wip.WipNameStructure;
+import org.openepics.names.repository.model.wip.WipStructure;
+import org.openepics.names.rest.beans.FieldStructure;
+import org.openepics.names.rest.beans.Status;
+import org.openepics.names.util.RepositoryUtil;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Handle discipline information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public class WipDisciplineRepository {
+
+    @PersistenceContext
+    private EntityManager em;
+
+    /**
+     * Count disciplines.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return count of disciplines
+     */
+    public Long countDisciplines(Boolean deleted,
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     deleted
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipDiscipline> from = cq.from(WipDiscipline.class);
+
+        cq.where(cb.and(preparePredicatesDisciplines(cb, cq, from, deleted,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find disciplines.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return list of disciplines
+     */
+    public List<WipDiscipline> readDisciplines(Boolean deleted,
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        return readDisciplines(deleted,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.FALSE, null, null, null, null);
+    }
+
+    /**
+     * Find disciplines.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of disciplines
+     */
+    public List<WipDiscipline> readDisciplines(Boolean deleted,
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     latest, deleted
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipDiscipline> cq = cb.createQuery(WipDiscipline.class);
+        Root<WipDiscipline> from = cq.from(WipDiscipline.class);
+
+        cq.where(cb.and(preparePredicatesDisciplines(cb, cq, from, deleted,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        TypedQuery<WipDiscipline> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Prepare predicates for disciplines.
+     *
+     * @param cb criteria builder
+     * @param cq criteria query
+     * @param from criteria query root
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesDisciplines(CriteriaBuilder cb, CriteriaQuery cq, Root<WipDiscipline> from, Boolean deleted,
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (!Boolean.TRUE.equals(includeHistory)) {
+            // purpose of Naming to show valid entries
+            //     therefore
+            //         exclude some values unless history requested
+            //         make sure to not exclude present and future values (latest approved and pending)
+            //
+            // condition(s)
+            //     exclude content (with latest) before latest
+            //     exclude content (with latest) after  latest (cancelled, rejected)
+            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
+            //         <-->
+            //         select * from structure s
+            //         where (
+            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
+            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
+            //         )
+            //         <-->
+            //                     not (exists (subquery id) and s.id < (subquery id))
+            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (subquery id) and s.id < (subquery 2))
+            //
+            // note
+            //     persistence libraries may optimize query
+            //         e.g. change (!a and !b) to !(a or b)
+
+            Subquery<Long> sub = cq.subquery(Long.class);
+            Root<WipDiscipline> fromSub = sub.from(WipDiscipline.class);
+            sub.where(cb.and(
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_LATEST), Boolean.TRUE)
+                    ));
+            sub.select(fromSub.get(Persistable.FIELD_ID));
+
+            Subquery<Long> sub2 = cq.subquery(Long.class);
+            Root<WipDiscipline> fromSub2 = sub2.from(WipDiscipline.class);
+            sub2.where(cb.and(
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_LATEST), Boolean.FALSE)
+                    ));
+            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
+
+            Predicate predicateExclude =
+                    cb.and(
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
+                                    cb.or(
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.CANCELLED),
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.REJECTED)))),
+                            cb.not(cb.and(
+                                    cb.not(cb.exists(sub)),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
+                            );
+            predicates.add(predicateExclude);
+        }
+
+        if (deleted != null) {
+            predicates.add(cb.equal(from.get(WipNameStructure.FIELD_DELETED), deleted));
+        }
+
+        // prepare pattern
+        //     jpa query characters % and _
+        //     remove excess % characters
+
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipNameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+        if (!StringUtils.isEmpty(mnemonic)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
+        }
+        if (!StringUtils.isEmpty(mnemonicEquivalence)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
+        }
+        if (!StringUtils.isEmpty(mnemonicPath)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonicPath))));
+        }
+        if (!StringUtils.isEmpty(description)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
+        }
+        if (!StringUtils.isEmpty(who)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_PROCESSED_BY), RepositoryUtil.preparePattern(who))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Prepare order by query expression.
+     *
+     * @param root root type in the from clause
+     * @param orderBy field on which to order by
+     * @return order by query expression
+     */
+    private Expression<String> orderBy(Root<WipDiscipline> root, FieldStructure orderBy) {
+        // no parent for discipline
+
+        if (FieldStructure.UUID.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_UUID);
+        } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.ORDERING.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_ORDERING);
+        } else if (FieldStructure.DESCRIPTION.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_DESCRIPTION);
+        } else if (FieldStructure.WHEN.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_PROCESSED);
+        } else {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        }
+    }
+
+    /**
+     * Count disciplines history.
+     *
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return count of disciplines
+     */
+    public Long countDisciplinesHistory(
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        // note
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipDiscipline> from = cq.from(WipDiscipline.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipDiscipline> fromSub = sub.from(WipDiscipline.class);
+        sub.where(cb.and(preparePredicatesDisciplines(cb, cq, fromSub, null,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find disciplines history.
+     *
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @return list of disciplines
+     */
+    public List<WipDiscipline> readDisciplinesHistory(
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            FieldStructure orderBy, Boolean isAsc) {
+
+        // note
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     outside of method
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipDiscipline> cq = cb.createQuery(WipDiscipline.class);
+        Root<WipDiscipline> from = cq.from(WipDiscipline.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipDiscipline> fromSub = sub.from(WipDiscipline.class);
+        sub.where(cb.and(preparePredicatesDisciplines(cb, cq, fromSub, null,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        return em.createQuery(cq).getResultList();
+    }
+
+    /**
+     * Persist discipline into persistence context.
+     *
+     * @param discipline discipline
+     */
+    public void createDiscipline(WipDiscipline discipline) {
+        em.persist(discipline);
+    }
+
+    /**
+     * Merge discipline into persistence context.
+     *
+     * @param discipline discipline
+     */
+    public void updateDiscipline(WipDiscipline discipline) {
+        em.merge(discipline);
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/WipNameRepository.java b/src/main/java/org/openepics/names/repository/wip/WipNameRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..56fbc98c49d8b57ddb9825d9bbefdf939f73b694
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/WipNameRepository.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Subquery;
+
+import org.apache.commons.compress.utils.Lists;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.wip.WipName;
+import org.openepics.names.repository.model.wip.WipNameStructure;
+import org.openepics.names.rest.beans.FieldName;
+import org.openepics.names.util.RepositoryUtil;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Handle name information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public class WipNameRepository {
+
+    /**
+     * Used to decide how to traverse structure references for names.
+     */
+    public enum NameByStructure {
+        NAME_BY_SYSTEMGROUP,
+        NAME_BY_SYSTEMGROUP_THROUGH_SYSTEM,
+        NAME_BY_SYSTEMGROUP_THROUGH_SUBSYSTEM,
+        NAME_BY_SYSTEM,
+        NAME_BY_SYSTEM_THROUGH_SUBSYSTEM,
+        NAME_BY_SUBSYSTEM,
+        NAME_BY_DISCIPLINE_THROUGH_DEVICETYPE,
+        NAME_BY_DEVICEGROUP_THROUGH_DEVICETYPE,
+        NAME_BY_DEVICETYPE;
+    }
+
+    @PersistenceContext
+    private EntityManager em;
+
+    /**
+     * Count names.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic
+     * @param deviceStructure device structure mnemonic
+     * @param index index
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return count of names
+     */
+    public Long countNames(Boolean deleted,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
+            Boolean includeHistory) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     latest, deleted
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipName> from = cq.from(WipName.class);
+
+        cq.where(cb.and(preparePredicatesNames(cb, from, deleted,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find names.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic
+     * @param deviceStructure device structure mnemonic
+     * @param index index
+     * @param description description
+     * @param who who
+     * @return list of names
+     */
+    public List<WipName> readNames(Boolean deleted,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who) {
+
+        return readNames(deleted,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                Boolean.FALSE, null, null, null, null);
+    }
+
+    /**
+     * Find names.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic
+     * @param deviceStructure device structure mnemonic
+     * @param index index
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of names
+     */
+    public List<WipName> readNames(Boolean deleted,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
+            Boolean includeHistory, FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     latest, deleted
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipName> cq = cb.createQuery(WipName.class);
+        Root<WipName> from = cq.from(WipName.class);
+
+        cq.where(cb.and(preparePredicatesNames(cb, from, deleted,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(cb, from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        TypedQuery<WipName> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Prepare predicates for names.
+     *
+     * @param cb criteria builder
+     * @param from criteria query root
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic
+     * @param deviceStructure device structure mnemonic
+     * @param index index
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesNames(CriteriaBuilder cb, Root<WipName> from, Boolean deleted,
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
+            Boolean includeHistory) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (!Boolean.TRUE.equals(includeHistory)) {
+            // purpose of Naming to show valid entries
+            //     therefore
+            //         exclude some values unless history requested
+            //         make sure to not exclude present and future values
+            //
+            // exclude not latest
+            //     select * from Name n where
+            //         not(n.latest = false)
+
+            Predicate predicateNotLatest = cb.equal(from.get(WipNameStructure.FIELD_LATEST), Boolean.FALSE);
+            Predicate predicateExclude   = cb.not(cb.and(predicateNotLatest));
+            predicates.add(predicateExclude);
+        }
+
+        if (deleted != null) {
+            predicates.add(cb.equal(from.get(WipNameStructure.FIELD_DELETED), deleted));
+        }
+
+        // prepare pattern
+        //     jpa query characters % and _
+        //     remove excess % characters
+
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipNameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+        if (!StringUtils.isEmpty(name)) {
+            predicates.add(cb.and(cb.like(from.get(WipName.FIELD_CONVENTION_NAME), RepositoryUtil.preparePattern(name))));
+        }
+        if (!StringUtils.isEmpty(nameEquivalence)) {
+            predicates.add(cb.and(cb.like(from.get(WipName.FIELD_CONVENTION_NAME_EQUIVALENCE), RepositoryUtil.preparePattern(nameEquivalence))));
+        }
+        if (!StringUtils.isEmpty(systemStructure)) {
+            predicates.add(cb.and(cb.like(cb.function(WipNameStructure.FUNCTION_GET_MNEMONIC_PATH_SYSTEM_STRUCTURE, String.class, from.get(WipName.FIELD_CONVENTION_NAME)), RepositoryUtil.preparePattern(systemStructure))));
+        }
+        if (!StringUtils.isEmpty(deviceStructure)) {
+            predicates.add(cb.and(cb.like(cb.function(WipNameStructure.FUNCTION_GET_MNEMONIC_PATH_DEVICE_STRUCTURE, String.class, from.get(WipName.FIELD_CONVENTION_NAME)), RepositoryUtil.preparePattern(deviceStructure))));
+        }
+        if (!StringUtils.isEmpty(index)) {
+            predicates.add(cb.and(cb.like(cb.function(WipNameStructure.FUNCTION_GET_INSTANCE_INDEX, String.class, from.get(WipName.FIELD_CONVENTION_NAME)), RepositoryUtil.preparePattern(index))));
+        }
+        if (!StringUtils.isEmpty(description)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
+        }
+        if (!StringUtils.isEmpty(who)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_REQUESTED_BY), RepositoryUtil.preparePattern(who))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Prepare order by query expression.
+     *
+     * @param cb criteria builder
+     * @param root root type in the from clause
+     * @param orderBy field on which to order by
+     * @return order by query expression
+     */
+    private Expression<String> orderBy(CriteriaBuilder cb, Root<WipName> root, FieldName orderBy) {
+        if (FieldName.UUID.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_UUID);
+        } else if (FieldName.SYSTEMSTRUCTURE.equals(orderBy)) {
+            return cb.function(WipNameStructure.FUNCTION_GET_MNEMONIC_PATH_SYSTEM_STRUCTURE, String.class, root.get(WipName.FIELD_CONVENTION_NAME));
+        } else if (FieldName.DEVICESTRUCTURE.equals(orderBy)) {
+            return cb.function(WipNameStructure.FUNCTION_GET_MNEMONIC_PATH_DEVICE_STRUCTURE, String.class, root.get(WipName.FIELD_CONVENTION_NAME));
+        } else if (FieldName.INDEX.equals(orderBy)) {
+            return cb.function(WipNameStructure.FUNCTION_GET_INSTANCE_INDEX, String.class, root.get(WipName.FIELD_CONVENTION_NAME));
+        } else if (FieldName.DESCRIPTION.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_DESCRIPTION);
+        } else if (FieldName.WHEN.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_REQUESTED);
+        } else {
+            return root.get(WipName.FIELD_CONVENTION_NAME);
+        }
+    }
+
+    /**
+     * Count names history.
+     *
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic
+     * @param deviceStructure device structure mnemonic
+     * @param index index
+     * @param description description
+     * @param who who
+     * @return count of names
+     */
+    public Long countNamesHistory(
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipName> from = cq.from(WipName.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipName> fromSub = sub.from(WipName.class);
+        sub.where(cb.and(preparePredicatesNames(cb, fromSub, null,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find names history.
+     *
+     * @param uuid uuid
+     * @param name name
+     * @param nameEquivalence name equivalence
+     * @param systemStructure system structure mnemonic
+     * @param deviceStructure device structure mnemonic
+     * @param index index
+     * @param description description
+     * @param who who
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of names
+     */
+    public List<WipName> readNamesHistory(
+            String uuid, String name, String nameEquivalence, String systemStructure, String deviceStructure, String index, String description, String who,
+            FieldName orderBy, Boolean isAsc, Integer offset, Integer limit) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipName> cq = cb.createQuery(WipName.class);
+        Root<WipName> from = cq.from(WipName.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipName> fromSub = sub.from(WipName.class);
+        sub.where(cb.and(preparePredicatesNames(cb, fromSub, null,
+                uuid, name, nameEquivalence, systemStructure, deviceStructure, index, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(cb, from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        TypedQuery<WipName> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Find names by structure uuid.
+     *
+     * @param nameByStructure kind of read operation, used to decide how to traverse structure references for names
+     * @param uuid structure uuid
+     * @param deleted deleted
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @return list of names
+     */
+    @SuppressWarnings("unchecked")
+    public List<WipName> readNamesLatestByStructure(NameByStructure nameByStructure, String uuid, Boolean deleted,
+            FieldName orderBy, Boolean isAsc) {
+
+        // must have NameByStructure
+        if (nameByStructure == null || StringUtils.isEmpty(uuid)) {
+            return Lists.newArrayList();
+        }
+
+        StringBuilder sql = new StringBuilder();
+        switch (nameByStructure) {
+        case NAME_BY_SYSTEMGROUP:
+            sql.append("SELECT n FROM WipName n, WipSystemGroup sg "
+                    + "WHERE n.latest = true "
+                    + "AND sg.uuid = n.systemGroupUuid "
+                    + "AND sg.latest = true "
+                    + "AND sg.uuid = :sUuid");
+            break;
+        case NAME_BY_SYSTEMGROUP_THROUGH_SYSTEM:
+            sql.append("SELECT n FROM WipName n, WipSystem sys, WipSystemGroup sg "
+                    + "WHERE n.latest = true "
+                    + "AND sys.uuid = n.systemUuid "
+                    + "AND sys.latest = true "
+                    + "AND sg.uuid = sys.parentUuid  "
+                    + "AND sg.latest = true "
+                    + "AND sg.uuid = :sUuid");
+            break;
+        case NAME_BY_SYSTEMGROUP_THROUGH_SUBSYSTEM:
+            sql.append("SELECT n FROM WipName n, WipSubsystem sub, WipSystem sys, WipSystemGroup sg "
+                    + "WHERE n.latest = true "
+                    + "AND sub.uuid = n.subsystemUuid "
+                    + "AND sub.latest = true "
+                    + "AND sys.uuid = sub.parentUuid  "
+                    + "AND sys.latest = true "
+                    + "AND sg.uuid = sys.parentUuid  "
+                    + "AND sg.latest = true "
+                    + "AND sg.uuid = :sUuid");
+            break;
+        case NAME_BY_SYSTEM:
+            sql.append("SELECT n FROM WipName n, WipSystem sys "
+                    + "WHERE n.latest = true "
+                    + "AND sys.uuid = n.systemUuid "
+                    + "AND sys.latest = true "
+                    + "AND sys.uuid = :sUuid");
+            break;
+        case NAME_BY_SYSTEM_THROUGH_SUBSYSTEM:
+            sql.append("SELECT n FROM WipName n, WipSubsystem sub, WipSystem sys "
+                    + "WHERE n.latest = true "
+                    + "AND sub.uuid = n.subsystemUuid "
+                    + "AND sub.latest = true "
+                    + "AND sys.uuid = sub.parentUuid  "
+                    + "AND sys.latest = true "
+                    + "AND sys.uuid = :sUuid");
+            break;
+        case NAME_BY_SUBSYSTEM:
+            sql.append("SELECT n FROM WipName n, WipSubsystem sub "
+                    + "WHERE n.latest = true "
+                    + "AND sub.uuid = n.subsystemUuid "
+                    + "AND sub.latest = true "
+                    + "AND sub.uuid = :sUuid");
+            break;
+        case NAME_BY_DISCIPLINE_THROUGH_DEVICETYPE:
+            sql.append("SELECT n FROM WipName n, WipDeviceType dt, WipDeviceGroup dg, WipDiscipline di "
+                    + "WHERE n.latest = true "
+                    + "AND dt.uuid = n.deviceTypeUuid "
+                    + "AND dt.latest = true "
+                    + "AND dg.uuid = dt.parentUuid "
+                    + "AND dg.latest = true "
+                    + "AND di.uuid = dg.parentUuid "
+                    + "AND di.latest = true "
+                    + "AND di.uuid = :sUuid");
+            break;
+        case NAME_BY_DEVICEGROUP_THROUGH_DEVICETYPE:
+            sql.append("SELECT n FROM WipName n, WipDeviceType dt, WipDeviceGroup dg "
+                    + "WHERE n.latest = true "
+                    + "AND dt.uuid = n.deviceTypeUuid "
+                    + "AND dt.latest = true "
+                    + "AND dg.uuid = dt.parentUuid "
+                    + "AND dg.latest = true "
+                    + "AND dg.uuid = :sUuid");
+            break;
+        case NAME_BY_DEVICETYPE:
+            sql.append("SELECT n FROM WipName n, WipDeviceType dt "
+                    + "WHERE n.latest = true "
+                    + "AND dt.uuid = n.deviceTypeUuid "
+                    + "AND dt.latest = true "
+                    + "AND dt.uuid = :sUuid");
+            break;
+        default: return Lists.newArrayList();
+        }
+        if (deleted != null) {
+            sql.append(" and n.deleted = :nDeleted");
+        }
+
+        StringBuilder sqlOrderBy = new StringBuilder();
+        if (orderBy != null) {
+            sqlOrderBy.append(" order by ");
+
+            if (FieldName.UUID.equals(orderBy)) {
+                sqlOrderBy.append("n.");
+                sqlOrderBy.append(WipNameStructure.FIELD_UUID);
+            } else if (FieldName.SYSTEMSTRUCTURE.equals(orderBy)) {
+                sqlOrderBy.append(WipNameStructure.FUNCTION_GET_MNEMONIC_PATH_SYSTEM_STRUCTURE);
+                sqlOrderBy.append("(n.conventionName)");
+            } else if (FieldName.DEVICESTRUCTURE.equals(orderBy)) {
+                sqlOrderBy.append(WipNameStructure.FUNCTION_GET_MNEMONIC_PATH_DEVICE_STRUCTURE);
+                sqlOrderBy.append("(n.conventionName)");
+            } else if (FieldName.INDEX.equals(orderBy)) {
+                sqlOrderBy.append(WipNameStructure.FUNCTION_GET_INSTANCE_INDEX);
+                sqlOrderBy.append("(n.conventionName)");
+            } else if (FieldName.DESCRIPTION.equals(orderBy)) {
+                sqlOrderBy.append("n.");
+                sqlOrderBy.append(WipNameStructure.FIELD_DESCRIPTION);
+            } else if (FieldName.WHEN.equals(orderBy)) {
+                sqlOrderBy.append("n.");
+                sqlOrderBy.append(WipNameStructure.FIELD_REQUESTED);
+            } else {
+                sqlOrderBy.append("n.");
+                sqlOrderBy.append(WipName.FIELD_CONVENTION_NAME);
+            }
+
+            if (BooleanUtils.toBoolean(isAsc)) {
+                sqlOrderBy.append(" asc");
+            } else {
+                sqlOrderBy.append(" desc");
+            }
+        }
+        if (orderBy != null) {
+            sql.append(sqlOrderBy.toString());
+        }
+
+        Query query = em.createQuery(sql.toString(), WipName.class).setParameter("sUuid", uuid);
+        if (deleted != null) {
+            query.setParameter("nDeleted", deleted);
+        }
+        return query.getResultList();
+    }
+
+    /**
+     * Persist name into persistence context.
+     *
+     * @param name name
+     */
+    public void createName(WipName name) {
+        em.persist(name);
+    }
+
+    /**
+     * Merge name into persistence context.
+     *
+     * @param name name
+     */
+    public void updateName(WipName name) {
+        em.merge(name);
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/WipSubsystemRepository.java b/src/main/java/org/openepics/names/repository/wip/WipSubsystemRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8f88f9acc41c0217c9e7b2aa09487e397659726
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/WipSubsystemRepository.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Subquery;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.Persistable;
+import org.openepics.names.repository.model.wip.WipNameStructure;
+import org.openepics.names.repository.model.wip.WipStructure;
+import org.openepics.names.repository.model.wip.WipSubsystem;
+import org.openepics.names.rest.beans.FieldStructure;
+import org.openepics.names.rest.beans.Status;
+import org.openepics.names.util.RepositoryUtil;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Handle subsystem information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public class WipSubsystemRepository {
+
+    @PersistenceContext
+    private EntityManager em;
+
+    /**
+     * Count subsystems.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return count of subsystems
+     */
+    public Long countSubsystems(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     deleted
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipSubsystem> from = cq.from(WipSubsystem.class);
+
+        cq.where(cb.and(preparePredicatesSubsystems(cb, cq, from, deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find subsystems.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return list of subsystems
+     */
+    public List<WipSubsystem> readSubsystems(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        return readSubsystems(deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.FALSE, null, null, null, null);
+    }
+
+    /**
+     * Find subsystems.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of subsystems
+     */
+    public List<WipSubsystem> readSubsystems(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     deleted
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipSubsystem> cq = cb.createQuery(WipSubsystem.class);
+        Root<WipSubsystem> from = cq.from(WipSubsystem.class);
+
+        cq.where(cb.and(preparePredicatesSubsystems(cb, cq, from, deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        TypedQuery<WipSubsystem> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Prepare predicates for subsystems.
+     *
+     * @param cb criteria builder
+     * @param cq criteria query
+     * @param from criteria query root
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesSubsystems(CriteriaBuilder cb, CriteriaQuery cq, Root<WipSubsystem> from, Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (!Boolean.TRUE.equals(includeHistory)) {
+            // purpose of Naming to show valid entries
+            //     therefore
+            //         exclude some values unless history requested
+            //         make sure to not exclude present and future values (latest approved and pending)
+            //
+            // condition(s)
+            //     exclude content (with latest) before latest
+            //     exclude content (with latest) after  latest (cancelled, rejected)
+            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
+            //         <-->
+            //         select * from structure s
+            //         where (
+            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
+            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
+            //         )
+            //         <-->
+            //                     not (exists (subquery id) and s.id < (subquery id))
+            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (subquery id) and s.id < (subquery 2))
+            //
+            // note
+            //     persistence libraries may optimize query
+            //         e.g. change (!a and !b) to !(a or b)
+
+            Subquery<Long> sub = cq.subquery(Long.class);
+            Root<WipSubsystem> fromSub = sub.from(WipSubsystem.class);
+            sub.where(cb.and(
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_LATEST), Boolean.TRUE)
+                    ));
+            sub.select(fromSub.get(Persistable.FIELD_ID));
+
+            Subquery<Long> sub2 = cq.subquery(Long.class);
+            Root<WipSubsystem> fromSub2 = sub2.from(WipSubsystem.class);
+            sub2.where(cb.and(
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_LATEST), Boolean.FALSE)
+                    ));
+            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
+
+            Predicate predicateExclude =
+                    cb.and(
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
+                                    cb.or(
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.CANCELLED),
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.REJECTED)))),
+                            cb.not(cb.and(
+                                    cb.not(cb.exists(sub)),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
+                            );
+            predicates.add(predicateExclude);
+        }
+
+        if (deleted != null) {
+            predicates.add(cb.equal(from.get(WipNameStructure.FIELD_DELETED), deleted));
+        }
+
+        // prepare pattern
+        //     jpa query characters % and _
+        //     remove excess % characters
+
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipNameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+        if (!StringUtils.isEmpty(parentUuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipSubsystem.FIELD_PARENT_UUID), RepositoryUtil.preparePattern(parentUuid))));
+        }
+        if (!StringUtils.isEmpty(mnemonic)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
+        }
+        if (!StringUtils.isEmpty(mnemonicEquivalence)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
+        }
+        if (!StringUtils.isEmpty(mnemonicPath)) {
+            predicates.add(cb.and(cb.like(cb.function(WipSubsystem.FUNCTION_GET_MNEMONIC_PATH_SUBSYSTEM, String.class, from.get(WipNameStructure.FIELD_UUID)), RepositoryUtil.preparePattern(mnemonicPath))));
+        }
+        if (!StringUtils.isEmpty(description)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
+        }
+        if (!StringUtils.isEmpty(who)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_PROCESSED_BY), RepositoryUtil.preparePattern(who))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Prepare order by query expression.
+     *
+     * @param root root type in the from clause
+     * @param orderBy field on which to order by
+     * @return order by query expression
+     */
+    private Expression<String> orderBy(Root<WipSubsystem> root, FieldStructure orderBy) {
+        if (FieldStructure.UUID.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_UUID);
+        } else if (FieldStructure.PARENT.equals(orderBy)) {
+            return root.get(WipSubsystem.FIELD_PARENT_UUID);
+        } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.ORDERING.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_ORDERING);
+        } else if (FieldStructure.DESCRIPTION.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_DESCRIPTION);
+        } else if (FieldStructure.WHEN.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_PROCESSED);
+        } else {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        }
+    }
+
+    /**
+     * Count subsystems history.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return count of subsystems
+     */
+    public Long countSubsystemsHistory(
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipSubsystem> from = cq.from(WipSubsystem.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipSubsystem> fromSub = sub.from(WipSubsystem.class);
+        sub.where(cb.and(preparePredicatesSubsystems(cb, cq, fromSub, null,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find subsystems history.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @return list of subsystems
+     */
+    public List<WipSubsystem> readSubsystemsHistory(
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            FieldStructure orderBy, Boolean isAsc) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     outside of method
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipSubsystem> cq = cb.createQuery(WipSubsystem.class);
+        Root<WipSubsystem> from = cq.from(WipSubsystem.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipSubsystem> fromSub = sub.from(WipSubsystem.class);
+        sub.where(cb.and(preparePredicatesSubsystems(cb, cq, fromSub, null,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        return em.createQuery(cq).getResultList();
+    }
+
+    /**
+     * Persist subsystem into persistence context.
+     *
+     * @param subsystem subsystem
+     */
+    public void createSubsystem(WipSubsystem subsystem) {
+        em.persist(subsystem);
+    }
+
+    /**
+     * Merge subsystem into persistence context.
+     *
+     * @param subsystem subsystem
+     */
+    public void updateSubsystem(WipSubsystem subsystem) {
+        em.merge(subsystem);
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/WipSystemGroupRepository.java b/src/main/java/org/openepics/names/repository/wip/WipSystemGroupRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ea665dba46d3a7679796f8c72a25c0c40abc76f
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/WipSystemGroupRepository.java
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Subquery;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.Persistable;
+import org.openepics.names.repository.model.wip.WipNameStructure;
+import org.openepics.names.repository.model.wip.WipStructure;
+import org.openepics.names.repository.model.wip.WipSystemGroup;
+import org.openepics.names.rest.beans.FieldStructure;
+import org.openepics.names.rest.beans.Status;
+import org.openepics.names.util.RepositoryUtil;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Handle system group information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public class WipSystemGroupRepository {
+
+    @PersistenceContext
+    private EntityManager em;
+
+    /**
+     * Count system groups.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return count of system groups
+     */
+    public Long countSystemGroups(Boolean deleted,
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        // where
+        //     deleted
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipSystemGroup> from = cq.from(WipSystemGroup.class);
+
+        cq.where(cb.and(preparePredicatesSystemGroups(cb, cq, from, deleted,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find system groups.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return list of system groups
+     */
+    public List<WipSystemGroup> readSystemGroups(Boolean deleted,
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        return readSystemGroups(deleted,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.FALSE, null, null, null, null);
+    }
+
+    /**
+     * Find system groups.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of system groups
+     */
+    public List<WipSystemGroup> readSystemGroups(Boolean deleted,
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+
+        // where
+        //     deleted
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipSystemGroup> cq = cb.createQuery(WipSystemGroup.class);
+        Root<WipSystemGroup> from = cq.from(WipSystemGroup.class);
+
+        cq.where(cb.and(preparePredicatesSystemGroups(cb, cq, from, deleted,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        TypedQuery<WipSystemGroup> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Prepare predicates for system groups.
+     *
+     * @param cb criteria builder
+     * @param cq criteria query
+     * @param from criteria query root
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesSystemGroups(CriteriaBuilder cb, CriteriaQuery cq, Root<WipSystemGroup> from, Boolean deleted,
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (!Boolean.TRUE.equals(includeHistory)) {
+            // purpose of Naming to show valid entries
+            //     therefore
+            //         exclude obsolete values unless history requested
+            //         make sure to not exclude present and future values (latest approved and pending)
+            //
+            // condition(s)
+            //     exclude content (with latest) before latest
+            //     exclude content (with latest) after  latest (cancelled, rejected)
+            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
+            //         <-->
+            //         select * from structure s
+            //         where (
+            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
+            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
+            //         )
+            //         <-->
+            //                     not (exists (subquery id) and s.id < (subquery id))
+            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (subquery id) and s.id < (subquery 2))
+            //
+            // note
+            //     persistence libraries may optimize query
+            //         e.g. change (!a and !b) to !(a or b)
+
+            Subquery<Long> sub = cq.subquery(Long.class);
+            Root<WipSystemGroup> fromSub = sub.from(WipSystemGroup.class);
+            sub.where(cb.and(
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_LATEST), Boolean.TRUE)
+                    ));
+            sub.select(fromSub.get(Persistable.FIELD_ID));
+
+            Subquery<Long> sub2 = cq.subquery(Long.class);
+            Root<WipSystemGroup> fromSub2 = sub2.from(WipSystemGroup.class);
+            sub2.where(cb.and(
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_LATEST), Boolean.FALSE)
+                    ));
+            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
+
+            Predicate predicateExclude =
+                    cb.and(
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
+                                    cb.or(
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.CANCELLED),
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.REJECTED)))),
+                            cb.not(cb.and(
+                                    cb.not(cb.exists(sub)),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
+                            );
+            predicates.add(predicateExclude);
+        }
+
+        if (deleted != null) {
+            predicates.add(cb.equal(from.get(WipNameStructure.FIELD_DELETED), deleted));
+        }
+
+        // prepare pattern
+        //     jpa query characters % and _
+        //     remove excess % characters
+
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipNameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+        if (!StringUtils.isEmpty(mnemonic)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
+        }
+        if (!StringUtils.isEmpty(mnemonicEquivalence)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
+        }
+        if (!StringUtils.isEmpty(mnemonicPath)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonicPath))));
+        }
+        if (!StringUtils.isEmpty(description)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
+        }
+        if (!StringUtils.isEmpty(who)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_PROCESSED_BY), RepositoryUtil.preparePattern(who))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Prepare order by query expression.
+     *
+     * @param root root type in the from clause
+     * @param orderBy field on which to order by
+     * @return order by query expression
+     */
+    private Expression<String> orderBy(Root<WipSystemGroup> root, FieldStructure orderBy) {
+        // no parent for system group
+
+        if (FieldStructure.UUID.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_UUID);
+        } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.ORDERING.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_ORDERING);
+        } else if (FieldStructure.DESCRIPTION.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_DESCRIPTION);
+        } else if (FieldStructure.WHEN.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_PROCESSED);
+        } else {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        }
+    }
+
+    /**
+     * Count system groups history.
+     *
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return count of system groups
+     */
+    public Long countSystemGroupsHistory(
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        // note
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipSystemGroup> from = cq.from(WipSystemGroup.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipSystemGroup> fromSub = sub.from(WipSystemGroup.class);
+        sub.where(cb.and(preparePredicatesSystemGroups(cb, cq, fromSub, null,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find system groups history.
+     *
+     * @param uuid uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @return list of system groups
+     */
+    public List<WipSystemGroup> readSystemGroupsHistory(
+            String uuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            FieldStructure orderBy, Boolean isAsc) {
+
+        // note
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     outside of method
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipSystemGroup> cq = cb.createQuery(WipSystemGroup.class);
+        Root<WipSystemGroup> from = cq.from(WipSystemGroup.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipSystemGroup> fromSub = sub.from(WipSystemGroup.class);
+        sub.where(cb.and(preparePredicatesSystemGroups(cb, cq, fromSub, null,
+                uuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        return em.createQuery(cq).getResultList();
+    }
+
+    /**
+     * Persist system group into persistence context.
+     *
+     * @param systemGroup system group
+     */
+    public void createSystemGroup(WipSystemGroup systemGroup) {
+        em.persist(systemGroup);
+    }
+
+    /**
+     * Merge system group into persistence context.
+     *
+     * @param systemGroup system group
+     */
+    public void updateSystemGroup(WipSystemGroup systemGroup) {
+        em.merge(systemGroup);
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/wip/WipSystemRepository.java b/src/main/java/org/openepics/names/repository/wip/WipSystemRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..898d4acfa73843207c69e72e525c430aab643f69
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/wip/WipSystemRepository.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2021 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.repository.wip;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+import javax.persistence.criteria.Subquery;
+
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.Persistable;
+import org.openepics.names.repository.model.wip.WipNameStructure;
+import org.openepics.names.repository.model.wip.WipStructure;
+import org.openepics.names.repository.model.wip.WipSystem;
+import org.openepics.names.rest.beans.FieldStructure;
+import org.openepics.names.rest.beans.Status;
+import org.openepics.names.util.RepositoryUtil;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Handle system information in JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public class WipSystemRepository {
+
+    @PersistenceContext
+    private EntityManager em;
+
+    /**
+     * Count systems.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return count of systems
+     */
+    public Long countSystems(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     deleted
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipSystem> from = cq.from(WipSystem.class);
+
+        cq.where(cb.and(preparePredicatesSystems(cb, cq, from, deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find systems.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return list of systems
+     */
+    public List<WipSystem> readSystems(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        return readSystems(deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.FALSE, null, null, null, null);
+    }
+
+    /**
+     * Find systems.
+     *
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @param offset offset
+     * @param limit limit
+     * @return list of systems
+     */
+    public List<WipSystem> readSystems(Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory, FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
+
+        // note
+        //     use of function for mnemonic path
+        // where
+        //     deleted
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     offset, limit
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipSystem> cq = cb.createQuery(WipSystem.class);
+        Root<WipSystem> from = cq.from(WipSystem.class);
+
+        cq.where(cb.and(preparePredicatesSystems(cb, cq, from, deleted,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                includeHistory).toArray(new Predicate[0])));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        TypedQuery<WipSystem> query = em.createQuery(cq);
+        if (offset != null && limit != null) {
+            query.setFirstResult(offset * limit);
+            query.setMaxResults(limit);
+        }
+
+        return query.getResultList();
+    }
+
+    /**
+     * Prepare predicates for systems.
+     *
+     * @param cb criteria builder
+     * @param cq criteria query
+     * @param from criteria query root
+     * @param deleted deleted
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param includeHistory include history
+     * @return list of predicates
+     */
+    private List<Predicate> preparePredicatesSystems(CriteriaBuilder cb, CriteriaQuery cq, Root<WipSystem> from, Boolean deleted,
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            Boolean includeHistory) {
+
+        List<Predicate> predicates = new ArrayList<>();
+
+        if (!Boolean.TRUE.equals(includeHistory)) {
+            // purpose of Naming to show valid entries
+            //     therefore
+            //         exclude some values unless history requested
+            //         make sure to not exclude present and future values (latest approved and pending)
+            //
+            // condition(s)
+            //     exclude content (with latest) before latest
+            //     exclude content (with latest) after  latest (cancelled, rejected)
+            //     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
+            //         <-->
+            //         select * from structure s
+            //         where (
+            //                     not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
+            //                 and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
+            //         )
+            //         <-->
+            //                     not (exists (subquery id) and s.id < (subquery id))
+            //                 and not (exists (subquery id) and s.id > (subquery id) and s.status in ('CANCELLED', 'REJECTED'))
+            //                 and not (not exists (subquery id) and s.id < (subquery 2))
+            //
+            // note
+            //     persistence libraries may optimize query
+            //         e.g. change (!a and !b) to !(a or b)
+
+            Subquery<Long> sub = cq.subquery(Long.class);
+            Root<WipSystem> fromSub = sub.from(WipSystem.class);
+            sub.where(cb.and(
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub.get(WipNameStructure.FIELD_LATEST), Boolean.TRUE)
+                    ));
+            sub.select(fromSub.get(Persistable.FIELD_ID));
+
+            Subquery<Long> sub2 = cq.subquery(Long.class);
+            Root<WipSystem> fromSub2 = sub2.from(WipSystem.class);
+            sub2.where(cb.and(
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_UUID),   from.get(WipNameStructure.FIELD_UUID)),
+                    cb.equal(fromSub2.get(WipNameStructure.FIELD_LATEST), Boolean.FALSE)
+                    ));
+            sub2.select(cb.max(fromSub2.get(Persistable.FIELD_ID)));
+
+            Predicate predicateExclude =
+                    cb.and(
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub))),
+                            cb.not(cb.and(
+                                    cb.exists(sub),
+                                    cb.greaterThan(from.get(Persistable.FIELD_ID).as(Long.class), sub),
+                                    cb.or(
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.CANCELLED),
+                                            cb.equal(from.get(WipNameStructure.FIELD_STATUS), Status.REJECTED)))),
+                            cb.not(cb.and(
+                                    cb.not(cb.exists(sub)),
+                                    cb.lessThan(from.get(Persistable.FIELD_ID).as(Long.class), sub2)))
+                            );
+            predicates.add(predicateExclude);
+        }
+
+        if (deleted != null) {
+            predicates.add(cb.equal(from.get(WipNameStructure.FIELD_DELETED), deleted));
+        }
+
+        // prepare pattern
+        //     jpa query characters % and _
+        //     remove excess % characters
+
+        if (!StringUtils.isEmpty(uuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipNameStructure.FIELD_UUID), RepositoryUtil.preparePattern(uuid))));
+        }
+        if (!StringUtils.isEmpty(parentUuid)) {
+            predicates.add(cb.and(cb.equal(from.get(WipSystem.FIELD_PARENT_UUID), RepositoryUtil.preparePattern(parentUuid))));
+        }
+        if (!StringUtils.isEmpty(mnemonic)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC), RepositoryUtil.preparePattern(mnemonic))));
+        }
+        if (!StringUtils.isEmpty(mnemonicEquivalence)) {
+            predicates.add(cb.and(cb.like(from.get(WipStructure.FIELD_MNEMONIC_EQUIVALENCE), RepositoryUtil.preparePattern(mnemonicEquivalence))));
+        }
+        if (!StringUtils.isEmpty(mnemonicPath)) {
+            predicates.add(cb.and(cb.like(cb.function(WipSystem.FUNCTION_GET_MNEMONIC_PATH_SYSTEM, String.class, from.get(WipNameStructure.FIELD_UUID)), RepositoryUtil.preparePattern(mnemonicPath))));
+        }
+        if (!StringUtils.isEmpty(description)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_DESCRIPTION), RepositoryUtil.preparePattern(description))));
+        }
+        if (!StringUtils.isEmpty(who)) {
+            predicates.add(cb.and(cb.like(from.get(WipNameStructure.FIELD_PROCESSED_BY), RepositoryUtil.preparePattern(who))));
+        }
+
+        return predicates;
+    }
+
+    /**
+     * Prepare order by query expression.
+     *
+     * @param root root type in the from clause
+     * @param orderBy field on which to order by
+     * @return order by query expression
+     */
+    private Expression<String> orderBy(Root<WipSystem> root, FieldStructure orderBy) {
+        if (FieldStructure.UUID.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_UUID);
+        } else if (FieldStructure.PARENT.equals(orderBy)) {
+            return root.get(WipSystem.FIELD_PARENT_UUID);
+        } else if (FieldStructure.MNEMONIC.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.MNEMONICPATH.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        } else if (FieldStructure.ORDERING.equals(orderBy)) {
+            return root.get(WipStructure.FIELD_ORDERING);
+        } else if (FieldStructure.DESCRIPTION.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_DESCRIPTION);
+        } else if (FieldStructure.WHEN.equals(orderBy)) {
+            return root.get(WipNameStructure.FIELD_PROCESSED);
+        } else {
+            return root.get(WipStructure.FIELD_MNEMONIC);
+        }
+    }
+
+    /**
+     * Count systems history.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @return count of systems
+     */
+    public Long countSystemsHistory(
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<Long> cq = cb.createQuery(Long.class);
+        Root<WipSystem> from = cq.from(WipSystem.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipSystem> fromSub = sub.from(WipSystem.class);
+        sub.where(cb.and(preparePredicatesSystems(cb, cq, fromSub, null,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(cb.count(from));
+
+        return em.createQuery(cq).getSingleResult();
+    }
+
+    /**
+     * Find systems history.
+     *
+     * @param uuid uuid
+     * @param parentUuid parent uuid
+     * @param mnemonic mnemonic
+     * @param mnemonicEquivalence mnemonic equivalence
+     * @param mnemonicPath mnemonic path
+     * @param description description
+     * @param who who
+     * @param orderBy order by
+     * @param isAsc is ascending
+     * @return list of systems
+     */
+    public List<WipSystem> readSystemsHistory(
+            String uuid, String parentUuid, String mnemonic, String mnemonicEquivalence, String mnemonicPath, String description, String who,
+            FieldStructure orderBy, Boolean isAsc) {
+
+        // note
+        //     use of function for mnemonic path
+        //     deleted - null
+        //     includeHistory - true
+        // where
+        //     queryFields, queryValues
+        // order
+        //     orderBy, isAsc
+        // paging
+        //     outside of method
+
+        CriteriaBuilder cb = em.getCriteriaBuilder();
+        CriteriaQuery<WipSystem> cq = cb.createQuery(WipSystem.class);
+        Root<WipSystem> from = cq.from(WipSystem.class);
+
+        Subquery<String> sub = cq.subquery(String.class);
+        Root<WipSystem> fromSub = sub.from(WipSystem.class);
+        sub.where(cb.and(preparePredicatesSystems(cb, cq, fromSub, null,
+                uuid, parentUuid, mnemonic, mnemonicEquivalence, mnemonicPath, description, who,
+                Boolean.TRUE).toArray(new Predicate[0])));
+        sub.select(fromSub.get(WipNameStructure.FIELD_UUID));
+
+        cq.where(cb.and(cb.in(from.get(WipNameStructure.FIELD_UUID)).value(sub)));
+        cq.select(from);
+
+        if (orderBy != null) {
+            Expression<String> exp = orderBy(from, orderBy);
+            if (BooleanUtils.toBoolean(isAsc)) {
+                cq.orderBy(cb.asc(exp));
+            } else {
+                cq.orderBy(cb.desc(exp));
+            }
+        }
+
+        return em.createQuery(cq).getResultList();
+    }
+
+    /**
+     * Persist system into persistence context.
+     *
+     * @param system system
+     */
+    public void createSystem(WipSystem system) {
+        em.persist(system);
+    }
+
+    /**
+     * Merge system into persistence context.
+     *
+     * @param system system
+     */
+    public void updateSystem(WipSystem system) {
+        em.merge(system);
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/rest/api/v1/INames.java b/src/main/java/org/openepics/names/rest/api/v1/INames.java
index ddc6d88965de367bff59262b6745a37ef91a1573..e91f96b1ba5592a8a17852bd7ca4249ce89e8018 100644
--- a/src/main/java/org/openepics/names/rest/api/v1/INames.java
+++ b/src/main/java/org/openepics/names/rest/api/v1/INames.java
@@ -79,7 +79,6 @@ public interface INames {
                      deviceStructure          (String)
                      name                     (String)
                      status                   (Status)
-                     latest                   (Boolean)
                      deleted                  (Boolean)
                      when                     (Date)
                      who                      (String)
@@ -112,8 +111,7 @@ public interface INames {
                    user          - create, update, delete
                  ( administrator )
            default for read is to have lifecycle attributes unless query for specific resource or specific use case
-               latest, deleted
-               note - latest handled by history
+               status, deleted
      */
 
     public static final String DEFAULT_PAGE            = "0";
diff --git a/src/main/java/org/openepics/names/rest/api/v1/IStructures.java b/src/main/java/org/openepics/names/rest/api/v1/IStructures.java
index 5a5def29dba5b2b114d0d18674e87176244aa409..8b8f68503e253d19b30af69ddee7147c7ee38392 100644
--- a/src/main/java/org/openepics/names/rest/api/v1/IStructures.java
+++ b/src/main/java/org/openepics/names/rest/api/v1/IStructures.java
@@ -80,7 +80,6 @@ public interface IStructures {
                           mnemonicPath    (String)
                           level           (Integer)
                           status          (Status)
-                          latest          (Boolean)
                           deleted         (Boolean)
                           when            (Date)
                           who             (String)
@@ -112,8 +111,7 @@ public interface IStructures {
                  ( user )
                    administrator - create, update, delete
            default for read is to have lifecycle attributes unless query for specific resource or specific use case
-               latest, deleted
-               note - latest handled by history
+               status, deleted
            mnemonic path for structure includes all levels of mnemonics
      */
 
diff --git a/src/main/java/org/openepics/names/rest/beans/element/NameElement.java b/src/main/java/org/openepics/names/rest/beans/element/NameElement.java
index bfa1e34ecaedf07303bc63ee4ce1d77e3bfd7be2..db1bf3279a82272faeb5fffce3f806a15744c249 100644
--- a/src/main/java/org/openepics/names/rest/beans/element/NameElement.java
+++ b/src/main/java/org/openepics/names/rest/beans/element/NameElement.java
@@ -52,8 +52,6 @@ public class NameElement extends NameElementCommand implements Serializable {
     private String name;
     @Schema(description = "Status of the name entry.")
     private Status status;
-    @Schema(description = "If the name entry is latest (with status APPROVED) in its line of entries.")
-    private Boolean latest;
     @Schema(description = "If the name entry is deleted.")
     private Boolean deleted;
     @Schema(description = "Date and time when the name entry was created.")
@@ -82,7 +80,6 @@ public class NameElement extends NameElementCommand implements Serializable {
      * @param deviceStructure device structure mnemonic path
      * @param name name
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param when when
      * @param who who
@@ -92,14 +89,13 @@ public class NameElement extends NameElementCommand implements Serializable {
             UUID uuid, UUID parentSystemStructure, UUID parentDeviceStructure,
             String index, String description,
             String systemStructure, String deviceStructure, String name,
-            Status status, Boolean latest, Boolean deleted,
+            Status status, Boolean deleted,
             Date when, String who, String comment) {
         super(uuid, parentSystemStructure, parentDeviceStructure, index, description);
         this.systemStructure = systemStructure;
         this.deviceStructure = deviceStructure;
         this.name = name;
         this.status = status;
-        this.latest = latest;
         this.deleted = deleted;
         this.when = when;
         this.who = who;
@@ -130,12 +126,6 @@ public class NameElement extends NameElementCommand implements Serializable {
     public void setStatus(Status status) {
         this.status = status;
     }
-    public Boolean isLatest() {
-        return latest;
-    }
-    public void setLatest(Boolean latest) {
-        this.latest = latest;
-    }
     public Boolean isDeleted() {
         return deleted;
     }
@@ -201,11 +191,6 @@ public class NameElement extends NameElementCommand implements Serializable {
                 return false;
         } else if (!getStatus().equals(other.getStatus()))
             return false;
-        if (isLatest() == null) {
-            if (other.isLatest() != null)
-                return false;
-        } else if (!isLatest().equals(other.isLatest()))
-            return false;
         if (isDeleted() == null) {
             if (other.isDeleted() != null)
                 return false;
@@ -248,7 +233,6 @@ public class NameElement extends NameElementCommand implements Serializable {
         sb.append(", \"description\": "           + getDescription());
         sb.append(", \"name\": "                  + getName());
         sb.append(", \"status\": "                + getStatus());
-        sb.append(", \"latest\": "                + isLatest());
         sb.append(", \"deleted\": "               + isDeleted());
         sb.append(", \"when\": "                  + getWhen());
         sb.append(", \"who\": "                   + getWho());
@@ -263,7 +247,6 @@ public class NameElement extends NameElementCommand implements Serializable {
         sb.append("\"uuid\": "                    + getUuid());
         sb.append(", \"name\": "                  + getName());
         sb.append(", \"status\": "                + getStatus());
-        sb.append(", \"latest\": "                + isLatest());
         sb.append(", \"deleted\": "               + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/rest/beans/element/StructureElement.java b/src/main/java/org/openepics/names/rest/beans/element/StructureElement.java
index f9c512b0e149a15eefbb13298de73c210e61c03d..8a24a8ca45bb8d22cf1c354dd19b62babdfbb61e 100644
--- a/src/main/java/org/openepics/names/rest/beans/element/StructureElement.java
+++ b/src/main/java/org/openepics/names/rest/beans/element/StructureElement.java
@@ -51,8 +51,6 @@ public class StructureElement extends StructureElementCommand implements Seriali
     private Integer level;
     @Schema(description = "Status of the structure entry.")
     private Status status;
-    @Schema(description = "If the structure entry is latest (with status APPROVED) in its line of entries.")
-    private Boolean latest;
     @Schema(description = "If the structure entry is deleted.")
     private Boolean deleted;
     @Schema(description = "Date and time when the structure entry was created.")
@@ -81,7 +79,6 @@ public class StructureElement extends StructureElementCommand implements Seriali
      * @param mnemonicPath mnemonic path
      * @param level level
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param when when
      * @param who who
@@ -91,13 +88,12 @@ public class StructureElement extends StructureElementCommand implements Seriali
             UUID uuid, Type type, UUID parent,
             String mnemonic, Integer ordering, String description,
             String mnemonicPath, Integer level,
-            Status status, Boolean latest, Boolean deleted,
+            Status status, Boolean deleted,
             Date when, String who, String comment) {
         super(uuid, type, parent, mnemonic, ordering, description);
         this.mnemonicPath = mnemonicPath;
         this.level = level;
         this.status = status;
-        this.latest = latest;
         this.deleted = deleted;
         this.when = when;
         this.who = who;
@@ -122,12 +118,6 @@ public class StructureElement extends StructureElementCommand implements Seriali
     public void setStatus(Status status) {
         this.status = status;
     }
-    public Boolean isLatest() {
-        return latest;
-    }
-    public void setLatest(Boolean latest) {
-        this.latest = latest;
-    }
     public Boolean isDeleted() {
         return deleted;
     }
@@ -188,11 +178,6 @@ public class StructureElement extends StructureElementCommand implements Seriali
                 return false;
         } else if (!getStatus().equals(other.getStatus()))
             return false;
-        if (isLatest() == null) {
-            if (other.isLatest() != null)
-                return false;
-        } else if (!isLatest().equals(other.isLatest()))
-            return false;
         if (isDeleted() == null) {
             if (other.isDeleted() != null)
                 return false;
@@ -235,7 +220,6 @@ public class StructureElement extends StructureElementCommand implements Seriali
         sb.append(", \"level\": "        + getLevel());
         sb.append(", \"description\": "  + getDescription());
         sb.append(", \"status\": "       + getStatus());
-        sb.append(", \"latest\": "       + isLatest());
         sb.append(", \"deleted\": "      + isDeleted());
         sb.append(", \"when\": "         + getWhen());
         sb.append(", \"who\": "          + getWho());
@@ -251,7 +235,6 @@ public class StructureElement extends StructureElementCommand implements Seriali
         sb.append(", \"type\": "         + getType());
         sb.append(", \"mnemonic\": "     + getMnemonic());
         sb.append(", \"status\": "       + getStatus());
-        sb.append(", \"latest\": "       + isLatest());
         sb.append(", \"deleted\": "      + isDeleted());
         sb.append("}");
         return sb.toString();
diff --git a/src/main/java/org/openepics/names/rest/controller/ReportController.java b/src/main/java/org/openepics/names/rest/controller/ReportController.java
index c6fdba20730afc2b8c52070eb24ff827c39b8f1a..bd7ca077ac7a484680f603393530a37ba3533419 100644
--- a/src/main/java/org/openepics/names/rest/controller/ReportController.java
+++ b/src/main/java/org/openepics/names/rest/controller/ReportController.java
@@ -25,13 +25,13 @@ import java.util.Map;
 import java.util.UUID;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.DeviceGroupRepository;
-import org.openepics.names.repository.DeviceTypeRepository;
-import org.openepics.names.repository.DisciplineRepository;
-import org.openepics.names.repository.NameRepository;
-import org.openepics.names.repository.SubsystemRepository;
-import org.openepics.names.repository.SystemGroupRepository;
-import org.openepics.names.repository.SystemRepository;
+import org.openepics.names.repository.wip.WipDeviceGroupRepository;
+import org.openepics.names.repository.wip.WipDeviceTypeRepository;
+import org.openepics.names.repository.wip.WipDisciplineRepository;
+import org.openepics.names.repository.wip.WipNameRepository;
+import org.openepics.names.repository.wip.WipSubsystemRepository;
+import org.openepics.names.repository.wip.WipSystemGroupRepository;
+import org.openepics.names.repository.wip.WipSystemRepository;
 import org.openepics.names.rest.beans.Status;
 import org.openepics.names.rest.beans.Type;
 import org.openepics.names.rest.beans.element.NameElement;
@@ -40,9 +40,9 @@ import org.openepics.names.rest.beans.response.ResponsePageNameElements;
 import org.openepics.names.rest.beans.response.ResponsePageStructureElements;
 import org.openepics.names.service.NamesService;
 import org.openepics.names.service.StructuresService;
-import org.openepics.names.util.HolderRepositories;
 import org.openepics.names.util.NamingConventionUtil;
 import org.openepics.names.util.StructureChoice;
+import org.openepics.names.util.wip.HolderWipRepositories;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -87,30 +87,30 @@ public class ReportController {
 
     private NamesService namesService;
     private StructuresService structuresService;
-    private HolderRepositories holderRepositories;
+    private HolderWipRepositories holderWipRepositories;
 
     @Autowired
     public ReportController(
             NamesService namesService,
             StructuresService structuresService,
-            NameRepository nameRepository,
-            SystemGroupRepository systemGroupRepository,
-            SystemRepository systemRepository,
-            SubsystemRepository subsystemRepository,
-            DisciplineRepository disciplineRepository,
-            DeviceGroupRepository deviceGroupRepository,
-            DeviceTypeRepository deviceTypeRepository) {
+            WipNameRepository wipNnameRepository,
+            WipSystemGroupRepository wipSystemGroupRepository,
+            WipSystemRepository wipSystemRepository,
+            WipSubsystemRepository wipSubsystemRepository,
+            WipDisciplineRepository wipDisciplineRepository,
+            WipDeviceGroupRepository wipDeviceGroupRepository,
+            WipDeviceTypeRepository wipDeviceTypeRepository) {
 
         this.namesService = namesService;
         this.structuresService = structuresService;
-        this.holderRepositories = new HolderRepositories(
-                nameRepository,
-                systemGroupRepository,
-                systemRepository,
-                subsystemRepository,
-                disciplineRepository,
-                deviceGroupRepository,
-                deviceTypeRepository);
+        this.holderWipRepositories = new HolderWipRepositories(
+                wipNnameRepository,
+                wipSystemGroupRepository,
+                wipSystemRepository,
+                wipSubsystemRepository,
+                wipDisciplineRepository,
+                wipDeviceGroupRepository,
+                wipDeviceTypeRepository);
     }
 
     /**
@@ -144,10 +144,10 @@ public class ReportController {
     public String reportAbout() {
         // report metrics about Naming
         //     ess names
-        //         read latest, latest deleted, latest not deleted
+        //         read valid, valid deleted, valid not deleted
         //         count for kind of name
         //     system structure, device structure
-        //         read latest per structure
+        //         read valid per structure
         //         count for status
         //
         // note
@@ -163,18 +163,18 @@ public class ReportController {
         // report
 
         // prepare metrics
-        //     read names  - latest, latest deleted, latest not deleted
+        //     read names  - valid, valid deleted, valid not deleted
         //     count names - kind of name
         //     count names - history
         ResponsePageNameElements nameElementsEssNames = namesService.readNames(null, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
         ResponsePageNameElements nameElementsEssNamesDeleted = namesService.readNames(Boolean.TRUE, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
         ResponsePageNameElements nameElementsEssNamesNotDeleted = namesService.readNames(Boolean.FALSE, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null);
-        Long nbrEssNamesHistory = holderRepositories.nameRepository().countNamesHistory(null, null, null, null, null, null, null, null);
+        Long nbrEssNamesHistory = holderWipRepositories.nameRepository().countNamesHistory(null, null, null, null, null, null, null, null);
 
         HolderReportName holderReportName = new HolderReportName(nameElementsEssNamesNotDeleted);
 
         // prepare metrics
-        //     read structures  - latest
+        //     read structures  - valid
         //     count structures - status
         //     count structures - history
         ResponsePageStructureElements structureElementsSystemGroup = structuresService.readStructures(Type.SYSTEMGROUP, null, null, null, null, null, null, null, Boolean.FALSE, null, null, null, null, StructureChoice.STRUCTURE);
@@ -191,12 +191,12 @@ public class ReportController {
         HolderReportStructure holderReportStructureDeviceGroup = new HolderReportStructure(structureElementsDeviceGroup);
         HolderReportStructure holderReportStructureDeviceType = new HolderReportStructure(structureElementsDeviceType);
 
-        Long nbrSystemGroupHistory = holderRepositories.systemGroupRepository().countSystemGroupsHistory(null, null, null, null, null, null);
-        Long nbrSystemHistory = holderRepositories.systemRepository().countSystemsHistory(null, null, null, null, null, null, null);
-        Long nbrSubsystemHistory = holderRepositories.subsystemRepository().countSubsystemsHistory(null, null, null, null, null, null, null);
-        Long nbrDisciplineHistory = holderRepositories.disciplineRepository().countDisciplinesHistory(null, null, null, null, null, null);
-        Long nbrDeviceGroupHistory = holderRepositories.deviceGroupRepository().countDeviceGroupsHistory(null, null, null, null, null, null, null);
-        Long nbrDeviceTypeHistory = holderRepositories.deviceTypeRepository().countDeviceTypesHistory(null, null, null, null, null, null, null);
+        Long nbrSystemGroupHistory = holderWipRepositories.systemGroupRepository().countSystemGroupsHistory(null, null, null, null, null, null);
+        Long nbrSystemHistory = holderWipRepositories.systemRepository().countSystemsHistory(null, null, null, null, null, null, null);
+        Long nbrSubsystemHistory = holderWipRepositories.subsystemRepository().countSubsystemsHistory(null, null, null, null, null, null, null);
+        Long nbrDisciplineHistory = holderWipRepositories.disciplineRepository().countDisciplinesHistory(null, null, null, null, null, null);
+        Long nbrDeviceGroupHistory = holderWipRepositories.deviceGroupRepository().countDeviceGroupsHistory(null, null, null, null, null, null, null);
+        Long nbrDeviceTypeHistory = holderWipRepositories.deviceTypeRepository().countDeviceTypesHistory(null, null, null, null, null, null, null);
 
         // prepare text
         int spaceUntilSizeStructure = 16;
@@ -283,7 +283,7 @@ public class ReportController {
         .append(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date())).append(NEWLINE)
         .append(DIVIDER_128).append(NEWLINE)
         .append("Name and structure data are displayed per line of uuid which is unique identifier through lifecycle of entry.").append(NEWLINE)
-        .append("Note # means number of, active means approved latest not deleted, obsolete values are not shown unless history is requested.").append(NEWLINE)
+        .append("Note # means number of, active means valid not deleted, obsolete values are not shown unless history is requested.").append(NEWLINE)
         .append(DIVIDER_128).append(NEWLINE)
         .append("Metrics for Naming").append(NEWLINE)
         .append("    1) # entries - Overview").append(NEWLINE)
@@ -478,15 +478,12 @@ public class ReportController {
                 addOne(structureElement.getUuid(), mapUuidCount);
 
                 if (Status.APPROVED.equals(structureElement.getStatus())
-                        && Boolean.TRUE.equals(structureElement.isLatest())
                         && Boolean.FALSE.equals(structureElement.isDeleted())) {
                     nbrActive++;
                 } else if (Status.APPROVED.equals(structureElement.getStatus())
-                        && Boolean.TRUE.equals(structureElement.isLatest())
                         && Boolean.TRUE.equals(structureElement.isDeleted())) {
                     nbrDeleted++;
-                } else if (Boolean.TRUE.equals(structureElement.isLatest())
-                        && Boolean.TRUE.equals(structureElement.isDeleted())) {
+                } else if (Boolean.TRUE.equals(structureElement.isDeleted())) {
                     // ref. V5__Data_transformation_status_deleted.sql
                     // migration script to transform data to not rely on status attribute
                     nbrDeleted++;
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 5b2666133638e60c41725dd7e930d720ebef89f4..162b9cca67f13e54349abe1f836ee5f92753fec9 100644
--- a/src/main/java/org/openepics/names/rest/controller/StructuresController.java
+++ b/src/main/java/org/openepics/names/rest/controller/StructuresController.java
@@ -127,7 +127,6 @@ public class StructuresController implements IStructures {
     public ResponseEntity<ResponsePageStructureElements> readStructure(String uuid) {
         // validate
         // read structure
-        // maximum number of elements will be two (PENDING, APPROVED) for given uuid
 
         try {
             // use offset, limit
diff --git a/src/main/java/org/openepics/names/rest/controller/VerificationController.java b/src/main/java/org/openepics/names/rest/controller/VerificationController.java
index 9098baeb992937a10ebff1469ef17b9ab64fa936..f4c4265c6237bf0ed8fb9b7281525c883d927211 100644
--- a/src/main/java/org/openepics/names/rest/controller/VerificationController.java
+++ b/src/main/java/org/openepics/names/rest/controller/VerificationController.java
@@ -41,6 +41,8 @@ import org.openepics.names.old.model.DeviceRevision;
 import org.openepics.names.old.model.NamePartRevision;
 import org.openepics.names.old.model.NamePartRevisionStatus;
 import org.openepics.names.old.nameviews.NameViewProvider;
+import org.openepics.names.repository.IAuditNameRepository;
+import org.openepics.names.repository.IAuditStructureRepository;
 import org.openepics.names.repository.IDeviceGroupRepository;
 import org.openepics.names.repository.IDeviceTypeRepository;
 import org.openepics.names.repository.IDisciplineRepository;
@@ -48,18 +50,37 @@ import org.openepics.names.repository.INameRepository;
 import org.openepics.names.repository.ISubsystemRepository;
 import org.openepics.names.repository.ISystemGroupRepository;
 import org.openepics.names.repository.ISystemRepository;
-import org.openepics.names.repository.model.DeviceGroup;
-import org.openepics.names.repository.model.DeviceType;
-import org.openepics.names.repository.model.Discipline;
-import org.openepics.names.repository.model.Name;
-import org.openepics.names.repository.model.Structure;
-import org.openepics.names.repository.model.Subsystem;
-import org.openepics.names.repository.model.System;
-import org.openepics.names.repository.model.SystemGroup;
+import org.openepics.names.repository.AuditNameRepository;
+import org.openepics.names.repository.AuditStructureRepository;
+import org.openepics.names.repository.DeviceGroupRepository;
+import org.openepics.names.repository.DeviceTypeRepository;
+import org.openepics.names.repository.DisciplineRepository;
+import org.openepics.names.repository.NameRepository;
+import org.openepics.names.repository.SubsystemRepository;
+import org.openepics.names.repository.SystemGroupRepository;
+import org.openepics.names.repository.SystemRepository;
+import org.openepics.names.repository.model.wip.WipDeviceGroup;
+import org.openepics.names.repository.model.wip.WipDeviceType;
+import org.openepics.names.repository.model.wip.WipDiscipline;
+import org.openepics.names.repository.model.wip.WipName;
+import org.openepics.names.repository.model.wip.WipStructure;
+import org.openepics.names.repository.model.wip.WipSubsystem;
+import org.openepics.names.repository.model.wip.WipSystem;
+import org.openepics.names.repository.model.wip.WipSystemGroup;
 import org.openepics.names.repository.old.IDeviceRevisionRepository;
 import org.openepics.names.repository.old.INamePartRevisionRepository;
+import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
+import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
+import org.openepics.names.repository.wip.IWipDisciplineRepository;
+import org.openepics.names.repository.wip.IWipNameRepository;
+import org.openepics.names.repository.wip.IWipSubsystemRepository;
+import org.openepics.names.repository.wip.IWipSystemGroupRepository;
+import org.openepics.names.repository.wip.IWipSystemRepository;
+import org.openepics.names.rest.beans.Type;
 import org.openepics.names.util.HolderIRepositories;
+import org.openepics.names.util.HolderRepositories;
 import org.openepics.names.util.ValidateUtil;
+import org.openepics.names.util.wip.HolderIWipRepositories;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -162,7 +183,9 @@ public class VerificationController {
 
     private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
 
+    private HolderIWipRepositories holderIWipRepositories;
     private HolderIRepositories holderIRepositories;
+    private HolderRepositories holderRepositories;
 
     @Autowired
     IDeviceRevisionRepository deviceRevisionRepository;
@@ -171,22 +194,60 @@ public class VerificationController {
 
     @Autowired
     public VerificationController(
-            INameRepository nameRepository,
-            ISystemGroupRepository systemGroupRepository,
-            ISystemRepository systemRepository,
-            ISubsystemRepository subsystemRepository,
-            IDisciplineRepository disciplineRepository,
-            IDeviceGroupRepository deviceGroupRepository,
-            IDeviceTypeRepository deviceTypeRepository) {
-
-        holderIRepositories = new HolderIRepositories(
+            IWipNameRepository iWipNameRepository,
+            IWipSystemGroupRepository iWipSystemGroupRepository,
+            IWipSystemRepository iWipSystemRepository,
+            IWipSubsystemRepository iWipSubsystemRepository,
+            IWipDisciplineRepository iWipDisciplineRepository,
+            IWipDeviceGroupRepository iWipDeviceGroupRepository,
+            IWipDeviceTypeRepository iWipDeviceTypeRepository,
+            INameRepository iNameRepository,
+            ISystemGroupRepository iSystemGroupRepository,
+            ISystemRepository iSystemRepository,
+            ISubsystemRepository iSubsystemRepository,
+            IDisciplineRepository iDisciplineRepository,
+            IDeviceGroupRepository iDeviceGroupRepository,
+            IDeviceTypeRepository iDeviceTypeRepository,
+            IAuditNameRepository iAuditNameRepository,
+            IAuditStructureRepository iAuditStructureRepository,
+            NameRepository nameRepository,
+            SystemGroupRepository systemGroupRepository,
+            SystemRepository systemRepository,
+            SubsystemRepository subsystemRepository,
+            DisciplineRepository disciplineRepository,
+            DeviceGroupRepository deviceGroupRepository,
+            DeviceTypeRepository deviceTypeRepository,
+            AuditNameRepository auditNameRepository,
+            AuditStructureRepository auditStructureRepository) {
+
+        holderIWipRepositories = new HolderIWipRepositories(
+                iWipNameRepository,
+                iWipSystemGroupRepository,
+                iWipSystemRepository,
+                iWipSubsystemRepository,
+                iWipDisciplineRepository,
+                iWipDeviceGroupRepository,
+                iWipDeviceTypeRepository);
+        this.holderIRepositories = new HolderIRepositories(
+                iNameRepository,
+                iSystemGroupRepository,
+                iSystemRepository,
+                iSubsystemRepository,
+                iDisciplineRepository,
+                iDeviceGroupRepository,
+                iDeviceTypeRepository,
+                iAuditNameRepository,
+                iAuditStructureRepository);
+        this.holderRepositories = new HolderRepositories(
                 nameRepository,
                 systemGroupRepository,
                 systemRepository,
                 subsystemRepository,
                 disciplineRepository,
                 deviceGroupRepository,
-                deviceTypeRepository);
+                deviceTypeRepository,
+                auditNameRepository,
+                auditStructureRepository);
     }
 
     /**
@@ -245,12 +306,12 @@ public class VerificationController {
         // find data
 
         List<NamePartRevision> namePartRevisions = namePartRevisionRepository.findAll();
-        List<SystemGroup>      systemGroups      = holderIRepositories.systemGroupRepository().findAll();
-        List<System>           systems           = holderIRepositories.systemRepository().findAll();
-        List<Subsystem>        subsystems        = holderIRepositories.subsystemRepository().findAll();
-        List<Discipline>       disciplines       = holderIRepositories.disciplineRepository().findAll();
-        List<DeviceGroup>      deviceGroups      = holderIRepositories.deviceGroupRepository().findAll();
-        List<DeviceType>       deviceTypes       = holderIRepositories.deviceTypeRepository().findAll();
+        List<WipSystemGroup>      systemGroups      = holderIWipRepositories.systemGroupRepository().findAll();
+        List<WipSystem>           systems           = holderIWipRepositories.systemRepository().findAll();
+        List<WipSubsystem>        subsystems        = holderIWipRepositories.subsystemRepository().findAll();
+        List<WipDiscipline>       disciplines       = holderIWipRepositories.disciplineRepository().findAll();
+        List<WipDeviceGroup>      deviceGroups      = holderIWipRepositories.deviceGroupRepository().findAll();
+        List<WipDeviceType>       deviceTypes       = holderIWipRepositories.deviceTypeRepository().findAll();
 
         int sumStructures = systemGroups.size()
                 + systems.size()
@@ -262,14 +323,27 @@ public class VerificationController {
         prepareLogReport(report, "Find data");
         prepareLogReport(report, DIVIDER_96);
         prepareLogReport(report, addSpaceUntilSize("# namepartrevision:", SPACE_UNTIL_SIZE_48) + namePartRevisions.size());
-        prepareLogReport(report, addSpaceUntilSize("# systemgroup:", SPACE_UNTIL_SIZE_48) + systemGroups.size());
-        prepareLogReport(report, addSpaceUntilSize("# system:", SPACE_UNTIL_SIZE_48) + systems.size());
-        prepareLogReport(report, addSpaceUntilSize("# subsystem:", SPACE_UNTIL_SIZE_48) + subsystems.size());
-        prepareLogReport(report, addSpaceUntilSize("# discipline:", SPACE_UNTIL_SIZE_48) + disciplines.size());
-        prepareLogReport(report, addSpaceUntilSize("# devicegroup:", SPACE_UNTIL_SIZE_48) + deviceGroups.size());
-        prepareLogReport(report, addSpaceUntilSize("# devicetype:", SPACE_UNTIL_SIZE_48) + deviceTypes.size());
+        prepareLogReport(report, addSpaceUntilSize("# wip systemgroup:", SPACE_UNTIL_SIZE_48) + systemGroups.size());
+        prepareLogReport(report, addSpaceUntilSize("# wip system:", SPACE_UNTIL_SIZE_48) + systems.size());
+        prepareLogReport(report, addSpaceUntilSize("# wip subsystem:", SPACE_UNTIL_SIZE_48) + subsystems.size());
+        prepareLogReport(report, addSpaceUntilSize("# wip discipline:", SPACE_UNTIL_SIZE_48) + disciplines.size());
+        prepareLogReport(report, addSpaceUntilSize("# wip devicegroup:", SPACE_UNTIL_SIZE_48) + deviceGroups.size());
+        prepareLogReport(report, addSpaceUntilSize("# wip devicetype:", SPACE_UNTIL_SIZE_48) + deviceTypes.size());
         prepareLogReport(report, addSpaceUntilSize("# sum:", SPACE_UNTIL_SIZE_48) + sumStructures);
         prepareLogReport(report, DIVIDER_96);
+        prepareLogReport(report, addSpaceUntilSize("# systemgroup:", SPACE_UNTIL_SIZE_48) + holderIRepositories.systemGroupRepository().findAll().size());
+        prepareLogReport(report, addSpaceUntilSize("# system:", SPACE_UNTIL_SIZE_48) + holderIRepositories.systemRepository().findAll().size());
+        prepareLogReport(report, addSpaceUntilSize("# subsystem:", SPACE_UNTIL_SIZE_48) + holderIRepositories.subsystemRepository().findAll().size());
+        prepareLogReport(report, addSpaceUntilSize("# discipline:", SPACE_UNTIL_SIZE_48) + holderIRepositories.disciplineRepository().findAll().size());
+        prepareLogReport(report, addSpaceUntilSize("# devicegroup:", SPACE_UNTIL_SIZE_48) + holderIRepositories.deviceGroupRepository().findAll().size());
+        prepareLogReport(report, addSpaceUntilSize("# devicetype:", SPACE_UNTIL_SIZE_48) + holderIRepositories.deviceTypeRepository().findAll().size());
+        prepareLogReport(report, addSpaceUntilSize("# audit systemgroup:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.SYSTEMGROUP, null));
+        prepareLogReport(report, addSpaceUntilSize("# audit system:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.SYSTEM, null));
+        prepareLogReport(report, addSpaceUntilSize("# audit subsystem:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.SUBSYSTEM, null));
+        prepareLogReport(report, addSpaceUntilSize("# audit discipline:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.DISCIPLINE, null));
+        prepareLogReport(report, addSpaceUntilSize("# audit devicegroup:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.DEVICEGROUP, null));
+        prepareLogReport(report, addSpaceUntilSize("# audit devicetype:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditStructureRepository().countAuditStructures(Type.DEVICETYPE, null));
+        prepareLogReport(report, DIVIDER_96);
 
         // utility
         //     interpret lists into hashmaps for faster retrieval in for loop below
@@ -288,7 +362,7 @@ public class VerificationController {
             mapIdNamePartRevision.put(namePartRevision.getId(), namePartRevision);
         }
         HashMap<UUID, Long> mapUuidMaxIdSystemGroup = new HashMap<>();
-        for (SystemGroup systemGroup : systemGroups) {
+        for (WipSystemGroup systemGroup : systemGroups) {
             if (		(mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()) == null
                         ||  systemGroup.getId() > mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()))
                     && NamePartRevisionStatus.APPROVED.name().equals(systemGroup.getStatus().name())) {
@@ -296,7 +370,7 @@ public class VerificationController {
             }
         }
         HashMap<UUID, Long> mapUuidMaxIdSystem = new HashMap<>();
-        for (System system : systems) {
+        for (WipSystem system : systems) {
             if ((		mapUuidMaxIdSystem.get(system.getUuid()) == null
                         ||  system.getId() > mapUuidMaxIdSystem.get(system.getUuid()))
                     && NamePartRevisionStatus.APPROVED.name().equals(system.getStatus().name())) {
@@ -304,7 +378,7 @@ public class VerificationController {
             }
         }
         HashMap<UUID, Long> mapUuidMaxIdSubsystem = new HashMap<>();
-        for (Subsystem subsystem : subsystems) {
+        for (WipSubsystem subsystem : subsystems) {
             if (		(mapUuidMaxIdSubsystem.get(subsystem.getUuid()) == null
                         ||  subsystem.getId() > mapUuidMaxIdSubsystem.get(subsystem.getUuid()))
                     && NamePartRevisionStatus.APPROVED.name().equals(subsystem.getStatus().name())) {
@@ -312,7 +386,7 @@ public class VerificationController {
             }
         }
         HashMap<UUID, Long> mapUuidMaxIdDiscipline = new HashMap<>();
-        for (Discipline discipline : disciplines) {
+        for (WipDiscipline discipline : disciplines) {
             if ((mapUuidMaxIdDiscipline.get(discipline.getUuid()) == null
                     ||  discipline.getId() > mapUuidMaxIdDiscipline.get(discipline.getUuid()))
                     && NamePartRevisionStatus.APPROVED.name().equals(discipline.getStatus().name())) {
@@ -320,7 +394,7 @@ public class VerificationController {
             }
         }
         HashMap<UUID, Long> mapUuidMaxIdDeviceGroup = new HashMap<>();
-        for (DeviceGroup deviceGroup : deviceGroups) {
+        for (WipDeviceGroup deviceGroup : deviceGroups) {
             if ((mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()) == null
                     ||  deviceGroup.getId() > mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()))
                     && NamePartRevisionStatus.APPROVED.name().equals(deviceGroup.getStatus().name())) {
@@ -328,7 +402,7 @@ public class VerificationController {
             }
         }
         HashMap<UUID, Long> mapUuidMaxIdDeviceType = new HashMap<>();
-        for (DeviceType deviceType : deviceTypes) {
+        for (WipDeviceType deviceType : deviceTypes) {
             if ((mapUuidMaxIdDeviceType.get(deviceType.getUuid()) == null
                     ||  deviceType.getId() > mapUuidMaxIdDeviceType.get(deviceType.getUuid()))
                     && NamePartRevisionStatus.APPROVED.name().equals(deviceType.getStatus().name())) {
@@ -362,7 +436,7 @@ public class VerificationController {
         //     each attribute as expected
         boolean check = false;
         NamePartRevision namePartRevision = null;
-        for (SystemGroup systemGroup : systemGroups) {
+        for (WipSystemGroup systemGroup : systemGroups) {
             namePartRevision = mapIdNamePartRevision.get(systemGroup.getId());
 
             // no check for parent uuid
@@ -381,7 +455,7 @@ public class VerificationController {
         // system
         // check entry by entry
         //     each attribute as expected
-        for (System system : systems) {
+        for (WipSystem system : systems) {
             namePartRevision = mapIdNamePartRevision.get(system.getId());
 
             check = namePartRevision != null
@@ -400,7 +474,7 @@ public class VerificationController {
         // subsystem
         // check entry by entry
         //     each attribute as expected
-        for (Subsystem subsystem : subsystems) {
+        for (WipSubsystem subsystem : subsystems) {
             namePartRevision = mapIdNamePartRevision.get(subsystem.getId());
 
             check = namePartRevision != null
@@ -419,7 +493,7 @@ public class VerificationController {
         // discipline
         // check entry by entry
         //     each attribute as expected
-        for (Discipline discipline : disciplines) {
+        for (WipDiscipline discipline : disciplines) {
             namePartRevision = mapIdNamePartRevision.get(discipline.getId());
 
             // no check for parent uuid
@@ -438,7 +512,7 @@ public class VerificationController {
         // device group
         // check entry by entry
         //     each attribute as expected
-        for (DeviceGroup deviceGroup : deviceGroups) {
+        for (WipDeviceGroup deviceGroup : deviceGroups) {
             namePartRevision = mapIdNamePartRevision.get(deviceGroup.getId());
 
             check = namePartRevision != null
@@ -457,7 +531,7 @@ public class VerificationController {
         // device type
         // check entry by entry
         //     each attribute as expected
-        for (DeviceType deviceType : deviceTypes) {
+        for (WipDeviceType deviceType : deviceTypes) {
             namePartRevision = mapIdNamePartRevision.get(deviceType.getId());
 
             check = namePartRevision != null
@@ -549,13 +623,16 @@ public class VerificationController {
 
         List<NamePartRevision> namePartRevisions = namePartRevisionRepository.findAll();
         List<DeviceRevision>   deviceRevisions   = deviceRevisionRepository.findAll();
-        List<Name>             names             = holderIRepositories.nameRepository().findAll();
+        List<WipName>          names             = holderIWipRepositories.nameRepository().findAll();
 
         prepareLogReport(report, "Find data");
         prepareLogReport(report, DIVIDER_96);
         prepareLogReport(report, addSpaceUntilSize("# namepartrevision:", SPACE_UNTIL_SIZE_48) + namePartRevisions.size());
         prepareLogReport(report, addSpaceUntilSize("# devicerevision:", SPACE_UNTIL_SIZE_48) + deviceRevisions.size());
-        prepareLogReport(report, addSpaceUntilSize("# name:", SPACE_UNTIL_SIZE_48) + names.size());
+        prepareLogReport(report, addSpaceUntilSize("# wip name:", SPACE_UNTIL_SIZE_48) + names.size());
+        prepareLogReport(report, DIVIDER_96);
+        prepareLogReport(report, addSpaceUntilSize("# name:", SPACE_UNTIL_SIZE_48) + holderIRepositories.nameRepository().findAll().size());
+        prepareLogReport(report, addSpaceUntilSize("# audit name:", SPACE_UNTIL_SIZE_48) + holderRepositories.auditNameRepository().countAuditNames(null));
         prepareLogReport(report, DIVIDER_96);
 
         // utility
@@ -575,7 +652,7 @@ public class VerificationController {
             mapIdDeviceRevision.put(deviceRevision.getId(), deviceRevision);
         }
         HashMap<UUID, Long> mapUuidMaxIdName = new HashMap<>();
-        for (Name name : names) {
+        for (WipName name : names) {
             if (mapUuidMaxIdName.get(name.getUuid()) == null
                     ||  name.getId() > mapUuidMaxIdName.get(name.getUuid())) {
                 mapUuidMaxIdName.put(name.getUuid(), name.getId());
@@ -605,7 +682,7 @@ public class VerificationController {
         boolean check = false;
         DeviceRevision deviceRevision = null;
         try {
-        for (Name name : names) {
+        for (WipName name : names) {
             deviceRevision = mapIdDeviceRevision.get(name.getId());
 
             check = deviceRevision != null
@@ -677,13 +754,13 @@ public class VerificationController {
         prepareLogReport(report, "           number of entries (structure) is same as number of entries found by id");
         prepareLogReport(report, DIVIDER_128);
 
-        List<Name>             names             = holderIRepositories.nameRepository().findAll();
-        List<SystemGroup>      systemGroups      = holderIRepositories.systemGroupRepository().findAll();
-        List<System>           systems           = holderIRepositories.systemRepository().findAll();
-        List<Subsystem>        subsystems        = holderIRepositories.subsystemRepository().findAll();
-        List<Discipline>       disciplines       = holderIRepositories.disciplineRepository().findAll();
-        List<DeviceGroup>      deviceGroups      = holderIRepositories.deviceGroupRepository().findAll();
-        List<DeviceType>       deviceTypes       = holderIRepositories.deviceTypeRepository().findAll();
+        List<WipName>             names             = holderIWipRepositories.nameRepository().findAll();
+        List<WipSystemGroup>      systemGroups      = holderIWipRepositories.systemGroupRepository().findAll();
+        List<WipSystem>           systems           = holderIWipRepositories.systemRepository().findAll();
+        List<WipSubsystem>        subsystems        = holderIWipRepositories.subsystemRepository().findAll();
+        List<WipDiscipline>       disciplines       = holderIWipRepositories.disciplineRepository().findAll();
+        List<WipDeviceGroup>      deviceGroups      = holderIWipRepositories.deviceGroupRepository().findAll();
+        List<WipDeviceType>       deviceTypes       = holderIWipRepositories.deviceTypeRepository().findAll();
 
         prepareLogReport(report, "Find data");
         prepareLogReport(report, DIVIDER_96);
@@ -704,13 +781,13 @@ public class VerificationController {
         HashSet<Long> foundbyIdDeviceGroup = new HashSet<>();
         HashSet<Long> foundbyIdDeviceType  = new HashSet<>();
 
-        List<Name>             namesByUuid             = null;
-        List<SystemGroup>      systemGroupsByUuid      = null;
-        List<System>           systemsByUuid           = null;
-        List<Subsystem>        subsystemsByUuid        = null;
-        List<Discipline>       disciplinesByUuid       = null;
-        List<DeviceGroup>      deviceGroupsByUuid      = null;
-        List<DeviceType>       deviceTypesByUuid       = null;
+        List<WipName>             namesByUuid             = null;
+        List<WipSystemGroup>      systemGroupsByUuid      = null;
+        List<WipSystem>           systemsByUuid           = null;
+        List<WipSubsystem>        subsystemsByUuid        = null;
+        List<WipDiscipline>       disciplinesByUuid       = null;
+        List<WipDeviceGroup>      deviceGroupsByUuid      = null;
+        List<WipDeviceType>       deviceTypesByUuid       = null;
 
         prepareLogReport(report, addSpaceUntilSize("Check", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize("# found by id", SPACE_UNTIL_SIZE_32));
         prepareLogReport(report, DIVIDER_96);
@@ -722,64 +799,64 @@ public class VerificationController {
         //     ok if set(s) size same as list(s) size
         //     any entry not in set or once in set
 
-        for (Name name : names) {
+        for (WipName name : names) {
             // to mimic - Find history for name by uuid
-            namesByUuid = holderIRepositories.nameRepository().findByUuid(name.getUuid().toString());
-            for (Name nameByUuid : namesByUuid) {
+            namesByUuid = holderIWipRepositories.nameRepository().findByUuid(name.getUuid().toString());
+            for (WipName nameByUuid : namesByUuid) {
                 foundbyIdName.add(nameByUuid.getId());
             }
         }
         prepareLogReport(report, addSpaceUntilSize("after name", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdName.size(), SPACE_UNTIL_SIZE_32));
 
-        for (SystemGroup systemGroup : systemGroups) {
+        for (WipSystemGroup systemGroup : systemGroups) {
             // to mimic - Find history for system group by uuid
-            systemGroupsByUuid = holderIRepositories.systemGroupRepository().findByUuid(systemGroup.getUuid().toString());
-            for (SystemGroup systemGroupByUuid : systemGroupsByUuid) {
+            systemGroupsByUuid = holderIWipRepositories.systemGroupRepository().findByUuid(systemGroup.getUuid().toString());
+            for (WipSystemGroup systemGroupByUuid : systemGroupsByUuid) {
                 foundbyIdSystemGroup.add(systemGroupByUuid.getId());
             }
         }
         prepareLogReport(report, addSpaceUntilSize("after systemgroup", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdSystemGroup.size(), SPACE_UNTIL_SIZE_32));
 
-        for (System system : systems) {
+        for (WipSystem system : systems) {
             // to mimic - Find history for system by uuid
-            systemsByUuid = holderIRepositories.systemRepository().findByUuid(system.getUuid().toString());
-            for (System systemByUuid : systemsByUuid) {
+            systemsByUuid = holderIWipRepositories.systemRepository().findByUuid(system.getUuid().toString());
+            for (WipSystem systemByUuid : systemsByUuid) {
                 foundbyIdSystem.add(systemByUuid.getId());
             }
         }
         prepareLogReport(report, addSpaceUntilSize("after system", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdSystem.size(), SPACE_UNTIL_SIZE_32));
 
-        for (Subsystem subsystem : subsystems) {
+        for (WipSubsystem subsystem : subsystems) {
             // to mimic - Find history for subsystem by uuid
-            subsystemsByUuid = holderIRepositories.subsystemRepository().findByUuid(subsystem.getUuid().toString());
-            for (Subsystem subsystemByUuid : subsystemsByUuid) {
+            subsystemsByUuid = holderIWipRepositories.subsystemRepository().findByUuid(subsystem.getUuid().toString());
+            for (WipSubsystem subsystemByUuid : subsystemsByUuid) {
                 foundbyIdSubsystem.add(subsystemByUuid.getId());
             }
         }
         prepareLogReport(report, addSpaceUntilSize("after subsystem", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdSubsystem.size(), SPACE_UNTIL_SIZE_32));
 
-        for (Discipline discipline : disciplines) {
+        for (WipDiscipline discipline : disciplines) {
             // to mimic - Find history for discipline by uuid
-            disciplinesByUuid = holderIRepositories.disciplineRepository().findByUuid(discipline.getUuid().toString());
-            for (Discipline disciplineByUuid : disciplinesByUuid) {
+            disciplinesByUuid = holderIWipRepositories.disciplineRepository().findByUuid(discipline.getUuid().toString());
+            for (WipDiscipline disciplineByUuid : disciplinesByUuid) {
                 foundbyIdDiscipline.add(disciplineByUuid.getId());
             }
         }
         prepareLogReport(report, addSpaceUntilSize("after discipline", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdDiscipline.size(), SPACE_UNTIL_SIZE_32));
 
-        for (DeviceGroup deviceGroup : deviceGroups) {
+        for (WipDeviceGroup deviceGroup : deviceGroups) {
             // to mimic - Find history for device group by uuid
-            deviceGroupsByUuid = holderIRepositories.deviceGroupRepository().findByUuid(deviceGroup.getUuid().toString());
-            for (DeviceGroup deviceGroupByUuid : deviceGroupsByUuid) {
+            deviceGroupsByUuid = holderIWipRepositories.deviceGroupRepository().findByUuid(deviceGroup.getUuid().toString());
+            for (WipDeviceGroup deviceGroupByUuid : deviceGroupsByUuid) {
                 foundbyIdDeviceGroup.add(deviceGroupByUuid.getId());
             }
         }
         prepareLogReport(report, addSpaceUntilSize("after devicegroup", SPACE_UNTIL_SIZE_48) + addSpaceUntilSize(foundbyIdDeviceGroup.size(), SPACE_UNTIL_SIZE_32));
 
-        for (DeviceType deviceType : deviceTypes) {
+        for (WipDeviceType deviceType : deviceTypes) {
             // to mimic - Find history for device type by uuid
-            deviceTypesByUuid = holderIRepositories.deviceTypeRepository().findByUuid(deviceType.getUuid().toString());
-            for (DeviceType deviceTypeByUuid : deviceTypesByUuid) {
+            deviceTypesByUuid = holderIWipRepositories.deviceTypeRepository().findByUuid(deviceType.getUuid().toString());
+            for (WipDeviceType deviceTypeByUuid : deviceTypesByUuid) {
                 foundbyIdDeviceType.add(deviceTypeByUuid.getId());
             }
         }
@@ -850,7 +927,7 @@ public class VerificationController {
 
         // prepare new REST API
 
-        List<Name> namesLatest = holderIRepositories.nameRepository().findLatest();
+        List<WipName> namesLatest = holderIWipRepositories.nameRepository().findLatest();
 
         prepareLogReport(report, "Find data");
         prepareLogReport(report, DIVIDER_96);
@@ -870,8 +947,8 @@ public class VerificationController {
             mapIdUuidDeviceRevision.put(entry.getValue().getId(), entry.getValue().getDevice().getUuid());
         }
 
-        HashMap<UUID, Name> mapUuidNameLatest = new HashMap<>((int)(namesLatest.size()/0.75 + 2));
-        for (Name name : namesLatest) {
+        HashMap<UUID, WipName> mapUuidNameLatest = new HashMap<>((int)(namesLatest.size()/0.75 + 2));
+        for (WipName name : namesLatest) {
             mapUuidNameLatest.put(name.getUuid(), name);
         }
 
@@ -919,7 +996,7 @@ public class VerificationController {
         int countIdInOld = 0;
         int countIdNotInOld = 0;
         int countIdNotInOldButDeleted = 0;
-        for (Name name : namesLatest) {
+        for (WipName name : namesLatest) {
             idInOld = mapIdDeviceRevisionDifference.containsKey(name.getId());
             if (idInOld) {
                 countIdInOld++;
@@ -961,7 +1038,7 @@ public class VerificationController {
             //     note use of mapUuidNameLatest - latest (!)
 
             UUID uuid = mapIdUuidDeviceRevision.get(entry.getKey());
-            Name name = uuid != null ? mapUuidNameLatest.get(uuid) : null;
+            WipName name = uuid != null ? mapUuidNameLatest.get(uuid) : null;
 
             // something may be wrong
             //     no name
@@ -1024,7 +1101,7 @@ public class VerificationController {
      * @param mapUuidMaxId map with max id for APPROVED entry in line of uuid for structure
      * @return
      */
-    private boolean equals(Structure structure, NamePartRevision namePartRevision, HashMap<UUID, Long> mapUuidMaxId) {
+    private boolean equals(WipStructure structure, NamePartRevision namePartRevision, HashMap<UUID, Long> mapUuidMaxId) {
         // check
         //     check entry by entry
         //         each attribute as expected
@@ -1122,7 +1199,7 @@ public class VerificationController {
      * @param mapUuidNamePartRevision map with uuid for name part revision
      * @return
      */
-    private boolean equals(Name name, DeviceRevision deviceRevision, HashMap<UUID, Long> mapUuidMaxIdName, HashMap<UUID, NamePartRevision> mapUuidNamePartRevision) {
+    private boolean equals(WipName name, DeviceRevision deviceRevision, HashMap<UUID, Long> mapUuidMaxIdName, HashMap<UUID, NamePartRevision> mapUuidNamePartRevision) {
         // check
         //     check entry by entry
         //         each attribute as expected
diff --git a/src/main/java/org/openepics/names/rest/controller/old/DeviceNamesControllerV0.java b/src/main/java/org/openepics/names/rest/controller/old/DeviceNamesControllerV0.java
index d0e6878898b381ba7642bce01de50654b2ac8311..afd98a9d86c03c4a7b26571e4cd81c606c662533 100644
--- a/src/main/java/org/openepics/names/rest/controller/old/DeviceNamesControllerV0.java
+++ b/src/main/java/org/openepics/names/rest/controller/old/DeviceNamesControllerV0.java
@@ -29,19 +29,19 @@ import java.util.regex.PatternSyntaxException;
 import io.swagger.v3.oas.annotations.Hidden;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.IDeviceGroupRepository;
-import org.openepics.names.repository.IDeviceTypeRepository;
-import org.openepics.names.repository.IDisciplineRepository;
-import org.openepics.names.repository.INameRepository;
-import org.openepics.names.repository.ISubsystemRepository;
-import org.openepics.names.repository.ISystemGroupRepository;
-import org.openepics.names.repository.ISystemRepository;
-import org.openepics.names.repository.model.Name;
+import org.openepics.names.repository.model.wip.WipName;
+import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
+import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
+import org.openepics.names.repository.wip.IWipDisciplineRepository;
+import org.openepics.names.repository.wip.IWipNameRepository;
+import org.openepics.names.repository.wip.IWipSubsystemRepository;
+import org.openepics.names.repository.wip.IWipSystemGroupRepository;
+import org.openepics.names.repository.wip.IWipSystemRepository;
 import org.openepics.names.rest.beans.old.DeviceNameElement;
-import org.openepics.names.util.HolderIRepositories;
-import org.openepics.names.util.HolderStructures;
 import org.openepics.names.util.NamingConventionUtil;
 import org.openepics.names.util.old.DeviceNameElementUtil;
+import org.openepics.names.util.wip.HolderIWipRepositories;
+import org.openepics.names.util.wip.HolderWipStructures;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -82,26 +82,26 @@ public class DeviceNamesControllerV0 {
 
     private static final Logger LOGGER = Logger.getLogger(DeviceNamesControllerV0.class.getName());
 
-    private HolderIRepositories holderIRepositories;
+    private HolderIWipRepositories holderIWipRepositories;
 
     @Autowired
     public DeviceNamesControllerV0(
-            INameRepository iNameRepository,
-            ISystemGroupRepository iSystemGroupRepository,
-            ISystemRepository iSystemRepository,
-            ISubsystemRepository iSubsystemRepository,
-            IDisciplineRepository iDisciplineRepository,
-            IDeviceGroupRepository iDeviceGroupRepository,
-            IDeviceTypeRepository iDeviceTypeRepository) {
-
-        holderIRepositories = new HolderIRepositories(
-                iNameRepository,
-                iSystemGroupRepository,
-                iSystemRepository,
-                iSubsystemRepository,
-                iDisciplineRepository,
-                iDeviceGroupRepository,
-                iDeviceTypeRepository);
+            IWipNameRepository iWipNameRepository,
+            IWipSystemGroupRepository iWipSystemGroupRepository,
+            IWipSystemRepository iWipSystemRepository,
+            IWipSubsystemRepository iWipSubsystemRepository,
+            IWipDisciplineRepository iWipDisciplineRepository,
+            IWipDeviceGroupRepository iWipDeviceGroupRepository,
+            IWipDeviceTypeRepository iWipDeviceTypeRepository) {
+
+        holderIWipRepositories = new HolderIWipRepositories(
+                iWipNameRepository,
+                iWipSystemGroupRepository,
+                iWipSystemRepository,
+                iWipSubsystemRepository,
+                iWipDisciplineRepository,
+                iWipDeviceGroupRepository,
+                iWipDeviceTypeRepository);
     }
 
     /**
@@ -111,15 +111,15 @@ public class DeviceNamesControllerV0 {
      */
     @GetMapping
     public List<DeviceNameElement> findNames() {
-        List<Name> names = holderIRepositories.nameRepository().findLatestNotDeleted();
+        List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
 
         // create collection with known initial capacity
         final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
 
-        // initiate holder of system and device structure content, for performance reasons
-        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+        // holder of valid content for system and device structures
+        HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
-        for (Name name : names) {
+        for (WipName name : names) {
             deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
         }
 
@@ -156,12 +156,12 @@ public class DeviceNamesControllerV0 {
             return deviceNameElements;
         }
 
-        List<Name> names = holderIRepositories.nameRepository().findLatestNotDeleted();
+        List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
 
-        // initiate holder of system and device structure content, for performance reasons
-        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+        // holder of valid content for system and device structures
+        HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
-        for (Name namee : names) {
+        for (WipName namee : names) {
             if (pattern.matcher(namee.getConventionName()).find()) {
                 deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(namee, holderStructures));
             }
@@ -186,20 +186,20 @@ public class DeviceNamesControllerV0 {
         //     exact match
         //     case sensitive
 
-        // initiate holder of system and device structure content, for performance reasons
-        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+        // holder of valid content for system and device structures
+        HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
         final List<DeviceNameElement> deviceNameElements = Lists.newArrayList();
-        List<Name> namesSystemGroup            = holderIRepositories.nameRepository().findLatestBySystemGroupMnemonic(system);
-        for (Name name : namesSystemGroup) {
+        List<WipName> namesSystemGroup            = holderIWipRepositories.nameRepository().findLatestBySystemGroupMnemonic(system);
+        for (WipName name : namesSystemGroup) {
             deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
         }
-        List<Name> namesSystem                 = holderIRepositories.nameRepository().findLatestBySystemMnemonic(system);
-        List<Name> namesSystemThroughSubsystem = holderIRepositories.nameRepository().findLatestBySystemMnemonicThroughSubsystem(system);
-        for (Name name : namesSystem) {
+        List<WipName> namesSystem                 = holderIWipRepositories.nameRepository().findLatestBySystemMnemonic(system);
+        List<WipName> namesSystemThroughSubsystem = holderIWipRepositories.nameRepository().findLatestBySystemMnemonicThroughSubsystem(system);
+        for (WipName name : namesSystem) {
             deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
         }
-        for (Name name : namesSystemThroughSubsystem) {
+        for (WipName name : namesSystemThroughSubsystem) {
             deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
         }
 
@@ -232,12 +232,12 @@ public class DeviceNamesControllerV0 {
             return deviceNameElements;
         }
 
-        List<Name> names = holderIRepositories.nameRepository().findLatestNotDeleted();
+        List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
 
-        // initiate holder of system and device structure content, for performance reasons
-        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+        // holder of valid content for system and device structures
+        HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
-        for (Name name : names) {
+        for (WipName name : names) {
             String sub = NamingConventionUtil.extractSystem(name.getConventionName());
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
                 deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
@@ -263,16 +263,16 @@ public class DeviceNamesControllerV0 {
         //     exact match
         //     case sensitive
 
-        List<Name> names = holderIRepositories.nameRepository().findLatestBySubsystemMnemonic(subsystem);
+        List<WipName> names = holderIWipRepositories.nameRepository().findLatestBySubsystemMnemonic(subsystem);
 
         // create collection with known initial capacity
         final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
 
         if (!names.isEmpty()) {
-            // initiate holder of system and device structure content, for performance reasons
-            HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+            // holder of valid content for system and device structures
+            HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
-            for (Name name : names) {
+            for (WipName name : names) {
                 deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
             }
         }
@@ -306,12 +306,12 @@ public class DeviceNamesControllerV0 {
             return deviceNameElements;
         }
 
-        List<Name> names = holderIRepositories.nameRepository().findLatestNotDeleted();
+        List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
 
-        // initiate holder of system and device structure content, for performance reasons
-        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+        // holder of valid content for system and device structures
+        HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
-        for (Name name : names) {
+        for (WipName name : names) {
             String sub = NamingConventionUtil.extractSubsystem(name.getConventionName());
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
                 deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
@@ -337,16 +337,16 @@ public class DeviceNamesControllerV0 {
         //     exact match
         //     case sensitive
 
-        List<Name> names = holderIRepositories.nameRepository().findLatestByDisciplineMnemonicThroughDeviceType(discipline);
+        List<WipName> names = holderIWipRepositories.nameRepository().findLatestByDisciplineMnemonicThroughDeviceType(discipline);
 
         // create collection with known initial capacity
         final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
 
         if (!names.isEmpty()) {
-            // initiate holder of system and device structure content, for performance reasons
-            HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+            // holder of valid content for system and device structures
+            HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
-            for (Name name : names) {
+            for (WipName name : names) {
                 deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
             }
         }
@@ -380,12 +380,12 @@ public class DeviceNamesControllerV0 {
             return deviceNameElements;
         }
 
-        List<Name> names = holderIRepositories.nameRepository().findLatestNotDeleted();
+        List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
 
-        // initiate holder of system and device structure content, for performance reasons
-        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+        // holder of valid content for system and device structures
+        HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
-        for (Name name : names) {
+        for (WipName name : names) {
             String sub = NamingConventionUtil.extractDiscipline(name.getConventionName());
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
                 deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
@@ -411,16 +411,16 @@ public class DeviceNamesControllerV0 {
         //     exact match
         //     case sensitive
 
-        List<Name> names = holderIRepositories.nameRepository().findLatestByDeviceTypeMnemonic(deviceType);
+        List<WipName> names = holderIWipRepositories.nameRepository().findLatestByDeviceTypeMnemonic(deviceType);
 
         // create collection with known initial capacity
         final List<DeviceNameElement> deviceNameElements = new ArrayList<>(names.size());
 
         if (!names.isEmpty()) {
-            // initiate holder of system and device structure content, for performance reasons
-            HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+            // holder of valid content for system and device structures
+            HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
-            for (Name name : names) {
+            for (WipName name : names) {
                 deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
             }
         }
@@ -454,12 +454,12 @@ public class DeviceNamesControllerV0 {
             return deviceNameElements;
         }
 
-        List<Name> names = holderIRepositories.nameRepository().findLatestNotDeleted();
+        List<WipName> names = holderIWipRepositories.nameRepository().findLatestNotDeleted();
 
-        // initiate holder of system and device structure content, for performance reasons
-        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
+        // holder of valid content for system and device structures
+        HolderWipStructures holderStructures = new HolderWipStructures(holderIWipRepositories);
 
-        for (Name name : names) {
+        for (WipName name : names) {
             String sub = NamingConventionUtil.extractDeviceType(name.getConventionName());
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
                 deviceNameElements.add(DeviceNameElementUtil.getDeviceNameElement(name, holderStructures));
@@ -484,14 +484,14 @@ public class DeviceNamesControllerV0 {
         //     exact match
         //     case sensitive
 
-        Name name = null;
+        WipName name = null;
         try {
             UUID.fromString(uuid);
-            name = holderIRepositories.nameRepository().findLatestByUuid(uuid);
+            name = holderIWipRepositories.nameRepository().findLatestByUuid(uuid);
         } catch (IllegalArgumentException e) {
-            name = holderIRepositories.nameRepository().findLatestByConventionName(uuid);
+            name = holderIWipRepositories.nameRepository().findLatestByConventionName(uuid);
         }
-        DeviceNameElement deviceNameElement = DeviceNameElementUtil.getDeviceNameElement(name, holderIRepositories);
+        DeviceNameElement deviceNameElement = DeviceNameElementUtil.getDeviceNameElement(name, holderIWipRepositories);
 
         LOGGER.log(Level.FINE, "findName, uuid:              {0}", uuid);
         LOGGER.log(Level.FINE, "findName, deviceNameElement: {0}", deviceNameElement);
diff --git a/src/main/java/org/openepics/names/rest/controller/old/HistoryControllerV0.java b/src/main/java/org/openepics/names/rest/controller/old/HistoryControllerV0.java
index 1d5f6856d382428c7fd5945823cf292727b23884..0e73cd480f523e5d4f47008270cf58b5e6ef87ef 100644
--- a/src/main/java/org/openepics/names/rest/controller/old/HistoryControllerV0.java
+++ b/src/main/java/org/openepics/names/rest/controller/old/HistoryControllerV0.java
@@ -23,23 +23,23 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.IDeviceGroupRepository;
-import org.openepics.names.repository.IDeviceTypeRepository;
-import org.openepics.names.repository.IDisciplineRepository;
-import org.openepics.names.repository.INameRepository;
-import org.openepics.names.repository.ISubsystemRepository;
-import org.openepics.names.repository.ISystemGroupRepository;
-import org.openepics.names.repository.ISystemRepository;
-import org.openepics.names.repository.model.DeviceGroup;
-import org.openepics.names.repository.model.DeviceType;
-import org.openepics.names.repository.model.Discipline;
-import org.openepics.names.repository.model.Name;
-import org.openepics.names.repository.model.Subsystem;
-import org.openepics.names.repository.model.System;
-import org.openepics.names.repository.model.SystemGroup;
+import org.openepics.names.repository.model.wip.WipDeviceGroup;
+import org.openepics.names.repository.model.wip.WipDeviceType;
+import org.openepics.names.repository.model.wip.WipDiscipline;
+import org.openepics.names.repository.model.wip.WipName;
+import org.openepics.names.repository.model.wip.WipSubsystem;
+import org.openepics.names.repository.model.wip.WipSystem;
+import org.openepics.names.repository.model.wip.WipSystemGroup;
+import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
+import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
+import org.openepics.names.repository.wip.IWipDisciplineRepository;
+import org.openepics.names.repository.wip.IWipNameRepository;
+import org.openepics.names.repository.wip.IWipSubsystemRepository;
+import org.openepics.names.repository.wip.IWipSystemGroupRepository;
+import org.openepics.names.repository.wip.IWipSystemRepository;
 import org.openepics.names.rest.beans.old.HistoryElement;
-import org.openepics.names.util.HolderIRepositories;
 import org.openepics.names.util.old.HistoryElementUtil;
+import org.openepics.names.util.wip.HolderIWipRepositories;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -75,26 +75,26 @@ public class HistoryControllerV0 {
 
     private static final long THOUSAND_MILLISECONDS = 1000;
 
-    private HolderIRepositories holderIRepositories;
+    private HolderIWipRepositories holderIWipRepositories;
 
     @Autowired
     public HistoryControllerV0(
-            INameRepository iNameRepository,
-            ISystemGroupRepository iSystemGroupRepository,
-            ISystemRepository iSystemRepository,
-            ISubsystemRepository iSubsystemRepository,
-            IDisciplineRepository iDisciplineRepository,
-            IDeviceGroupRepository iDeviceGroupRepository,
-            IDeviceTypeRepository iDeviceTypeRepository) {
-
-        holderIRepositories = new HolderIRepositories(
-                iNameRepository,
-                iSystemGroupRepository,
-                iSystemRepository,
-                iSubsystemRepository,
-                iDisciplineRepository,
-                iDeviceGroupRepository,
-                iDeviceTypeRepository);
+            IWipNameRepository iWipNameRepository,
+            IWipSystemGroupRepository iWipSystemGroupRepository,
+            IWipSystemRepository iWipSystemRepository,
+            IWipSubsystemRepository iWipSubsystemRepository,
+            IWipDisciplineRepository iWipDisciplineRepository,
+            IWipDeviceGroupRepository iWipDeviceGroupRepository,
+            IWipDeviceTypeRepository iWipDeviceTypeRepository) {
+
+        holderIWipRepositories = new HolderIWipRepositories(
+                iWipNameRepository,
+                iWipSystemGroupRepository,
+                iWipSystemRepository,
+                iWipSubsystemRepository,
+                iWipDisciplineRepository,
+                iWipDeviceGroupRepository,
+                iWipDeviceTypeRepository);
     }
 
     /**
@@ -118,16 +118,16 @@ public class HistoryControllerV0 {
             return historyElements;
         }
 
-        List<SystemGroup> systemGroups = holderIRepositories.systemGroupRepository().findByUuid(uuid);
-        List<System>      systems      = holderIRepositories.systemRepository().findByUuid(uuid);
-        List<Subsystem>   subsystems   = holderIRepositories.subsystemRepository().findByUuid(uuid);
+        List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findByUuid(uuid);
+        List<WipSystem>      systems      = holderIWipRepositories.systemRepository().findByUuid(uuid);
+        List<WipSubsystem>   subsystems   = holderIWipRepositories.subsystemRepository().findByUuid(uuid);
 
-        List<Discipline>  disciplines  = holderIRepositories.disciplineRepository().findByUuid(uuid);
-        List<DeviceGroup> deviceGroups = holderIRepositories.deviceGroupRepository().findByUuid(uuid);
-        List<DeviceType>  deviceTypes  = holderIRepositories.deviceTypeRepository().findByUuid(uuid);
+        List<WipDiscipline>  disciplines  = holderIWipRepositories.disciplineRepository().findByUuid(uuid);
+        List<WipDeviceGroup> deviceGroups = holderIWipRepositories.deviceGroupRepository().findByUuid(uuid);
+        List<WipDeviceType>  deviceTypes  = holderIWipRepositories.deviceTypeRepository().findByUuid(uuid);
 
         if (!systemGroups.isEmpty()) {
-            for (SystemGroup systemGroup : systemGroups) {
+            for (WipSystemGroup systemGroup : systemGroups) {
                 // one or two return elements
                 //     processed != null and processed != requested (>  1s difference) --> two entries (processed, requested)
                 //     processed != null and processed == requested (<= 1s difference) --> one entry   (processed initial)
@@ -143,7 +143,7 @@ public class HistoryControllerV0 {
                 }
             }
         } else if (!systems.isEmpty()) {
-            for (System system : systems) {
+            for (WipSystem system : systems) {
                 // one or two return elements
                 //     processed != null and processed != requested (>  1s difference) --> two entries (processed, requested)
                 //     processed != null and processed == requested (<= 1s difference) --> one entry   (processed initial)
@@ -159,7 +159,7 @@ public class HistoryControllerV0 {
                 }
             }
         } else if (!subsystems.isEmpty()) {
-            for (Subsystem subsystem : subsystems) {
+            for (WipSubsystem subsystem : subsystems) {
                 // one or two return elements
                 //     processed != null and processed != requested (>  1s difference) --> two entries (processed, requested)
                 //     processed != null and processed == requested (<= 1s difference) --> one entry   (processed initial)
@@ -175,7 +175,7 @@ public class HistoryControllerV0 {
                 }
             }
         } else if (!disciplines.isEmpty()) {
-            for (Discipline discipline : disciplines) {
+            for (WipDiscipline discipline : disciplines) {
                 // one or two return elements
                 //     processed != null and processed != requested (>  1s difference) --> two entries (processed, requested)
                 //     processed != null and processed == requested (<= 1s difference) --> one entry   (processed initial)
@@ -191,7 +191,7 @@ public class HistoryControllerV0 {
                 }
             }
         } else if (!deviceGroups.isEmpty()) {
-            for (DeviceGroup deviceGroup : deviceGroups) {
+            for (WipDeviceGroup deviceGroup : deviceGroups) {
                 // one or two return elements
                 //     processed != null and processed != requested (>  1s difference) --> two entries (processed, requested)
                 //     processed != null and processed == requested (<= 1s difference) --> one entry   (processed initial)
@@ -207,7 +207,7 @@ public class HistoryControllerV0 {
                 }
             }
         } else if (!deviceTypes.isEmpty()) {
-            for (DeviceType deviceType : deviceTypes) {
+            for (WipDeviceType deviceType : deviceTypes) {
                 // one or two return elements
                 //     processed != null and processed != requested (>  1s difference) --> two entries (processed, requested)
                 //     processed != null and processed == requested (<= 1s difference) --> one entry   (processed initial)
@@ -251,8 +251,8 @@ public class HistoryControllerV0 {
             return historyElements;
         }
 
-        List<Name> names = holderIRepositories.nameRepository().findByUuid(uuid);
-        for (Name name : names) {
+        List<WipName> names = holderIWipRepositories.nameRepository().findByUuid(uuid);
+        for (WipName name : names) {
             historyElements.add(HistoryElementUtil.getHistoryElement(name));
         }
 
diff --git a/src/main/java/org/openepics/names/rest/controller/old/PartControllerV0.java b/src/main/java/org/openepics/names/rest/controller/old/PartControllerV0.java
index 5c7db28b83365241e97600106a91127b823b0095..0ce94e3e65691dc4f4dcf7df66fced1c7522561a 100644
--- a/src/main/java/org/openepics/names/rest/controller/old/PartControllerV0.java
+++ b/src/main/java/org/openepics/names/rest/controller/old/PartControllerV0.java
@@ -25,23 +25,23 @@ import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.IDeviceGroupRepository;
-import org.openepics.names.repository.IDeviceTypeRepository;
-import org.openepics.names.repository.IDisciplineRepository;
-import org.openepics.names.repository.INameRepository;
-import org.openepics.names.repository.ISubsystemRepository;
-import org.openepics.names.repository.ISystemGroupRepository;
-import org.openepics.names.repository.ISystemRepository;
-import org.openepics.names.repository.model.DeviceGroup;
-import org.openepics.names.repository.model.DeviceType;
-import org.openepics.names.repository.model.Discipline;
-import org.openepics.names.repository.model.Subsystem;
-import org.openepics.names.repository.model.System;
-import org.openepics.names.repository.model.SystemGroup;
+import org.openepics.names.repository.model.wip.WipDeviceGroup;
+import org.openepics.names.repository.model.wip.WipDeviceType;
+import org.openepics.names.repository.model.wip.WipDiscipline;
+import org.openepics.names.repository.model.wip.WipSubsystem;
+import org.openepics.names.repository.model.wip.WipSystem;
+import org.openepics.names.repository.model.wip.WipSystemGroup;
+import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
+import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
+import org.openepics.names.repository.wip.IWipDisciplineRepository;
+import org.openepics.names.repository.wip.IWipNameRepository;
+import org.openepics.names.repository.wip.IWipSubsystemRepository;
+import org.openepics.names.repository.wip.IWipSystemGroupRepository;
+import org.openepics.names.repository.wip.IWipSystemRepository;
 import org.openepics.names.rest.beans.old.PartElement;
-import org.openepics.names.util.HolderIRepositories;
 import org.openepics.names.util.NamingConventionUtil;
 import org.openepics.names.util.old.PartElementUtil;
+import org.openepics.names.util.wip.HolderIWipRepositories;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -76,26 +76,26 @@ public class PartControllerV0 {
 
     private static final Logger LOGGER = Logger.getLogger(PartControllerV0.class.getName());
 
-    private HolderIRepositories holderIRepositories;
+    private HolderIWipRepositories holderIWipRepositories;
 
     @Autowired
     public PartControllerV0(
-            INameRepository iNameRepository,
-            ISystemGroupRepository iSystemGroupRepository,
-            ISystemRepository iSystemRepository,
-            ISubsystemRepository iSubsystemRepository,
-            IDisciplineRepository iDisciplineRepository,
-            IDeviceGroupRepository iDeviceGroupRepository,
-            IDeviceTypeRepository iDeviceTypeRepository) {
-
-        holderIRepositories = new HolderIRepositories(
-                iNameRepository,
-                iSystemGroupRepository,
-                iSystemRepository,
-                iSubsystemRepository,
-                iDisciplineRepository,
-                iDeviceGroupRepository,
-                iDeviceTypeRepository);
+            IWipNameRepository iWipNameRepository,
+            IWipSystemGroupRepository iWipSystemGroupRepository,
+            IWipSystemRepository iWipSystemRepository,
+            IWipSubsystemRepository iWipSubsystemRepository,
+            IWipDisciplineRepository iWipDisciplineRepository,
+            IWipDeviceGroupRepository iWipDeviceGroupRepository,
+            IWipDeviceTypeRepository iWipDeviceTypeRepository) {
+
+        holderIWipRepositories = new HolderIWipRepositories(
+                iWipNameRepository,
+                iWipSystemGroupRepository,
+                iWipSystemRepository,
+                iWipSubsystemRepository,
+                iWipDisciplineRepository,
+                iWipDeviceGroupRepository,
+                iWipDeviceTypeRepository);
     }
 
     /**
@@ -115,30 +115,30 @@ public class PartControllerV0 {
 
         // find in system structure
 
-        List<SystemGroup> systemGroups = holderIRepositories.systemGroupRepository().findLatestByMnemonic(mnemonic);
-        List<System>      systems      = holderIRepositories.systemRepository().findLatestByMnemonic(mnemonic);
-        List<Subsystem>   subsystems   = holderIRepositories.subsystemRepository().findLatestByMnemonic(mnemonic);
+        List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findLatestByMnemonic(mnemonic);
+        List<WipSystem>      systems      = holderIWipRepositories.systemRepository().findLatestByMnemonic(mnemonic);
+        List<WipSubsystem>   subsystems   = holderIWipRepositories.subsystemRepository().findLatestByMnemonic(mnemonic);
 
-        for (SystemGroup systemGroup : systemGroups) {
+        for (WipSystemGroup systemGroup : systemGroups) {
             partElements.add(PartElementUtil.getPartElement(systemGroup));
         }
-        for (System system : systems) {
-            partElements.add(PartElementUtil.getPartElement(system, holderIRepositories));
+        for (WipSystem system : systems) {
+            partElements.add(PartElementUtil.getPartElement(system, holderIWipRepositories));
         }
-        for (Subsystem subsystem : subsystems) {
-            partElements.add(PartElementUtil.getPartElement(subsystem, holderIRepositories));
+        for (WipSubsystem subsystem : subsystems) {
+            partElements.add(PartElementUtil.getPartElement(subsystem, holderIWipRepositories));
         }
 
         // find in system structure
 
-        List<Discipline> disciplines = holderIRepositories.disciplineRepository().findLatestByMnemonic(mnemonic);
-        List<DeviceType> deviceTypes = holderIRepositories.deviceTypeRepository().findLatestByMnemonic(mnemonic);
+        List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findLatestByMnemonic(mnemonic);
+        List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findLatestByMnemonic(mnemonic);
 
-        for (Discipline discipline : disciplines) {
+        for (WipDiscipline discipline : disciplines) {
             partElements.add(PartElementUtil.getPartElement(discipline));
         }
-        for (DeviceType deviceType : deviceTypes) {
-            partElements.add(PartElementUtil.getPartElement(deviceType, holderIRepositories));
+        for (WipDeviceType deviceType : deviceTypes) {
+            partElements.add(PartElementUtil.getPartElement(deviceType, holderIWipRepositories));
         }
 
         LOGGER.log(Level.FINE, "findPartsByMnemonic, mnemonic:          {0}", mnemonic);
@@ -172,44 +172,44 @@ public class PartControllerV0 {
 
         // find in system structure
 
-        List<SystemGroup> systemGroups = holderIRepositories.systemGroupRepository().findLatest();
-        List<System>      systems      = holderIRepositories.systemRepository().findLatest();
-        List<Subsystem>   subsystems   = holderIRepositories.subsystemRepository().findLatest();
+        List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findLatest();
+        List<WipSystem>      systems      = holderIWipRepositories.systemRepository().findLatest();
+        List<WipSubsystem>   subsystems   = holderIWipRepositories.subsystemRepository().findLatest();
 
-        for (SystemGroup systemGroup : systemGroups) {
+        for (WipSystemGroup systemGroup : systemGroups) {
             String sub = systemGroup.getMnemonic();
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
                 partElements.add(PartElementUtil.getPartElement(systemGroup));
             }
         }
-        for (System system : systems) {
+        for (WipSystem system : systems) {
             String sub = system.getMnemonic();
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
-                partElements.add(PartElementUtil.getPartElement(system, holderIRepositories));
+                partElements.add(PartElementUtil.getPartElement(system, holderIWipRepositories));
             }
         }
-        for (Subsystem subsystem : subsystems) {
+        for (WipSubsystem subsystem : subsystems) {
             String sub = subsystem.getMnemonic();
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
-                partElements.add(PartElementUtil.getPartElement(subsystem, holderIRepositories));
+                partElements.add(PartElementUtil.getPartElement(subsystem, holderIWipRepositories));
             }
         }
 
         // find in device structure
 
-        List<Discipline> disciplines = holderIRepositories.disciplineRepository().findLatest();
-        List<DeviceType> deviceTypes = holderIRepositories.deviceTypeRepository().findLatest();
+        List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findLatest();
+        List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findLatest();
 
-        for (Discipline discipline : disciplines) {
+        for (WipDiscipline discipline : disciplines) {
             String sub = discipline.getMnemonic();
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
                 partElements.add(PartElementUtil.getPartElement(discipline));
             }
         }
-        for (DeviceType deviceType : deviceTypes) {
+        for (WipDeviceType deviceType : deviceTypes) {
             String sub = deviceType.getMnemonic();
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
-                partElements.add(PartElementUtil.getPartElement(deviceType, holderIRepositories));
+                partElements.add(PartElementUtil.getPartElement(deviceType, holderIWipRepositories));
             }
         }
 
@@ -244,52 +244,52 @@ public class PartControllerV0 {
 
         // find in system structure
 
-        List<SystemGroup> systemGroups = holderIRepositories.systemGroupRepository().findLatest();
-        List<System>      systems      = holderIRepositories.systemRepository().findLatest();
-        List<Subsystem>   subsystems   = holderIRepositories.subsystemRepository().findLatest();
+        List<WipSystemGroup> systemGroups = holderIWipRepositories.systemGroupRepository().findLatest();
+        List<WipSystem>      systems      = holderIWipRepositories.systemRepository().findLatest();
+        List<WipSubsystem>   subsystems   = holderIWipRepositories.subsystemRepository().findLatest();
 
-        for (SystemGroup systemGroup : systemGroups) {
+        for (WipSystemGroup systemGroup : systemGroups) {
             String sub = systemGroup.getMnemonic();
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
                 partElements.add(PartElementUtil.getPartElement(systemGroup));
             }
         }
-        for (System system : systems) {
-            SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
+        for (WipSystem system : systems) {
+            WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
 
             String sub = NamingConventionUtil.mnemonicPath2String(null, null);
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
-                partElements.add(PartElementUtil.getPartElement(system, holderIRepositories));
+                partElements.add(PartElementUtil.getPartElement(system, holderIWipRepositories));
             }
         }
-        for (Subsystem subsystem : subsystems) {
-            System      system      = holderIRepositories.systemRepository().findLatestByUuid(subsystem.getParentUuid().toString());
-            SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
+        for (WipSubsystem subsystem : subsystems) {
+            WipSystem      system      = holderIWipRepositories.systemRepository().findLatestByUuid(subsystem.getParentUuid().toString());
+            WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
 
             String sub = NamingConventionUtil.mnemonicPath2String(systemGroup.getMnemonic(), system.getMnemonic(), subsystem.getMnemonic());
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
-                partElements.add(PartElementUtil.getPartElement(subsystem, holderIRepositories));
+                partElements.add(PartElementUtil.getPartElement(subsystem, holderIWipRepositories));
             }
         }
 
         // find in device structure
 
-        List<Discipline> disciplines = holderIRepositories.disciplineRepository().findLatest();
-        List<DeviceType> deviceTypes = holderIRepositories.deviceTypeRepository().findLatest();
+        List<WipDiscipline> disciplines = holderIWipRepositories.disciplineRepository().findLatest();
+        List<WipDeviceType> deviceTypes = holderIWipRepositories.deviceTypeRepository().findLatest();
 
-        for (Discipline discipline : disciplines) {
+        for (WipDiscipline discipline : disciplines) {
             String sub = discipline.getMnemonic();
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
                 partElements.add(PartElementUtil.getPartElement(discipline));
             }
         }
-        for (DeviceType deviceType : deviceTypes) {
-            DeviceGroup deviceGroup = holderIRepositories.deviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString());
-            Discipline  discipline  = holderIRepositories.disciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString());
+        for (WipDeviceType deviceType : deviceTypes) {
+            WipDeviceGroup deviceGroup = holderIWipRepositories.deviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString());
+            WipDiscipline  discipline  = holderIWipRepositories.disciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString());
 
             String sub = NamingConventionUtil.mnemonicPath2String(discipline.getMnemonic(), deviceType.getMnemonic());
             if (!StringUtils.isEmpty(sub) && pattern.matcher(sub).find()) {
-                partElements.add(PartElementUtil.getPartElement(deviceType, holderIRepositories));
+                partElements.add(PartElementUtil.getPartElement(deviceType, holderIWipRepositories));
             }
         }
 
diff --git a/src/main/java/org/openepics/names/service/DeviceGroupService.java b/src/main/java/org/openepics/names/service/DeviceGroupService.java
index 7edcda9cbe56f1c2991538f69b1495a60c4eefe9..83983c6d8c35e56589acf74c1fae4dbbea40e48a 100644
--- a/src/main/java/org/openepics/names/service/DeviceGroupService.java
+++ b/src/main/java/org/openepics/names/service/DeviceGroupService.java
@@ -26,11 +26,16 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.DeviceGroupRepository;
+import org.openepics.names.repository.IAuditStructureRepository;
 import org.openepics.names.repository.IDeviceGroupRepository;
 import org.openepics.names.repository.IDeviceTypeRepository;
+import org.openepics.names.repository.IDisciplineRepository;
+import org.openepics.names.repository.model.AuditStructure;
 import org.openepics.names.repository.model.DeviceGroup;
 import org.openepics.names.repository.model.DeviceType;
+import org.openepics.names.repository.model.Discipline;
+import org.openepics.names.repository.AuditStructureRepository;
+import org.openepics.names.repository.DeviceGroupRepository;
 import org.openepics.names.rest.beans.Status;
 import org.openepics.names.rest.beans.Type;
 import org.openepics.names.rest.beans.element.StructureElementCommand;
@@ -40,8 +45,8 @@ import org.openepics.names.util.StructureChoice;
 import org.openepics.names.util.StructureCommand;
 import org.openepics.names.util.StructureElementUtil;
 import org.openepics.names.util.TextUtil;
-import org.openepics.names.util.ValidateUtil;
 import org.openepics.names.util.notification.NotificationUtil;
+import org.openepics.names.util.notification.StructureElementNotification;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -59,50 +64,59 @@ public class DeviceGroupService {
 
     private static final Logger LOGGER = Logger.getLogger(DeviceGroupService.class.getName());
 
+    private DeviceTypeService deviceTypeService;
+    private IDisciplineRepository iDisciplineRepository;
     private IDeviceGroupRepository iDeviceGroupRepository;
     private IDeviceTypeRepository iDeviceTypeRepository;
+    private IAuditStructureRepository iAuditStructureRepository;
     private DeviceGroupRepository deviceGroupRepository;
-    private DeviceTypeService deviceTypeService;
+    private AuditStructureRepository auditStructureRepository;
 
     @Autowired
     public DeviceGroupService(
+            DeviceTypeService deviceTypeService,
+            IDisciplineRepository iDisciplineRepository,
             IDeviceGroupRepository iDeviceGroupRepository,
             IDeviceTypeRepository iDeviceTypeRepository,
+            IAuditStructureRepository iAuditStructureRepository,
             DeviceGroupRepository deviceGroupRepository,
-            DeviceTypeService deviceTypeService) {
+            AuditStructureRepository auditStructureRepository) {
+        this.deviceTypeService = deviceTypeService;
+        this.iDisciplineRepository = iDisciplineRepository;
         this.iDeviceGroupRepository = iDeviceGroupRepository;
-        this.iDeviceTypeRepository = iDeviceTypeRepository;
+        this.iDeviceTypeRepository  = iDeviceTypeRepository;
+        this.iAuditStructureRepository = iAuditStructureRepository;
         this.deviceGroupRepository = deviceGroupRepository;
-        this.deviceTypeService = deviceTypeService;
+        this.auditStructureRepository = auditStructureRepository;
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     create structure - approved, latest, not deleted
+        //     create structure
+        //     create audit
         //     return
         //         structure element for created structure
         //         notification
-        //
-        // attributes
-        //     type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
+        UUID uuid = UUID.randomUUID();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // create
-        DeviceGroup deviceGroup = new DeviceGroup(UUID.randomUUID(), structureElementCommand.getParent(),
+        // create structure
+        // create audit
+        Discipline discipline = iDisciplineRepository.findByUuid(structureElementCommand.getParent().toString());
+        DeviceGroup deviceGroup = new DeviceGroup(uuid, discipline.getId(),
                 mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
+                structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
                 when, username, null);
         deviceGroupRepository.createDeviceGroup(deviceGroup);
+        auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, deviceGroup));
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
 
@@ -112,50 +126,38 @@ public class DeviceGroupService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, not deleted
+        //     update structure
+        //     create audit
         //     previous for notification
         //     return
         //         structure element for updated structure
         //         notification
-        //
-        // attributes
-        //     uuid, type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
         String uuid = structureElementCommand.getUuid().toString();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // find
-        List<DeviceGroup> deviceGroups = deviceGroupRepository.readDeviceGroups(Boolean.FALSE, uuid, null, null, null, null, null, null);
-        DeviceGroup deviceGroup = null;
-        if (ValidateUtil.isSize(deviceGroups, 1)) {
-            deviceGroup = deviceGroups.get(0);
-
-            // update not latest
-            deviceGroup.setLatest(Boolean.FALSE);
-            deviceGroupRepository.updateDeviceGroup(deviceGroup);
-        }
-
-        // create
-        deviceGroup = new DeviceGroup(structureElementCommand.getUuid(), structureElementCommand.getParent(),
-                mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
-                when, username, null);
-        deviceGroupRepository.createDeviceGroup(deviceGroup);
+        // update structure
+        // create audit
+        DeviceGroup deviceGroup = iDeviceGroupRepository.findByUuid(uuid);
+        deviceGroup.setMnemonic(mnemonic);
+        deviceGroup.setMnemonicEquivalence(equivalenceClassRepresentative);
+        deviceGroup.setOrdering(structureElementCommand.getOrdering());
+        deviceGroup.setDescription(structureElementCommand.getDescription());
+        deviceGroupRepository.updateDeviceGroup(deviceGroup);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, deviceGroup);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<DeviceGroup> previouses = iDeviceGroupRepository.findPreviousByUuidAndId(deviceGroup.getUuid().toString(), deviceGroup.getId());
-        DeviceGroup previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DEVICEGROUP.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        DeviceGroup previous = new DeviceGroup(previousAuditStructure);
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
 
@@ -165,51 +167,40 @@ public class DeviceGroupService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username, HolderStructures holderStructures) {
+    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, deleted
+        //     delete structure (update)
+        //     create audit
         //     previous for notification
-        //     additional - delete sub structures (and related names)
+        //     additional
+        //         delete sub structures (and related names)
         //     return
         //         structure element for deleted structure
         //         notification
-        //
-        // attributes
-        //     uuid
 
         String uuid = structureElementCommand.getUuid().toString();
 
-        // find
-        List<DeviceGroup> deviceGroups = deviceGroupRepository.readDeviceGroups(Boolean.FALSE, uuid, null, null, null, null, null, null);
-        DeviceGroup deviceGroup = null;
-        if (ValidateUtil.isSize(deviceGroups, 1)) {
-            deviceGroup = deviceGroups.get(0);
-
-            // update not latest
-            deviceGroup.setLatest(Boolean.FALSE);
-            deviceGroupRepository.updateDeviceGroup(deviceGroup);
-        } else {
-            return null;
-        }
-
-        // create
-        deviceGroup = new DeviceGroup(deviceGroup.getUuid(), deviceGroup.getParentUuid(),
-                deviceGroup.getMnemonic(), deviceGroup.getMnemonicEquivalence(), deviceGroup.getOrdering(),
-                deviceGroup.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.TRUE,
-                when, username, null);
-        deviceGroupRepository.createDeviceGroup(deviceGroup);
+        // delete structure
+        // create audit
+        DeviceGroup deviceGroup = iDeviceGroupRepository.findByUuid(uuid);
+        deviceGroup.setDeleted(Boolean.TRUE);
+        deviceGroup.setAttributesProcessed(when, username, null);
+        deviceGroupRepository.updateDeviceGroup(deviceGroup);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, deviceGroup);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<DeviceGroup> previouses = iDeviceGroupRepository.findPreviousByUuidAndId(uuid, deviceGroup.getId());
-        DeviceGroup previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DEVICEGROUP.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        DeviceGroup previous = new DeviceGroup(previousAuditStructure);
 
         // additional
         //     will propagate to sub structures
         List<StructureElementCommand> commands = Lists.newArrayList();
-        List<DeviceType> deviceTypes = iDeviceTypeRepository.findLatestNotDeletedByParent(uuid);
+        List<DeviceType> deviceTypes = iDeviceTypeRepository.findNotDeletedByParent(deviceGroup.getId());
         for (DeviceType deviceType : deviceTypes) {
             commands.add(new StructureElementCommand(deviceType.getUuid(), Type.DEVICETYPE, null, null, null, null));
         }
diff --git a/src/main/java/org/openepics/names/service/DeviceTypeService.java b/src/main/java/org/openepics/names/service/DeviceTypeService.java
index 169907c1dacf9c42fbf8b1d71cf2027b62e93463..146936caa4aa52222c0c7abdc2a681bbae4891b9 100644
--- a/src/main/java/org/openepics/names/service/DeviceTypeService.java
+++ b/src/main/java/org/openepics/names/service/DeviceTypeService.java
@@ -20,15 +20,19 @@ package org.openepics.names.service;
 
 import java.text.MessageFormat;
 import java.util.Date;
-import java.util.List;
 import java.util.UUID;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.DeviceTypeRepository;
+import org.openepics.names.repository.IAuditStructureRepository;
+import org.openepics.names.repository.IDeviceGroupRepository;
 import org.openepics.names.repository.IDeviceTypeRepository;
+import org.openepics.names.repository.model.AuditStructure;
+import org.openepics.names.repository.model.DeviceGroup;
 import org.openepics.names.repository.model.DeviceType;
+import org.openepics.names.repository.AuditStructureRepository;
+import org.openepics.names.repository.DeviceTypeRepository;
 import org.openepics.names.rest.beans.Status;
 import org.openepics.names.rest.beans.Type;
 import org.openepics.names.rest.beans.element.StructureElementCommand;
@@ -38,8 +42,8 @@ import org.openepics.names.util.StructureChoice;
 import org.openepics.names.util.StructureCommand;
 import org.openepics.names.util.StructureElementUtil;
 import org.openepics.names.util.TextUtil;
-import org.openepics.names.util.ValidateUtil;
 import org.openepics.names.util.notification.NotificationUtil;
+import org.openepics.names.util.notification.StructureElementNotification;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -55,47 +59,56 @@ public class DeviceTypeService {
 
     private static final Logger LOGGER = Logger.getLogger(DeviceTypeService.class.getName());
 
+    private NamesService namesService;
+    private IDeviceGroupRepository iDeviceGroupRepository;
     private IDeviceTypeRepository iDeviceTypeRepository;
+    private IAuditStructureRepository iAuditStructureRepository;
     private DeviceTypeRepository deviceTypeRepository;
-    private NamesService namesService;
+    private AuditStructureRepository auditStructureRepository;
 
     @Autowired
     public DeviceTypeService(
+            NamesService namesService,
+            IDeviceGroupRepository iDeviceGroupRepository,
             IDeviceTypeRepository iDeviceTypeRepository,
+            IAuditStructureRepository iAuditStructureRepository,
             DeviceTypeRepository deviceTypeRepository,
-            NamesService namesService) {
+            AuditStructureRepository auditStructureRepository) {
+        this.namesService = namesService;
+        this.iDeviceGroupRepository = iDeviceGroupRepository;
         this.iDeviceTypeRepository = iDeviceTypeRepository;
+        this.iAuditStructureRepository = iAuditStructureRepository;
         this.deviceTypeRepository = deviceTypeRepository;
-        this.namesService = namesService;
+        this.auditStructureRepository = auditStructureRepository;
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     create structure - approved, latest, not deleted
+        //     create structure
+        //     create audit
         //     return
         //         structure element for created structure
         //         notification
-        //
-        // attributes
-        //     type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
+        UUID uuid = UUID.randomUUID();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // create
-        DeviceType deviceType = new DeviceType(UUID.randomUUID(), structureElementCommand.getParent(),
+        // create structure
+        // create audit
+        DeviceGroup deviceGroup = iDeviceGroupRepository.findByUuid(structureElementCommand.getParent().toString());
+        DeviceType deviceType = new DeviceType(uuid, deviceGroup.getId(),
                 mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
+                structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
                 when, username, null);
         deviceTypeRepository.createDeviceType(deviceType);
+        auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, deviceType));
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
 
@@ -105,54 +118,43 @@ public class DeviceTypeService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, not deleted
+        //     update structure
+        //     create audit
         //     previous for notification
-        //     additional - update related names
+        //     additional
+        //         update related names
         //     return
         //         structure element for updated structure
         //         notification
-        //
-        // attributes
-        //     uuid, type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
         String uuid = structureElementCommand.getUuid().toString();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // find
-        List<DeviceType> deviceTypes = deviceTypeRepository.readDeviceTypes(Boolean.FALSE, uuid, null, null, null, null, null, null);
-        DeviceType deviceType = null;
-        if (ValidateUtil.isSize(deviceTypes, 1)) {
-            deviceType = deviceTypes.get(0);
-
-            // update not latest
-            deviceType.setLatest(Boolean.FALSE);
-            deviceTypeRepository.updateDeviceType(deviceType);
-        }
-
-        // create
-        deviceType = new DeviceType(structureElementCommand.getUuid(), structureElementCommand.getParent(),
-                mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
-                when, username, null);
-        deviceTypeRepository.createDeviceType(deviceType);
+        // update structure
+        // create audit
+        DeviceType deviceType = iDeviceTypeRepository.findByUuid(uuid);
+        deviceType.setMnemonic(mnemonic);
+        deviceType.setMnemonicEquivalence(equivalenceClassRepresentative);
+        deviceType.setOrdering(structureElementCommand.getOrdering());
+        deviceType.setDescription(structureElementCommand.getDescription());
+        deviceTypeRepository.updateDeviceType(deviceType);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, deviceType);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<DeviceType> previouses = iDeviceTypeRepository.findPreviousByUuidAndId(deviceType.getUuid().toString(), deviceType.getId());
-        DeviceType previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DEVICETYPE.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        DeviceType previous = new DeviceType(previousAuditStructure);
 
         // additional
-        namesService.updateNames(previous, deviceType, username);
+        namesService.updateNames(previous, deviceType, username, holderStructures);
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
 
@@ -162,49 +164,38 @@ public class DeviceTypeService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username, HolderStructures holderStructures) {
+    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, deleted
+        //     delete structure (update)
+        //     create audit
         //     previous for notification
-        //     additional - delete related names
+        //     additional
+        //         delete related names
         //     return
         //         structure element for deleted structure
         //         notification
-        //
-        // attributes
-        //     uuid
 
         String uuid = structureElementCommand.getUuid().toString();
 
-        // find
-        List<DeviceType> deviceTypes = deviceTypeRepository.readDeviceTypes(Boolean.FALSE, uuid, null, null, null, null, null, null);
-        DeviceType deviceType = null;
-        if (ValidateUtil.isSize(deviceTypes, 1)) {
-            deviceType = deviceTypes.get(0);
-
-            // update not latest
-            deviceType.setLatest(Boolean.FALSE);
-            deviceTypeRepository.updateDeviceType(deviceType);
-        } else {
-            return null;
-        }
-
-        // create
-        deviceType = new DeviceType(deviceType.getUuid(), deviceType.getParentUuid(),
-                deviceType.getMnemonic(), deviceType.getMnemonicEquivalence(), deviceType.getOrdering(),
-                deviceType.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.TRUE,
-                when, username, null);
-        deviceTypeRepository.createDeviceType(deviceType);
+        // delete structure
+        // create audit
+        DeviceType deviceType = iDeviceTypeRepository.findByUuid(uuid);
+        deviceType.setDeleted(Boolean.TRUE);
+        deviceType.setAttributesProcessed(when, username, null);
+        deviceTypeRepository.updateDeviceType(deviceType);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, deviceType);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<DeviceType> previouses = iDeviceTypeRepository.findPreviousByUuidAndId(uuid, deviceType.getId());
-        DeviceType previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DEVICETYPE.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        DeviceType previous = new DeviceType(previousAuditStructure);
 
         // additional
-        namesService.deleteNames(deviceType, username);
+        namesService.deleteNames(deviceType, username, holderStructures);
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.COMMAND, StructureCommand.DELETE));
 
diff --git a/src/main/java/org/openepics/names/service/DisciplineService.java b/src/main/java/org/openepics/names/service/DisciplineService.java
index 052d298754218aed0912ad63f5d78f59a26bb467..ab1786823b1056e5ee2ac9e811c3f65dd4c9e1d6 100644
--- a/src/main/java/org/openepics/names/service/DisciplineService.java
+++ b/src/main/java/org/openepics/names/service/DisciplineService.java
@@ -26,11 +26,14 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.DisciplineRepository;
+import org.openepics.names.repository.IAuditStructureRepository;
 import org.openepics.names.repository.IDeviceGroupRepository;
 import org.openepics.names.repository.IDisciplineRepository;
+import org.openepics.names.repository.model.AuditStructure;
 import org.openepics.names.repository.model.DeviceGroup;
 import org.openepics.names.repository.model.Discipline;
+import org.openepics.names.repository.AuditStructureRepository;
+import org.openepics.names.repository.DisciplineRepository;
 import org.openepics.names.rest.beans.Status;
 import org.openepics.names.rest.beans.Type;
 import org.openepics.names.rest.beans.element.StructureElementCommand;
@@ -40,8 +43,8 @@ import org.openepics.names.util.StructureChoice;
 import org.openepics.names.util.StructureCommand;
 import org.openepics.names.util.StructureElementUtil;
 import org.openepics.names.util.TextUtil;
-import org.openepics.names.util.ValidateUtil;
 import org.openepics.names.util.notification.NotificationUtil;
+import org.openepics.names.util.notification.StructureElementNotification;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -59,53 +62,58 @@ public class DisciplineService {
 
     private static final Logger LOGGER = Logger.getLogger(DisciplineService.class.getName());
 
-    private IDisciplineRepository iDisciplineRepository;
+    private NamesService namesService;
+    private DeviceGroupService deviceGroupService;
     private IDeviceGroupRepository iDeviceGroupRepository;
+    private IDisciplineRepository iDisciplineRepository;
+    private IAuditStructureRepository iAuditStructureRepository;
     private DisciplineRepository disciplineRepository;
-    private DeviceGroupService deviceGroupService;
-    private NamesService namesService;
+    private AuditStructureRepository auditStructureRepository;
 
     @Autowired
     public DisciplineService(
-            IDisciplineRepository iDisciplineRepository,
+            NamesService namesService,
+            DeviceGroupService deviceGroupService,
             IDeviceGroupRepository iDeviceGroupRepository,
+            IDisciplineRepository iDisciplineRepository,
+            IAuditStructureRepository iAuditStructureRepository,
             DisciplineRepository disciplineRepository,
-            DeviceGroupService deviceGroupService,
-            NamesService namesService) {
-        this.iDisciplineRepository = iDisciplineRepository;
+            AuditStructureRepository auditStructureRepository) {
+        this.namesService = namesService;
+        this.deviceGroupService = deviceGroupService;
         this.iDeviceGroupRepository = iDeviceGroupRepository;
+        this.iDisciplineRepository = iDisciplineRepository;
+        this.iAuditStructureRepository = iAuditStructureRepository;
         this.disciplineRepository = disciplineRepository;
-        this.deviceGroupService = deviceGroupService;
-        this.namesService = namesService;
+        this.auditStructureRepository = auditStructureRepository;
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     create structure - approved, latest, not deleted
+        //     create structure
+        //     create audit
         //     return
         //         structure element for created structure
         //         notification
-        //
-        // attributes
-        //     type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
+        UUID uuid = UUID.randomUUID();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // create
-        Discipline discipline = new Discipline(UUID.randomUUID(),
+        // create structure
+        // create audit
+        Discipline discipline = new Discipline(uuid,
                 mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
+                structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
                 when, username, null);
         disciplineRepository.createDiscipline(discipline);
+        auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, discipline));
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
 
@@ -115,54 +123,43 @@ public class DisciplineService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, not deleted
+        //     update structure
+        //     create audit
         //     previous for notification
-        //     additional - update related names
+        //     additional
+        //         update related names
         //     return
         //         structure element for updated structure
         //         notification
-        //
-        // attributes
-        //     uuid, type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
         String uuid = structureElementCommand.getUuid().toString();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // find
-        List<Discipline> disciplines = disciplineRepository.readDisciplines(Boolean.FALSE, uuid, null, null, null, null, null);
-        Discipline discipline = null;
-        if (ValidateUtil.isSize(disciplines, 1)) {
-            discipline = disciplines.get(0);
-
-            // update not latest
-            discipline.setLatest(Boolean.FALSE);
-            disciplineRepository.updateDiscipline(discipline);
-        }
-
-        // create
-        discipline = new Discipline(structureElementCommand.getUuid(),
-                mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
-                when, username, null);
-        disciplineRepository.createDiscipline(discipline);
+        // update structure
+        // create audit
+        Discipline discipline = iDisciplineRepository.findByUuid(uuid);
+        discipline.setMnemonic(mnemonic);
+        discipline.setMnemonicEquivalence(equivalenceClassRepresentative);
+        discipline.setOrdering(structureElementCommand.getOrdering());
+        discipline.setDescription(structureElementCommand.getDescription());
+        disciplineRepository.updateDiscipline(discipline);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, discipline);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<Discipline> previouses = iDisciplineRepository.findPreviousByUuidAndId(discipline.getUuid().toString(), discipline.getId());
-        Discipline previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DISCIPLINE.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        Discipline previous = new Discipline(previousAuditStructure);
 
         // additional
-        namesService.updateNames(previous, discipline, username);
+        namesService.updateNames(previous, discipline, username, holderStructures);
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
 
@@ -172,53 +169,43 @@ public class DisciplineService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username, HolderStructures holderStructures) {
+    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, deleted
+        //     delete structure (update)
+        //     create audit
         //     previous for notification
-        //     additional - delete related names, delete sub structures (and related names)
+        //     additional
+        //         delete related names
+        //         delete sub structures (and related names)
         //     return
         //         structure element for deleted structure
         //         notification
-        //
-        // attributes
-        //     uuid
 
         String uuid = structureElementCommand.getUuid().toString();
 
-        // find
-        List<Discipline> disciplines = disciplineRepository.readDisciplines(Boolean.FALSE, uuid, null, null, null, null, null);
-        Discipline discipline = null;
-        if (ValidateUtil.isSize(disciplines, 1)) {
-            discipline = disciplines.get(0);
-
-            // update not latest
-            discipline.setLatest(Boolean.FALSE);
-            disciplineRepository.updateDiscipline(discipline);
-        } else {
-            return null;
-        }
-
-        // create
-        discipline = new Discipline(discipline.getUuid(),
-                discipline.getMnemonic(), discipline.getMnemonicEquivalence(), discipline.getOrdering(),
-                discipline.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.TRUE,
-                when, username, null);
-        disciplineRepository.createDiscipline(discipline);
+        // delete structure
+        // create audit
+        Discipline discipline = iDisciplineRepository.findByUuid(uuid);
+        discipline.setDeleted(Boolean.TRUE);
+        discipline.setAttributesProcessed(when, username, null);
+        disciplineRepository.updateDiscipline(discipline);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, discipline);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<Discipline> previouses = iDisciplineRepository.findPreviousByUuidAndId(uuid, discipline.getId());
-        Discipline previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.DISCIPLINE.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        Discipline previous = new Discipline(previousAuditStructure);
 
         // additional
         //     will propagate to sub structures
-        namesService.deleteNames(discipline, username);
+        namesService.deleteNames(discipline, username, holderStructures);
 
         List<StructureElementCommand> commands = Lists.newArrayList();
-        List<DeviceGroup> deviceGroups = iDeviceGroupRepository.findLatestNotDeletedByParent(uuid);
+        List<DeviceGroup> deviceGroups = iDeviceGroupRepository.findNotDeletedByParent(discipline.getId());
         for (DeviceGroup deviceGroup : deviceGroups) {
             commands.add(new StructureElementCommand(deviceGroup.getUuid(), Type.DEVICEGROUP, null, null, null, null));
         }
diff --git a/src/main/java/org/openepics/names/service/MetricsService.java b/src/main/java/org/openepics/names/service/MetricsService.java
index 104de407be7f689e8da1160db85e2c0c306e336d..009c23f73265ed8143dd29a3b1c17361f5cad174 100644
--- a/src/main/java/org/openepics/names/service/MetricsService.java
+++ b/src/main/java/org/openepics/names/service/MetricsService.java
@@ -18,6 +18,8 @@
 
 package org.openepics.names.service;
 
+import org.openepics.names.repository.AuditNameRepository;
+import org.openepics.names.repository.AuditStructureRepository;
 import org.openepics.names.repository.DeviceGroupRepository;
 import org.openepics.names.repository.DeviceTypeRepository;
 import org.openepics.names.repository.DisciplineRepository;
@@ -64,7 +66,9 @@ public class MetricsService {
             SubsystemRepository subsystemRepository,
             DisciplineRepository disciplineRepository,
             DeviceGroupRepository deviceGroupRepository,
-            DeviceTypeRepository deviceTypeRepository) {
+            DeviceTypeRepository deviceTypeRepository,
+            AuditNameRepository auditNameRepository,
+            AuditStructureRepository auditStructureRepository) {
         this.holderRepositories = new HolderRepositories(
                 nameRepository,
                 systemGroupRepository,
@@ -72,7 +76,9 @@ public class MetricsService {
                 subsystemRepository,
                 disciplineRepository,
                 deviceGroupRepository,
-                deviceTypeRepository);
+                deviceTypeRepository,
+                auditNameRepository,
+                auditStructureRepository);
         registerGaugeMetrics(meterRegistry);
     }
 
@@ -85,17 +91,17 @@ public class MetricsService {
         //     deleted
 
         Gauge.builder(METRICS_NAME[0],
-                () -> holderRepositories.nameRepository().countNamesHistory(null, null, null, null, null, null, null, null))
+                () -> holderRepositories.auditNameRepository().countAuditNames(null))
                 .description(METRICS_NAME[1])
                 .tag(STATUS, STATUS_METRICS[0])
                 .register(meterRegistry);
         Gauge.builder(METRICS_NAME[0],
-                () -> holderRepositories.nameRepository().countNames(Boolean.FALSE, null, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.nameRepository().countNames(Boolean.FALSE, null, null, null, null, null, null, null, null))
                 .description(METRICS_NAME[1])
                 .tag(STATUS, STATUS_METRICS[1])
                 .register(meterRegistry);
         Gauge.builder(METRICS_NAME[0],
-                () -> holderRepositories.nameRepository().countNames(Boolean.TRUE, null, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.nameRepository().countNames(Boolean.TRUE, null, null, null, null, null, null, null, null))
                 .description(METRICS_NAME[1])
                 .tag(STATUS, STATUS_METRICS[2])
                 .register(meterRegistry);
@@ -106,114 +112,114 @@ public class MetricsService {
         //     deleted
 
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.systemGroupRepository().countSystemGroupsHistory(null, null, null, null, null, null))
+                () -> holderRepositories.auditStructureRepository().countAuditStructures(Type.SYSTEMGROUP, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.SYSTEMGROUP.toString())
                 .tag(STATUS, STATUS_METRICS[0])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.systemGroupRepository().countSystemGroups(Boolean.FALSE, null, null, null, null, null, null, null))
+                () -> holderRepositories.systemGroupRepository().countSystemGroups(Boolean.FALSE, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.SYSTEMGROUP.toString())
                 .tag(STATUS, STATUS_METRICS[1])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.systemGroupRepository().countSystemGroups(Boolean.TRUE, null, null, null, null, null, null, null))
+                () -> holderRepositories.systemGroupRepository().countSystemGroups(Boolean.TRUE, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.SYSTEMGROUP.toString())
                 .tag(STATUS, STATUS_METRICS[2])
                 .register(meterRegistry);
 
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.systemRepository().countSystemsHistory(null, null, null, null, null, null, null))
+                () -> holderRepositories.auditStructureRepository().countAuditStructures(Type.SYSTEM, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.SYSTEM.toString())
                 .tag(STATUS, STATUS_METRICS[0])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.systemRepository().countSystems(Boolean.FALSE, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.systemRepository().countSystems(Boolean.FALSE, null, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.SYSTEM.toString())
                 .tag(STATUS, STATUS_METRICS[1])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.systemRepository().countSystems(Boolean.TRUE, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.systemRepository().countSystems(Boolean.TRUE, null, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.SYSTEM.toString())
                 .tag(STATUS, STATUS_METRICS[2])
                 .register(meterRegistry);
 
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.subsystemRepository().countSubsystemsHistory(null, null, null, null, null, null, null))
+                () -> holderRepositories.auditStructureRepository().countAuditStructures(Type.SUBSYSTEM, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.SUBSYSTEM.toString())
                 .tag(STATUS, STATUS_METRICS[0])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.subsystemRepository().countSubsystems(Boolean.FALSE, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.subsystemRepository().countSubsystems(Boolean.FALSE, null, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.SUBSYSTEM.toString())
                 .tag(STATUS, STATUS_METRICS[1])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.subsystemRepository().countSubsystems(Boolean.TRUE, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.subsystemRepository().countSubsystems(Boolean.TRUE, null, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.SUBSYSTEM.toString())
                 .tag(STATUS, STATUS_METRICS[2])
                 .register(meterRegistry);
 
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.disciplineRepository().countDisciplinesHistory(null, null, null, null, null, null))
+                () -> holderRepositories.auditStructureRepository().countAuditStructures(Type.DISCIPLINE, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.DISCIPLINE.toString())
                 .tag(STATUS, STATUS_METRICS[0])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.disciplineRepository().countDisciplines(Boolean.FALSE, null, null, null, null, null, null, null))
+                () -> holderRepositories.disciplineRepository().countDisciplines(Boolean.FALSE, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.DISCIPLINE.toString())
                 .tag(STATUS, STATUS_METRICS[1])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.disciplineRepository().countDisciplines(Boolean.TRUE, null, null, null, null, null, null, null))
+                () -> holderRepositories.disciplineRepository().countDisciplines(Boolean.TRUE, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.DISCIPLINE.toString())
                 .tag(STATUS, STATUS_METRICS[2])
                 .register(meterRegistry);
 
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.deviceGroupRepository().countDeviceGroupsHistory(null, null, null, null, null, null, null))
+                () -> holderRepositories.auditStructureRepository().countAuditStructures(Type.DEVICEGROUP, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.DEVICEGROUP.toString())
                 .tag(STATUS, STATUS_METRICS[0])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.deviceGroupRepository().countDeviceGroups(Boolean.FALSE, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.deviceGroupRepository().countDeviceGroups(Boolean.FALSE, null, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.DEVICEGROUP.toString())
                 .tag(STATUS, STATUS_METRICS[1])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.deviceGroupRepository().countDeviceGroups(Boolean.TRUE, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.deviceGroupRepository().countDeviceGroups(Boolean.TRUE, null, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.DEVICEGROUP.toString())
                 .tag(STATUS, STATUS_METRICS[2])
                 .register(meterRegistry);
 
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.deviceTypeRepository().countDeviceTypesHistory(null, null, null, null, null, null, null))
+                () -> holderRepositories.auditStructureRepository().countAuditStructures(Type.DEVICETYPE, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.DEVICETYPE.toString())
                 .tag(STATUS, STATUS_METRICS[0])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.deviceTypeRepository().countDeviceTypes(Boolean.FALSE, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.deviceTypeRepository().countDeviceTypes(Boolean.FALSE, null, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.DEVICETYPE.toString())
                 .tag(STATUS, STATUS_METRICS[1])
                 .register(meterRegistry);
         Gauge.builder(METRICS_STRUCTURE[0],
-                () -> holderRepositories.deviceTypeRepository().countDeviceTypes(Boolean.TRUE, null, null, null, null, null, null, null, null))
+                () -> holderRepositories.deviceTypeRepository().countDeviceTypes(Boolean.TRUE, null, null, null, null, null, null, null))
                 .description(METRICS_STRUCTURE[1])
                 .tag(TYPE, Type.DEVICETYPE.toString())
                 .tag(STATUS, STATUS_METRICS[2])
diff --git a/src/main/java/org/openepics/names/service/NamesService.java b/src/main/java/org/openepics/names/service/NamesService.java
index c7699eeb7d815ab7a2de3759a16521a0562eec97..ef068cf615353618270e582eb8dc5f022dc455d7 100644
--- a/src/main/java/org/openepics/names/service/NamesService.java
+++ b/src/main/java/org/openepics/names/service/NamesService.java
@@ -26,9 +26,8 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.DeviceGroupRepository;
-import org.openepics.names.repository.DeviceTypeRepository;
-import org.openepics.names.repository.DisciplineRepository;
+import org.openepics.names.repository.IAuditNameRepository;
+import org.openepics.names.repository.IAuditStructureRepository;
 import org.openepics.names.repository.IDeviceGroupRepository;
 import org.openepics.names.repository.IDeviceTypeRepository;
 import org.openepics.names.repository.IDisciplineRepository;
@@ -36,10 +35,16 @@ import org.openepics.names.repository.INameRepository;
 import org.openepics.names.repository.ISubsystemRepository;
 import org.openepics.names.repository.ISystemGroupRepository;
 import org.openepics.names.repository.ISystemRepository;
+import org.openepics.names.repository.AuditNameRepository;
+import org.openepics.names.repository.AuditStructureRepository;
+import org.openepics.names.repository.DeviceGroupRepository;
+import org.openepics.names.repository.DeviceTypeRepository;
+import org.openepics.names.repository.DisciplineRepository;
 import org.openepics.names.repository.NameRepository;
 import org.openepics.names.repository.SubsystemRepository;
 import org.openepics.names.repository.SystemGroupRepository;
 import org.openepics.names.repository.SystemRepository;
+import org.openepics.names.repository.model.AuditName;
 import org.openepics.names.repository.model.DeviceType;
 import org.openepics.names.repository.model.Discipline;
 import org.openepics.names.repository.model.Name;
@@ -76,15 +81,12 @@ import com.google.common.collect.Lists;
 public class NamesService {
 
     // note
+    //     default
+    //         active means valid not deleted
+    //         obsolete values are not shown unless history is requested
     //     handling of system structure, device structure
-    //         parent system structure uuid (system group, system, subsystem) - ability to find structure
+    //         parent system structure uuid (system group, system, subsystem)
     //         parent device structure uuid (device type)
-    //     holder
-    //         HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return
-    //     latest
-    //         automatically not show names that do not come into play
-    //         = automatically exclude (approved and not latest)
-    //         otherwise refer to history
     //     namecommand
     //         cud - create update delete
 
@@ -93,8 +95,6 @@ public class NamesService {
     private EssNamingConvention namingConvention;
     private HolderIRepositories holderIRepositories;
     private HolderRepositories holderRepositories;
-    // convenience, also part of holderRepositories
-    private NameRepository nameRepository;
 
     @Autowired
     public NamesService(
@@ -105,13 +105,17 @@ public class NamesService {
             IDisciplineRepository iDisciplineRepository,
             IDeviceGroupRepository iDeviceGroupRepository,
             IDeviceTypeRepository iDeviceTypeRepository,
+            IAuditNameRepository iAuditNameRepository,
+            IAuditStructureRepository iAuditStructureRepository,
             NameRepository nameRepository,
             SystemGroupRepository systemGroupRepository,
             SystemRepository systemRepository,
             SubsystemRepository subsystemRepository,
             DisciplineRepository disciplineRepository,
             DeviceGroupRepository deviceGroupRepository,
-            DeviceTypeRepository deviceTypeRepository) {
+            DeviceTypeRepository deviceTypeRepository,
+            AuditNameRepository auditNameRepository,
+            AuditStructureRepository auditStructureRepository) {
 
         this.namingConvention = new EssNamingConvention();
         this.holderIRepositories = new HolderIRepositories(
@@ -121,7 +125,9 @@ public class NamesService {
                 iSubsystemRepository,
                 iDisciplineRepository,
                 iDeviceGroupRepository,
-                iDeviceTypeRepository);
+                iDeviceTypeRepository,
+                iAuditNameRepository,
+                iAuditStructureRepository);
         this.holderRepositories = new HolderRepositories(
                 nameRepository,
                 systemGroupRepository,
@@ -129,8 +135,9 @@ public class NamesService {
                 subsystemRepository,
                 disciplineRepository,
                 deviceGroupRepository,
-                deviceTypeRepository);
-        this.nameRepository = nameRepository;
+                deviceTypeRepository,
+                auditNameRepository,
+                auditStructureRepository);
     }
 
     @Transactional
@@ -138,12 +145,12 @@ public class NamesService {
         // validation outside method
         // transaction
         //     for each name element
-        //         create name, latest, with data
+        //         create name
         //         handle name element for created name
         //     no notify
         //     return name elements for created names
 
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         Date when = new Date();
@@ -166,35 +173,37 @@ public class NamesService {
                         createdNameElements.size()));
         return createdNameElements;
     }
+
     @Transactional(propagation = Propagation.MANDATORY)
     public NameElement createName(NameElementCommand nameElementCommand, Date when, String username, HolderStructures holderStructures) {
+        return createName(nameElementCommand, when, username, holderStructures, null);
+    }
+    @Transactional(propagation = Propagation.MANDATORY)
+    public NameElement createName(NameElementCommand nameElementCommand, Date when, String username, HolderStructures holderStructures, Structure structure) {
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     attributes
-        //     find
-        //     prepare
-        //     create - approved, latest, not deleted, uuid
+        //     find & prepare
+        //     create name
+        //     create audit
         //     return name element for created name
-        //
-        // attributes
-        //     parentSystemStructure, parentDeviceStructure, index, description
 
+        UUID uuid = UUID.randomUUID();
         UUID parentSystemStructure = nameElementCommand.getParentSystemStructure();
         UUID parentDeviceStructure = nameElementCommand.getParentDeviceStructure();
         String index = nameElementCommand.getIndex();
         String description = nameElementCommand.getDescription();
         String comment = null;
 
-        // find
+        // find & prepare
         //     system structure - system group, system, subsystem - one of the three expected to be non-null, other two expected to be null
         //     device structure - device type - may be null
-        SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(parentSystemStructure.toString());
-        System      system      = holderIRepositories.systemRepository().findLatestByUuid(parentSystemStructure.toString());
-        Subsystem   subsystem   = holderIRepositories.subsystemRepository().findLatestByUuid(parentSystemStructure.toString());
-        DeviceType  deviceType  = null;
+        SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findByUuid(parentSystemStructure.toString());
+        System system = holderIRepositories.systemRepository().findByUuid(parentSystemStructure.toString());
+        Subsystem subsystem = holderIRepositories.subsystemRepository().findByUuid(parentSystemStructure.toString());
+        DeviceType deviceType = null;
         if (parentDeviceStructure != null) {
-            deviceType = holderIRepositories.deviceTypeRepository().findLatestByUuid(parentDeviceStructure.toString());
+            deviceType = holderIRepositories.deviceTypeRepository().findByUuid(parentDeviceStructure.toString());
         }
 
         String derivedName = null;
@@ -206,18 +215,20 @@ public class NamesService {
             derivedName = NameUtil.getName(subsystem, deviceType, index, holderStructures);
         }
 
-        // create
-        Name name = new Name(UUID.randomUUID(),
-                systemGroup != null ? systemGroup.getUuid() : null,
-                system != null ? system.getUuid() : null,
-                subsystem != null ? subsystem.getUuid() : null,
-                parentDeviceStructure,
+        // create name
+        // create audit
+        Name name = new Name(uuid,
+                systemGroup != null ? systemGroup.getId() : null,
+                system != null ? system.getId() : null,
+                subsystem != null ? subsystem.getId() : null,
+                deviceType != null ? deviceType.getId() : null,
                 index, derivedName, namingConvention.equivalenceClassRepresentative(derivedName), description,
-                Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
+                Status.APPROVED, Boolean.FALSE,
                 when, username, comment);
-        nameRepository.createName(name);
+        holderRepositories.nameRepository().createName(name);
+        holderRepositories.auditNameRepository().createAuditName(new AuditName(TextUtil.CREATE, name));
 
-        return NameElementUtil.getNameElement(name);
+        return NameElementUtil.getNameElement(name, holderStructures, structure);
     }
 
     // ----------------------------------------------------------------------------------------------------
@@ -253,20 +264,24 @@ public class NamesService {
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_NAMES, "limit", limit));
         }
 
-        List<Name> names = null;
-        Long totalCount = null;
-        if (Boolean.TRUE.equals(includeHistory)) {
-            names = nameRepository.readNamesHistory(uuid, name, null, systemStructure, deviceStructure, index, description, who, orderBy, isAsc, offset, limit);
-            totalCount = nameRepository.countNamesHistory(uuid, name, null, systemStructure, deviceStructure, index, description, who);
-        } else {
-            names = nameRepository.readNames(deleted, uuid, name, null, systemStructure, deviceStructure, index, description, who, includeHistory, orderBy, isAsc, offset, limit);
-            totalCount = nameRepository.countNames(deleted, uuid, name, null, systemStructure, deviceStructure, index, description, who, includeHistory);
-        }
+        // holder of valid content for system and device structures
+        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         // one name entry will give one name element
         //     history does not affect totalCount, sorting, pagination
+        List<NameElement> nameElements = null;
+        Long totalCount = null;
+        if (Boolean.TRUE.equals(includeHistory)) {
+            List<AuditName> auditNames = holderRepositories.auditNameRepository().readAuditNames(uuid, offset, limit);
+            totalCount = holderRepositories.auditNameRepository().countAuditNames(uuid);
 
-        final List<NameElement> nameElements = NameElementUtil.getNameElements(names);
+            nameElements = NameElementUtil.getNameElementsForAuditNames(auditNames, holderStructures);
+        } else {
+            List<Name> names = holderRepositories.nameRepository().readNames(deleted, uuid, name, null, systemStructure, deviceStructure, index, description, who, orderBy, isAsc, offset, limit);
+            totalCount = holderRepositories.nameRepository().countNames(deleted, uuid, name, null, systemStructure, deviceStructure, index, description, who);
+
+            nameElements = NameElementUtil.getNameElements(names, holderStructures);
+        }
 
         ResponsePageNameElements response = new ResponsePageNameElements(nameElements, totalCount, nameElements.size(), offset, limit);
         LOGGER.log(Level.FINE,
@@ -327,23 +342,25 @@ public class NamesService {
         //     consider multiplicity if search for both system structure uuid and device structure uuid
 
         List<Name> names = Lists.newArrayList();
-
         // directly
-        names.addAll(holderRepositories.nameRepository().readNamesLatestByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEMGROUP, uuid, deleted, orderBy, isAsc));
-        names.addAll(holderRepositories.nameRepository().readNamesLatestByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEM, uuid, deleted, orderBy, isAsc));
-        names.addAll(holderRepositories.nameRepository().readNamesLatestByStructure(NameRepository.NameByStructure.NAME_BY_SUBSYSTEM, uuid, deleted, orderBy, isAsc));
-        names.addAll(holderRepositories.nameRepository().readNamesLatestByStructure(NameRepository.NameByStructure.NAME_BY_DEVICETYPE, uuid, deleted, orderBy, isAsc));
+        names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEMGROUP, uuid, deleted, orderBy, isAsc));
+        names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEM, uuid, deleted, orderBy, isAsc));
+        names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SUBSYSTEM, uuid, deleted, orderBy, isAsc));
+        names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_DEVICETYPE, uuid, deleted, orderBy, isAsc));
 
         // indirectly
-        names.addAll(holderRepositories.nameRepository().readNamesLatestByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEMGROUP_THROUGH_SYSTEM, uuid, deleted, orderBy, isAsc));
-        names.addAll(holderRepositories.nameRepository().readNamesLatestByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEMGROUP_THROUGH_SUBSYSTEM, uuid, deleted, orderBy, isAsc));
-        names.addAll(holderRepositories.nameRepository().readNamesLatestByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEM_THROUGH_SUBSYSTEM, uuid, deleted, orderBy, isAsc));
-        names.addAll(holderRepositories.nameRepository().readNamesLatestByStructure(NameRepository.NameByStructure.NAME_BY_DISCIPLINE_THROUGH_DEVICETYPE, uuid, deleted, orderBy, isAsc));
-        names.addAll(holderRepositories.nameRepository().readNamesLatestByStructure(NameRepository.NameByStructure.NAME_BY_DEVICEGROUP_THROUGH_DEVICETYPE, uuid, deleted, orderBy, isAsc));
+        names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEMGROUP_THROUGH_SYSTEM, uuid, deleted, orderBy, isAsc));
+        names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEMGROUP_THROUGH_SUBSYSTEM, uuid, deleted, orderBy, isAsc));
+        names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_SYSTEM_THROUGH_SUBSYSTEM, uuid, deleted, orderBy, isAsc));
+        names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_DISCIPLINE_THROUGH_DEVICETYPE, uuid, deleted, orderBy, isAsc));
+        names.addAll(holderRepositories.nameRepository().readNamesByStructure(NameRepository.NameByStructure.NAME_BY_DEVICEGROUP_THROUGH_DEVICETYPE, uuid, deleted, orderBy, isAsc));
+
+        // holder of valid content for system and device structures
+        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         // pagination
         Long totalCount = Long.valueOf(names.size());
-        final List<NameElement> nameElements = paginate(NameElementUtil.getNameElements(names), offset, limit);
+        final List<NameElement> nameElements = paginate(NameElementUtil.getNameElements(names, holderStructures), offset, limit);
         ResponsePageNameElements response = new ResponsePageNameElements(nameElements, totalCount, nameElements.size(), offset, limit);
 
         LOGGER.log(Level.FINE,
@@ -392,7 +409,7 @@ public class NamesService {
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.EXISTS_NAME, "name", name));
 
-        List<Name> names = nameRepository.readNames(false,
+        List<Name> names = holderRepositories.nameRepository().readNames(false,
                 null, name, null, null, null, null, null, null);
         return !names.isEmpty();
     }
@@ -403,7 +420,7 @@ public class NamesService {
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.IS_VALID_TO_CREATE_NAME, "name", name));
 
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         //     note false to not include deleted entries
         HolderStructures holderStructures = new HolderStructures(holderIRepositories, false);
 
@@ -419,17 +436,15 @@ public class NamesService {
     }
     public void validateNamesCreate(NameElementCommand nameElement, HolderStructures holderStructures) {
         // validate name element
-        //     input
-        //         input itself
-        //     data
-        //         data itself
-        //         relative other data
+        //     input vs given task
+        //     data  vs given task
 
         ValidateNameElementUtil.validateNameElementInputCreate(nameElement);
-        ValidateNameElementUtil.validateNameElementDataCreate(nameElement, namingConvention, holderIRepositories, nameRepository, holderStructures);
+        ValidateNameElementUtil.validateNameElementDataCreate(nameElement, namingConvention,
+                holderIRepositories, holderRepositories, holderStructures);
     }
     public void validateNamesCreate(List<NameElementCommand> nameElements) {
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         for (NameElementCommand nameElement : nameElements) {
@@ -442,17 +457,15 @@ public class NamesService {
     }
     public void validateNamesUpdate(NameElementCommand nameElement, HolderStructures holderStructures) {
         // validate name element
-        //     input
-        //         input itself
-        //     data
-        //         data itself
-        //         relative other data
+        //     input vs given task
+        //     data  vs given task
 
         ValidateNameElementUtil.validateNameElementInputUpdate(nameElement);
-        ValidateNameElementUtil.validateNameElementDataUpdate(nameElement, namingConvention, holderIRepositories, nameRepository, holderStructures);
+        ValidateNameElementUtil.validateNameElementDataUpdate(nameElement, namingConvention,
+                holderIRepositories, holderRepositories, holderStructures);
     }
     public void validateNamesUpdate(List<NameElementCommand> nameElements) {
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         for (NameElementCommand nameElement : nameElements) {
@@ -465,17 +478,15 @@ public class NamesService {
     }
     public void validateNamesDelete(NameElementCommand nameElement, HolderStructures holderStructures) {
         // validate name element
-        //     input
-        //         input itself
-        //     data
-        //         data itself
-        //         relative other data
+        //     input vs given task
+        //     data  vs given task
 
         ValidateNameElementUtil.validateNameElementInputDelete(nameElement);
-        ValidateNameElementUtil.validateNameElementDataDelete(nameElement, namingConvention, holderIRepositories, nameRepository, holderStructures);
+        ValidateNameElementUtil.validateNameElementDataDelete(nameElement, namingConvention,
+                holderIRepositories, holderRepositories, holderStructures);
     }
     public void validateNamesDelete(List<NameElementCommand> nameElements) {
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         for (NameElementCommand nameElement : nameElements) {
@@ -490,27 +501,19 @@ public class NamesService {
         // validation outside method
         // transaction
         //     for each name element
-        //         attributes
-        //         find
-        //         update name to not latest
-        //         find
-        //         insert name to latest, not deleted, with data
+        //         find & prepare
+        //         update name
+        //         create audit
         //         handle name element for updated name
         //     no notify
         //     return name elements for updated names
-        //
-        // attributes
-        //     uuid, parentSystemStructure, parentDeviceStructure, index, description
 
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         Date when = new Date();
         final List<NameElement> updatedNameElements = Lists.newArrayList();
         for (NameElementCommand nameElementCommand : nameElementCommands) {
-            // update not latest, not deleted
-            // create latest, not deleted
-
             UUID uuid = nameElementCommand.getUuid();
             UUID parentSystemStructure = nameElementCommand.getParentSystemStructure();
             UUID parentDeviceStructure = nameElementCommand.getParentDeviceStructure();
@@ -518,29 +521,15 @@ public class NamesService {
             String description = nameElementCommand.getDescription();
             String comment = null;
 
-            Name name = holderIRepositories.nameRepository().findLatestByUuid(uuid.toString());
-            if (name == null) {
-                continue;
-            }
-
-            // skip if name element has same content as name
-            //     proceed without fail
-            if (NameElementUtil.hasSameContent(nameElementCommand, name, holderIRepositories, holderStructures)) {
-                continue;
-            }
-
-            // update
-            name.setLatest(Boolean.FALSE);
-            nameRepository.updateName(name);
-
-            // find out system group, system, subsystem
-            //     one of the three expected to be non-null, other two expected to be null
-            SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(parentSystemStructure.toString());
-            System      system      = holderIRepositories.systemRepository().findLatestByUuid(parentSystemStructure.toString());
-            Subsystem   subsystem   = holderIRepositories.subsystemRepository().findLatestByUuid(parentSystemStructure.toString());
-            DeviceType  deviceType  = null;
+            // find & prepare
+            //     system structure - system group, system, subsystem - one of the three expected to be non-null, other two expected to be null
+            //     device structure - device type - may be null
+            SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findByUuid(parentSystemStructure.toString());
+            System system = holderIRepositories.systemRepository().findByUuid(parentSystemStructure.toString());
+            Subsystem subsystem = holderIRepositories.subsystemRepository().findByUuid(parentSystemStructure.toString());
+            DeviceType deviceType = null;
             if (parentDeviceStructure != null) {
-                deviceType  = holderIRepositories.deviceTypeRepository().findLatestByUuid(parentDeviceStructure.toString());
+                deviceType = holderIRepositories.deviceTypeRepository().findByUuid(parentDeviceStructure.toString());
             }
 
             String derivedName = null;
@@ -552,18 +541,26 @@ public class NamesService {
                 derivedName = NameUtil.getName(subsystem, deviceType, index, holderStructures);
             }
 
-            // create
-            name = new Name(uuid,
-                    systemGroup != null ? systemGroup.getUuid() : null,
-                    system != null ? system.getUuid() : null,
-                    subsystem != null ? subsystem.getUuid() : null,
-                    parentDeviceStructure,
-                    index, derivedName, namingConvention.equivalenceClassRepresentative(derivedName), description,
-                    Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
-                    when, username, comment);
-            nameRepository.createName(name);
-
-            NameElement updatedNameElement = NameElementUtil.getNameElement(name);
+            // update name
+            // create audit
+            Name name = holderIRepositories.nameRepository().findByUuid(uuid.toString());
+            if (name == null) {
+                continue;
+            }
+            // skip if name element has same content as name
+            //     proceed without fail
+            if (NameElementUtil.hasSameContent(nameElementCommand, name, holderIRepositories, holderStructures)) {
+                continue;
+            }
+            name.setInstanceIndex(index);
+            name.setConventionName(derivedName);
+            name.setConventionNameEquivalence(namingConvention.equivalenceClassRepresentative(derivedName));
+            name.setDescription(description);
+            name.setAttributesRequested(when, username, comment);
+            holderRepositories.nameRepository().updateName(name);
+            holderRepositories.auditNameRepository().createAuditName(new AuditName(TextUtil.UPDATE, name));
+
+            NameElement updatedNameElement = NameElementUtil.getNameElement(name, holderStructures);
             updatedNameElements.add(updatedNameElement);
 
             if (LOGGER.isLoggable(Level.FINER)) {
@@ -582,15 +579,13 @@ public class NamesService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public List<NameElement> updateNames(Structure previousStructure, Structure structure, String username) {
+    public List<NameElement> updateNames(Structure previousStructure, Structure structure, String username, HolderStructures holderStructures) {
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     find out names referenced by structure
-        //         not for device group
-        //         sg, sys, sys-sub, sg:di-dt-idx, sys:di-dt-idx, sys-sub:di-dt-idx
+        //     find out names referenced by structure - not for device group
         //     prepare name element commands
-        //     update names - re-calculate names
+        //     update names
         //     return name elements for updated names
 
         List<NameElement> updatedNameElements = Lists.newArrayList();
@@ -600,72 +595,72 @@ public class NamesService {
                 && !StringUtils.isEmpty(structure.getMnemonic())) {
             List<Name> names = null;
             List<NameElementCommand> nameElements = Lists.newArrayList();
-            UUID parentSystemStructure = null;
+            UUID parentSystemStructureUuid = null;
+            UUID parentDeviceStructureUuid = null;
 
             if (previousStructure instanceof SystemGroup && structure instanceof SystemGroup) {
-                // find
-                // prepare
-                names = holderIRepositories.nameRepository().findLatestNotDeletedBySystemGroupUuid(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedBySystemGroupUuid(structure.getUuid().toString());
                 for (Name name : names) {
+                    parentSystemStructureUuid = NameElementUtil.getSystemGroupUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), name.getSystemGroupUuid(), name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
             } else if (previousStructure instanceof System && structure instanceof System) {
-                // find
-                // prepare
-                names = holderIRepositories.nameRepository().findLatestNotDeletedBySystemUuid(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedBySystemUuid(structure.getUuid().toString());
                 for (Name name : names) {
+                    parentSystemStructureUuid = NameElementUtil.getSystemUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), name.getSystemUuid(), name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
 
-                names = holderIRepositories.nameRepository().findLatestNotDeletedBySystemUuidThroughSubsystem(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedBySystemUuidThroughSubsystem(structure.getUuid().toString());
                 for (Name name : names) {
+                    parentSystemStructureUuid = NameElementUtil.getSubsystemUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), name.getSubsystemUuid(), name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
             } else if (previousStructure instanceof Subsystem && structure instanceof Subsystem) {
-                // find
-                // prepare
-                names = holderIRepositories.nameRepository().findLatestNotDeletedBySubsystemUuid(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedBySubsystemUuid(structure.getUuid().toString());
                 for (Name name : names) {
+                    parentSystemStructureUuid = NameElementUtil.getSubsystemUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), name.getSubsystemUuid(), name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
             } else if (previousStructure instanceof Discipline && structure instanceof Discipline) {
-                // find
-                // prepare
-                names = holderIRepositories.nameRepository().findLatestNotDeletedByDisciplineUuidThroughDeviceType(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedByDisciplineUuidThroughDeviceType(structure.getUuid().toString());
                 for (Name name : names) {
-                    parentSystemStructure = NameUtil.getParentSystemStructure(name);
+                    parentSystemStructureUuid = NameElementUtil.getParentSystemStructureUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), parentSystemStructure, name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
             } else if (previousStructure instanceof DeviceType && structure instanceof DeviceType) {
-                // find
-                // prepare
-                names = holderIRepositories.nameRepository().findLatestNotDeletedByDeviceTypeUuid(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedByDeviceTypeUuid(structure.getUuid().toString());
                 for (Name name : names) {
-                    parentSystemStructure = NameUtil.getParentSystemStructure(name);
+                    parentSystemStructureUuid = NameElementUtil.getParentSystemStructureUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), parentSystemStructure, name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
             }
 
             // update names
-            //     use active transaction or, if not available, throw exception
             updatedNameElements = updateNames(nameElements, username);
         }
         return updatedNameElements;
@@ -678,16 +673,14 @@ public class NamesService {
         // validation outside method
         // transaction
         //     for each name element
-        //         attributes
-        //         find
-        //         update name to not latest
-        //         insert name to latest, deleted
-        //         handle name element for deleted name
+        //         delete name (update)
+        //         create audit
+        //         handle name element for deleted name (updated)
         //     no notify
         //     return name elements for deleted names
-        //
-        // attributes
-        //     uuid
+
+        // holder of valid content for system and device structures
+        HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         Date when = new Date();
         final List<NameElement> deletedNameElements = Lists.newArrayList();
@@ -695,25 +688,18 @@ public class NamesService {
             UUID uuid = nameElementCommand.getUuid();
             String comment = null;
 
-            Name name = holderIRepositories.nameRepository().findLatestByUuid(uuid.toString());
+            // update
+            // create audit
+            Name name = holderIRepositories.nameRepository().findByUuid(uuid.toString());
             if (name == null) {
                 continue;
             }
+            name.setDeleted(Boolean.TRUE);
+            name.setAttributesRequested(when, username, comment);
+            holderRepositories.nameRepository().updateName(name);
+            holderRepositories.auditNameRepository().createAuditName(new AuditName(TextUtil.DELETE, name));
 
-            name.setLatest(Boolean.FALSE);
-            nameRepository.updateName(name);
-
-            name = new Name(uuid,
-                    name.getSystemGroupUuid(),
-                    name.getSystemUuid(),
-                    name.getSubsystemUuid(),
-                    name.getDeviceTypeUuid(),
-                    name.getInstanceIndex(), name.getConventionName(), name.getConventionNameEquivalence(), name.getDescription(),
-                    Status.APPROVED, Boolean.TRUE, Boolean.TRUE,
-                    when, username, comment);
-            nameRepository.createName(name);
-
-            NameElement deletedNameElement = NameElementUtil.getNameElement(name);
+            NameElement deletedNameElement = NameElementUtil.getNameElement(name, holderStructures);
             deletedNameElements.add(deletedNameElement);
 
             if (LOGGER.isLoggable(Level.FINER)) {
@@ -732,70 +718,66 @@ public class NamesService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public List<NameElement> deleteNames(Structure structure, String username) {
+    public List<NameElement> deleteNames(Structure structure, String username, HolderStructures holderStructures) {
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
         //     find out names referenced by structure
-        //         by system group
-        //         by system
-        //         by subsystem
-        //         by device type
-        //     delete names
+        //     prepare name element commands
+        //     delete names (update)
         //     no notify
-        //     return name elements for deleted names
+        //     return name elements for deleted names (updated)
 
         List<NameElement> deletedNameElements = Lists.newArrayList();
         if (structure != null) {
             List<Name> names = null;
             List<NameElementCommand> nameElements = Lists.newArrayList();
-            UUID parentSystemStructure = null;
+            UUID parentSystemStructureUuid = null;
+            UUID parentDeviceStructureUuid = null;
 
             if (structure instanceof SystemGroup) {
-                // find
-                // prepare
-                names = holderIRepositories.nameRepository().findLatestNotDeletedBySystemGroupUuid(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedBySystemGroupUuid(structure.getUuid().toString());
                 for (Name name : names) {
+                    parentSystemStructureUuid = NameElementUtil.getSystemGroupUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), name.getSubsystemUuid(), name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
             } else if (structure instanceof System) {
-                // find
-                // prepare
-                names = holderIRepositories.nameRepository().findLatestNotDeletedBySystemUuid(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedBySystemUuid(structure.getUuid().toString());
                 for (Name name : names) {
+                    parentSystemStructureUuid = NameElementUtil.getSystemUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), name.getSubsystemUuid(), name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
             } else if (structure instanceof Subsystem) {
-                // find
-                // prepare
-                names = holderIRepositories.nameRepository().findLatestNotDeletedBySubsystemUuid(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedBySubsystemUuid(structure.getUuid().toString());
                 for (Name name : names) {
+                    parentSystemStructureUuid = NameElementUtil.getSubsystemUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), name.getSubsystemUuid(), name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
             } else if (structure instanceof DeviceType) {
-                // find
-                // prepare
-                names = holderIRepositories.nameRepository().findLatestNotDeletedByDeviceTypeUuid(structure.getUuid().toString());
+                names = holderIRepositories.nameRepository().findNotDeletedByDeviceTypeUuid(structure.getUuid().toString());
                 for (Name name : names) {
-                    parentSystemStructure = NameUtil.getParentSystemStructure(name);
+                    parentSystemStructureUuid = NameElementUtil.getParentSystemStructureUuid(name, holderStructures);
+                    parentDeviceStructureUuid = NameElementUtil.getDeviceTypeUuid(name, holderStructures);
                     nameElements.add(
                             new NameElementCommand(
-                                    name.getUuid(), parentSystemStructure, name.getDeviceTypeUuid(),
+                                    name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                                     name.getInstanceIndex(), name.getDescription()));
                 }
             }
 
             // delete names
-            //     use active transaction or, if not available, throw exception
             deletedNameElements = deleteNames(nameElements, username);
         }
         return deletedNameElements;
diff --git a/src/main/java/org/openepics/names/service/StructuresService.java b/src/main/java/org/openepics/names/service/StructuresService.java
index 64b450958cc11d1179d634a23c15bb817d9d961b..64f0841d75863c4376dece9a9c562a4bbce96812 100644
--- a/src/main/java/org/openepics/names/service/StructuresService.java
+++ b/src/main/java/org/openepics/names/service/StructuresService.java
@@ -25,9 +25,8 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.DeviceGroupRepository;
-import org.openepics.names.repository.DeviceTypeRepository;
-import org.openepics.names.repository.DisciplineRepository;
+import org.openepics.names.repository.IAuditNameRepository;
+import org.openepics.names.repository.IAuditStructureRepository;
 import org.openepics.names.repository.IDeviceGroupRepository;
 import org.openepics.names.repository.IDeviceTypeRepository;
 import org.openepics.names.repository.IDisciplineRepository;
@@ -35,10 +34,16 @@ import org.openepics.names.repository.INameRepository;
 import org.openepics.names.repository.ISubsystemRepository;
 import org.openepics.names.repository.ISystemGroupRepository;
 import org.openepics.names.repository.ISystemRepository;
+import org.openepics.names.repository.AuditNameRepository;
+import org.openepics.names.repository.AuditStructureRepository;
+import org.openepics.names.repository.DeviceGroupRepository;
+import org.openepics.names.repository.DeviceTypeRepository;
+import org.openepics.names.repository.DisciplineRepository;
 import org.openepics.names.repository.NameRepository;
 import org.openepics.names.repository.SubsystemRepository;
 import org.openepics.names.repository.SystemGroupRepository;
 import org.openepics.names.repository.SystemRepository;
+import org.openepics.names.repository.model.AuditStructure;
 import org.openepics.names.repository.model.DeviceGroup;
 import org.openepics.names.repository.model.DeviceType;
 import org.openepics.names.repository.model.Discipline;
@@ -61,6 +66,7 @@ import org.openepics.names.util.TextUtil;
 import org.openepics.names.util.Utilities;
 import org.openepics.names.util.ValidateStructureElementUtil;
 import org.openepics.names.util.notification.NotificationStructure;
+import org.openepics.names.util.notification.StructureElementNotification;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -76,12 +82,11 @@ import com.google.common.collect.Lists;
 public class StructuresService {
 
     // note
-    //     holder
-    //         HolderIRepositories and HolderSystemDeviceStructure may or may not be used for preparation of what to return
-    //     latest
-    //         automatically not show structures that do not come into play
-    //         = automatically exclude (approved and not latest)
-    //         otherwise refer to history
+    //     default
+    //         active means valid not deleted
+    //         obsolete values are not shown unless history is requested
+    //     sorting
+    //         sorting not applicable when multiple repositories are queried in same method
     //     structurecommand
     //         cud - create update delete
 
@@ -90,18 +95,25 @@ public class StructuresService {
     protected static final String SYSTEM_STRUCTURE_ONLY                 = "System structure only";
 
     private EssNamingConvention namingConvention;
-    private HolderIRepositories holderIRepositories;
-    private HolderRepositories holderRepositories;
+    private NotificationService notificationService;
     private SystemGroupService systemGroupService;
     private SystemService systemService;
     private SubsystemService subsystemService;
     private DisciplineService disciplineService;
     private DeviceGroupService deviceGroupService;
     private DeviceTypeService deviceTypeService;
-    private NotificationService notificationService;
+    private HolderIRepositories holderIRepositories;
+    private HolderRepositories holderRepositories;
 
     @Autowired
     public StructuresService(
+            NotificationService notificationService,
+            SystemGroupService systemGroupService,
+            SystemService systemService,
+            SubsystemService subsystemService,
+            DisciplineService disciplineService,
+            DeviceGroupService deviceGroupService,
+            DeviceTypeService deviceTypeService,
             INameRepository iNameRepository,
             ISystemGroupRepository iSystemGroupRepository,
             ISystemRepository iSystemRepository,
@@ -109,6 +121,8 @@ public class StructuresService {
             IDisciplineRepository iDisciplineRepository,
             IDeviceGroupRepository iDeviceGroupRepository,
             IDeviceTypeRepository iDeviceTypeRepository,
+            IAuditNameRepository iAuditNameRepository,
+            IAuditStructureRepository iAuditStructureRepository,
             NameRepository nameRepository,
             SystemGroupRepository systemGroupRepository,
             SystemRepository systemRepository,
@@ -116,15 +130,17 @@ public class StructuresService {
             DisciplineRepository disciplineRepository,
             DeviceGroupRepository deviceGroupRepository,
             DeviceTypeRepository deviceTypeRepository,
-            SystemGroupService systemGroupService,
-            SystemService systemService,
-            SubsystemService subsystemService,
-            DisciplineService disciplineService,
-            DeviceGroupService deviceGroupService,
-            DeviceTypeService deviceTypeService,
-            NotificationService notificationService) {
+            AuditNameRepository auditNameRepository,
+            AuditStructureRepository auditStructureRepository) {
 
         this.namingConvention = new EssNamingConvention();
+        this.notificationService = notificationService;
+        this.systemGroupService = systemGroupService;
+        this.systemService = systemService;
+        this.subsystemService = subsystemService;
+        this.disciplineService = disciplineService;
+        this.deviceGroupService = deviceGroupService;
+        this.deviceTypeService = deviceTypeService;
         this.holderIRepositories = new HolderIRepositories(
                 iNameRepository,
                 iSystemGroupRepository,
@@ -132,7 +148,9 @@ public class StructuresService {
                 iSubsystemRepository,
                 iDisciplineRepository,
                 iDeviceGroupRepository,
-                iDeviceTypeRepository);
+                iDeviceTypeRepository,
+                iAuditNameRepository,
+                iAuditStructureRepository);
         this.holderRepositories = new HolderRepositories(
                 nameRepository,
                 systemGroupRepository,
@@ -140,14 +158,9 @@ public class StructuresService {
                 subsystemRepository,
                 disciplineRepository,
                 deviceGroupRepository,
-                deviceTypeRepository);
-        this.systemGroupService = systemGroupService;
-        this.systemService = systemService;
-        this.subsystemService = subsystemService;
-        this.disciplineService = disciplineService;
-        this.deviceGroupService = deviceGroupService;
-        this.deviceTypeService = deviceTypeService;
-        this.notificationService = notificationService;
+                deviceTypeRepository,
+                auditNameRepository,
+                auditStructureRepository);
     }
 
     @Transactional
@@ -162,7 +175,7 @@ public class StructuresService {
         //     notify
         //     return structure elements for created structures
 
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         Date when = new Date();
@@ -246,22 +259,9 @@ public class StructuresService {
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.READ_STRUCTURES, "structureChoice", structureChoice));
         }
 
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
-        // one structure entry will give one or two structure elements
-        //     depends on history or not - history may give one or two elements, if not history then one element
-        //     history affects totalCount, sorting, pagination
-        //         additional effects (entries) if type is not given
-        //         totalCount = Long.valueOf(structureElements.size())
-        //         this affects result
-        //         -->
-        //         actions to mitigate / handle
-        //             have type as required parameter
-        //             have pagination for history in StructuresService and not in Repository classes (!)
-        //                 after conversion to List<StructureElement>
-        //             analyse and decide on sorting for history
-
         List<StructureElement> structureElements = Lists.newArrayList();
 
         // systemgroup and discipline do not have parent uuid
@@ -269,63 +269,63 @@ public class StructuresService {
         // pagination after queries since type is not required
 
         if (StringUtils.isEmpty(parent) && (Type.SYSTEMGROUP.equals(type) || type == null)) {
-            List<SystemGroup> systemGroups = null;
             if (Boolean.TRUE.equals(includeHistory)) {
-                systemGroups = holderRepositories.systemGroupRepository().readSystemGroupsHistory(uuid, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc);
+                List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
             } else {
-                systemGroups = holderRepositories.systemGroupRepository().readSystemGroups(deleted, uuid, mnemonic, null, mnemonicPath, description, who, includeHistory, orderBy, isAsc, null, null);
+                List<SystemGroup> systemGroups = holderRepositories.systemGroupRepository().readSystemGroups(deleted, uuid, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForSystemGroups(systemGroups, holderStructures, structureChoice));
             }
-            structureElements.addAll(StructureElementUtil.getStructureElementsForSystemGroups(systemGroups, holderStructures, structureChoice));
         }
 
         if (Type.SYSTEM.equals(type) || type == null) {
-            List<System> systems = null;
             if (Boolean.TRUE.equals(includeHistory)) {
-                systems = holderRepositories.systemRepository().readSystemsHistory(uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc);
+                List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
             } else {
-                systems = holderRepositories.systemRepository().readSystems(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, includeHistory, orderBy, isAsc, null, null);
+                List<System> systems = holderRepositories.systemRepository().readSystems(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForSystems(systems, holderStructures, structureChoice));
             }
-            structureElements.addAll(StructureElementUtil.getStructureElementsForSystems(systems, holderStructures, structureChoice));
         }
 
         if (Type.SUBSYSTEM.equals(type) || type == null) {
-            List<Subsystem> subsystems = null;
             if (Boolean.TRUE.equals(includeHistory)) {
-                subsystems = holderRepositories.subsystemRepository().readSubsystemsHistory(uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc);
+                List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
             } else {
-                subsystems = holderRepositories.subsystemRepository().readSubsystems(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, includeHistory, orderBy, isAsc, null, null);
+                List<Subsystem> subsystems = holderRepositories.subsystemRepository().readSubsystems(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForSubsystems(subsystems, holderStructures, structureChoice));
             }
-            structureElements.addAll(StructureElementUtil.getStructureElementsForSubsystems(subsystems, holderStructures, structureChoice));
         }
 
         if (StringUtils.isEmpty(parent) && (Type.DISCIPLINE.equals(type) || type == null)) {
-            List<Discipline> disciplines = null;
             if (Boolean.TRUE.equals(includeHistory)) {
-                disciplines = holderRepositories.disciplineRepository().readDisciplinesHistory(uuid, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc);
+                List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
             } else {
-                disciplines = holderRepositories.disciplineRepository().readDisciplines(deleted, uuid, mnemonic, null, mnemonicPath, description, who, includeHistory, orderBy, isAsc, null, null);
+                List<Discipline> disciplines = holderRepositories.disciplineRepository().readDisciplines(deleted, uuid, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForDisciplines(disciplines, holderStructures, structureChoice));
             }
-            structureElements.addAll(StructureElementUtil.getStructureElementsForDisciplines(disciplines, holderStructures, structureChoice));
         }
 
         if (Type.DEVICEGROUP.equals(type) || type == null) {
-            List<DeviceGroup> deviceGroups = null;
             if (Boolean.TRUE.equals(includeHistory)) {
-                deviceGroups = holderRepositories.deviceGroupRepository().readDeviceGroupsHistory(uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc);
+                List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
             } else {
-                deviceGroups = holderRepositories.deviceGroupRepository().readDeviceGroups(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, includeHistory, orderBy, isAsc, null, null);
+                List<DeviceGroup> deviceGroups = holderRepositories.deviceGroupRepository().readDeviceGroups(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceGroups(deviceGroups, holderStructures, structureChoice));
             }
-            structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceGroups(deviceGroups, holderStructures, structureChoice));
         }
 
         if (Type.DEVICETYPE.equals(type) || type == null) {
-            List<DeviceType> deviceTypes = null;
             if (Boolean.TRUE.equals(includeHistory)) {
-                deviceTypes = holderRepositories.deviceTypeRepository().readDeviceTypesHistory(uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc);
+                List<AuditStructure> auditStructures = holderRepositories.auditStructureRepository().readAuditStructures(null, uuid, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForAuditStructures(auditStructures, holderStructures, structureChoice));
             } else {
-                deviceTypes = holderRepositories.deviceTypeRepository().readDeviceTypes(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, includeHistory, orderBy, isAsc, null, null);
+                List<DeviceType> deviceTypes = holderRepositories.deviceTypeRepository().readDeviceTypes(deleted, uuid, parent, mnemonic, null, mnemonicPath, description, who, orderBy, isAsc, null, null);
+                structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceTypes(deviceTypes, holderStructures, structureChoice));
             }
-            structureElements.addAll(StructureElementUtil.getStructureElementsForDeviceTypes(deviceTypes, holderStructures, structureChoice));
         }
 
         // pagination for normal read and history
@@ -363,7 +363,7 @@ public class StructuresService {
             Boolean deleted,
             FieldStructure orderBy, Boolean isAsc, Integer offset, Integer limit) {
         // validation outside method
-        // read structure latest by uuid for type
+        // read structure by uuid for type
         // return structure elements for structures
 
         if (LOGGER.isLoggable(Level.FINE)) {
@@ -421,6 +421,7 @@ public class StructuresService {
         response = response.getTotalCount() == 0 ? readStructures(Type.DISCIPLINE,  null, uuid, null, null, null, null, null, Boolean.TRUE, FieldStructure.WHEN, Boolean.TRUE, offset, limit, StructureChoice.HISTORY) : response;
         response = response.getTotalCount() == 0 ? readStructures(Type.DEVICEGROUP, null, uuid, null, null, null, null, null, Boolean.TRUE, FieldStructure.WHEN, Boolean.TRUE, offset, limit, StructureChoice.HISTORY) : response;
         response = response.getTotalCount() == 0 ? readStructures(Type.DEVICETYPE,  null, uuid, null, null, null, null, null, Boolean.TRUE, FieldStructure.WHEN, Boolean.TRUE, offset, limit, StructureChoice.HISTORY) : response;
+
         return response;
     }
 
@@ -466,7 +467,7 @@ public class StructuresService {
             LOGGER.log(Level.FINE, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.IS_VALID_TO_CREATE_STRUCTURE, "mnemonicPath", mnemonicPath));
         }
 
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         //     note false to not include deleted entries
         HolderStructures holderStructures = new HolderStructures(holderIRepositories, false);
 
@@ -482,17 +483,14 @@ public class StructuresService {
     }
     public void validateStructuresCreate(StructureElementCommand structureElement, HolderStructures holderStructures) {
         // validate structure element
-        //     input
-        //         input itself
-        //     data
-        //         data itself
-        //         relative other data
+        //     input vs given task
+        //     data  vs given task
 
         ValidateStructureElementUtil.validateStructureElementInputCreate(structureElement, namingConvention);
         ValidateStructureElementUtil.validateStructureElementDataCreate(structureElement, namingConvention, holderRepositories, holderStructures);
     }
     public void validateStructuresCreate(List<StructureElementCommand> structureElements) {
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         for (StructureElementCommand structureElement : structureElements) {
@@ -505,17 +503,14 @@ public class StructuresService {
     }
     public void validateStructuresUpdate(StructureElementCommand structureElement, HolderStructures holderStructures) {
         // validate structure element
-        //     input
-        //         input itself
-        //     data
-        //         data itself
-        //         relative other data
+        //     input vs given task
+        //     data  vs given task
 
         ValidateStructureElementUtil.validateStructureElementInputUpdate(structureElement, namingConvention);
         ValidateStructureElementUtil.validateStructureElementDataUpdate(structureElement, namingConvention, holderRepositories, holderStructures);
     }
     public void validateStructuresUpdate(List<StructureElementCommand> structureElements) {
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         for (StructureElementCommand structureElement : structureElements) {
@@ -528,17 +523,14 @@ public class StructuresService {
     }
     public void validateStructuresDelete(StructureElementCommand structureElement, HolderStructures holderStructures) {
         // validate structure element
-        //     input
-        //         input itself
-        //     data
-        //         data itself
-        //         relative other data
+        //     input vs given task
+        //     data  vs given task
 
         ValidateStructureElementUtil.validateStructureElementInputDelete(structureElement, namingConvention);
         ValidateStructureElementUtil.validateStructureElementDataDelete(structureElement, namingConvention, holderRepositories, holderStructures);
     }
     public void validateStructuresDelete(List<StructureElementCommand> structureElements) {
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         for (StructureElementCommand structureElement : structureElements) {
@@ -560,7 +552,7 @@ public class StructuresService {
         //     notify
         //     return structure elements for updated structures
 
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         Date when = new Date();
@@ -623,7 +615,7 @@ public class StructuresService {
         //     notify
         //     return structure elements for deleted structures
 
-        // initiate holder of system and device structure content, for performance reasons
+        // holder of valid content for system and device structures
         HolderStructures holderStructures = new HolderStructures(holderIRepositories);
 
         Date when = new Date();
diff --git a/src/main/java/org/openepics/names/service/SubsystemService.java b/src/main/java/org/openepics/names/service/SubsystemService.java
index 697c761bdb53900f02efa7ed0ba3159eae2744cf..bb979ee24885d4cb2ca646dbad19167725090c91 100644
--- a/src/main/java/org/openepics/names/service/SubsystemService.java
+++ b/src/main/java/org/openepics/names/service/SubsystemService.java
@@ -20,15 +20,19 @@ package org.openepics.names.service;
 
 import java.text.MessageFormat;
 import java.util.Date;
-import java.util.List;
 import java.util.UUID;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.IAuditStructureRepository;
 import org.openepics.names.repository.ISubsystemRepository;
+import org.openepics.names.repository.ISystemRepository;
+import org.openepics.names.repository.AuditStructureRepository;
 import org.openepics.names.repository.SubsystemRepository;
+import org.openepics.names.repository.model.AuditStructure;
 import org.openepics.names.repository.model.Subsystem;
+import org.openepics.names.repository.model.System;
 import org.openepics.names.rest.beans.Status;
 import org.openepics.names.rest.beans.Type;
 import org.openepics.names.rest.beans.element.NameElementCommand;
@@ -40,8 +44,8 @@ import org.openepics.names.util.StructureCommand;
 import org.openepics.names.util.StructureElementUtil;
 import org.openepics.names.util.StructureUtil;
 import org.openepics.names.util.TextUtil;
-import org.openepics.names.util.ValidateUtil;
 import org.openepics.names.util.notification.NotificationUtil;
+import org.openepics.names.util.notification.StructureElementNotification;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -57,60 +61,68 @@ public class SubsystemService {
 
     private static final Logger LOGGER = Logger.getLogger(SubsystemService.class.getName());
 
+    private NamesService namesService;
+    private ISystemRepository iSystemRepository;
     private ISubsystemRepository iSubsystemRepository;
+    private IAuditStructureRepository iAuditStructureRepository;
     private SubsystemRepository subsystemRepository;
-    private NamesService namesService;
+    private AuditStructureRepository auditStructureRepository;
 
     @Autowired
     public SubsystemService(
+            NamesService namesService,
+            ISystemRepository iSystemRepository,
             ISubsystemRepository iSubsystemRepository,
+            IAuditStructureRepository iAuditStructureRepository,
             SubsystemRepository subsystemRepository,
-            NamesService namesService) {
+            AuditStructureRepository auditStructureRepository) {
+        this.namesService = namesService;
+        this.iSystemRepository = iSystemRepository;
         this.iSubsystemRepository = iSubsystemRepository;
+        this.iAuditStructureRepository = iAuditStructureRepository;
         this.subsystemRepository = subsystemRepository;
-        this.namesService = namesService;
+        this.auditStructureRepository = auditStructureRepository;
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     create structure - approved, latest, not deleted
+        //     create structure
+        //     create audit
         //     additional
         //         automatically create name when system structure is created
-        //         condition on name and structure entry
-        //             system structure should exist (uuid), one entry that is not deleted
-        //             name should not exist (system structure mnemonic path)
-        //         within current transaction
+        //         conditions on name and structure entry
+        //             system structure should exist - mnemonic
+        //             name should not exist         - system structure mnemonic path
         //     return
         //         structure element for created structure
         //         notification
-        //
-        // attributes
-        //     type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
+        UUID uuid = UUID.randomUUID();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // create
-        Subsystem subsystem = new Subsystem(UUID.randomUUID(), structureElementCommand.getParent(),
+        // create structure
+        // create audit
+        System system = iSystemRepository.findByUuid(structureElementCommand.getParent().toString());
+        Subsystem subsystem = new Subsystem(uuid, system.getId(),
                 mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
+                structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
                 when, username, null);
         subsystemRepository.createSubsystem(subsystem);
+        auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, subsystem));
 
         // additional
         boolean hasMnemonic = !StringUtils.isEmpty(subsystem.getMnemonic());
         boolean existsName = hasMnemonic && namesService.existsName(StructureUtil.getMnemonicPath(subsystem, holderStructures));
         if (hasMnemonic && !existsName) {
             NameElementCommand nameElement = new NameElementCommand(null, subsystem.getUuid(), null, null, StructuresService.SYSTEM_STRUCTURE_ONLY);
-            namesService.createName(nameElement, when, username, holderStructures);
+            namesService.createName(nameElement, when, username, holderStructures, subsystem);
         }
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
@@ -121,54 +133,42 @@ public class SubsystemService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, not deleted
+        //     update structure
+        //     create audit
         //     previous for notification
         //     additional - update related names
         //     return
         //         structure element for updated structure
         //         notification
-        //
-        // attributes
-        //     uuid, type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
         String uuid = structureElementCommand.getUuid().toString();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // find
-        List<Subsystem> subsystems = subsystemRepository.readSubsystems(Boolean.FALSE, uuid, null, null, null, null, null, null);
-        Subsystem subsystem = null;
-        if (ValidateUtil.isSize(subsystems, 1)) {
-            subsystem = subsystems.get(0);
-
-            // update not latest
-            subsystem.setLatest(Boolean.FALSE);
-            subsystemRepository.updateSubsystem(subsystem);
-        }
-
-        // create
-        subsystem = new Subsystem(structureElementCommand.getUuid(), structureElementCommand.getParent(),
-                mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
-                when, username, null);
-        subsystemRepository.createSubsystem(subsystem);
+        // update structure
+        // create audit
+        Subsystem subsystem = iSubsystemRepository.findByUuid(uuid);
+        subsystem.setMnemonic(mnemonic);
+        subsystem.setMnemonicEquivalence(equivalenceClassRepresentative);
+        subsystem.setOrdering(structureElementCommand.getOrdering());
+        subsystem.setDescription(structureElementCommand.getDescription());
+        subsystemRepository.updateSubsystem(subsystem);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, subsystem);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<Subsystem> previouses = iSubsystemRepository.findPreviousByUuidAndId(subsystem.getUuid().toString(), subsystem.getId());
-        Subsystem previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SUBSYSTEM.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        Subsystem previous = new Subsystem(previousAuditStructure);
 
         // additional
-        namesService.updateNames(previous, subsystem, username);
+        namesService.updateNames(previous, subsystem, username, holderStructures);
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
 
@@ -178,49 +178,38 @@ public class SubsystemService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username, HolderStructures holderStructures) {
+    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, deleted
+        //     delete structure (update)
+        //     create audit
         //     previous for notification
-        //     additional - delete related names
+        //     additional
+        //         delete related names
         //     return
         //         structure element for deleted structure
         //         notification
-        //
-        // attributes
-        //     uuid
 
         String uuid = structureElementCommand.getUuid().toString();
 
-        // find
-        List<Subsystem> subsystems = subsystemRepository.readSubsystems(Boolean.FALSE, uuid, null, null, null, null, null, null);
-        Subsystem subsystem = null;
-        if (ValidateUtil.isSize(subsystems, 1)) {
-            subsystem = subsystems.get(0);
-
-            // update not latest
-            subsystem.setLatest(Boolean.FALSE);
-            subsystemRepository.updateSubsystem(subsystem);
-        } else {
-            return null;
-        }
-
-        // create
-        subsystem = new Subsystem(subsystem.getUuid(), subsystem.getParentUuid(),
-                subsystem.getMnemonic(), subsystem.getMnemonicEquivalence(), subsystem.getOrdering(),
-                subsystem.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.TRUE,
-                when, username, null);
-        subsystemRepository.createSubsystem(subsystem);
+        // delete structure
+        // create audit
+        Subsystem subsystem = iSubsystemRepository.findByUuid(uuid);
+        subsystem.setDeleted(Boolean.TRUE);
+        subsystem.setAttributesProcessed(when, username, null);
+        subsystemRepository.updateSubsystem(subsystem);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, subsystem);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<Subsystem> previouses = iSubsystemRepository.findPreviousByUuidAndId(uuid, subsystem.getId());
-        Subsystem previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SUBSYSTEM.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        Subsystem previous = new Subsystem(previousAuditStructure);
 
         // additional
-        namesService.deleteNames(subsystem, username);
+        namesService.deleteNames(subsystem, username, holderStructures);
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.DELETE_STRUCTURE, TextUtil.COMMAND, StructureCommand.DELETE));
 
diff --git a/src/main/java/org/openepics/names/service/SystemGroupService.java b/src/main/java/org/openepics/names/service/SystemGroupService.java
index 69d02e6591376fe789b21449f0e3b79dec9dd7a5..072f62b1f55f59ecb4172b0974c601beb7f41efc 100644
--- a/src/main/java/org/openepics/names/service/SystemGroupService.java
+++ b/src/main/java/org/openepics/names/service/SystemGroupService.java
@@ -26,9 +26,12 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.IAuditStructureRepository;
 import org.openepics.names.repository.ISystemGroupRepository;
 import org.openepics.names.repository.ISystemRepository;
+import org.openepics.names.repository.AuditStructureRepository;
 import org.openepics.names.repository.SystemGroupRepository;
+import org.openepics.names.repository.model.AuditStructure;
 import org.openepics.names.repository.model.System;
 import org.openepics.names.repository.model.SystemGroup;
 import org.openepics.names.rest.beans.Status;
@@ -42,8 +45,8 @@ import org.openepics.names.util.StructureCommand;
 import org.openepics.names.util.StructureElementUtil;
 import org.openepics.names.util.StructureUtil;
 import org.openepics.names.util.TextUtil;
-import org.openepics.names.util.ValidateUtil;
 import org.openepics.names.util.notification.NotificationUtil;
+import org.openepics.names.util.notification.StructureElementNotification;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -61,66 +64,69 @@ public class SystemGroupService {
 
     private static final Logger LOGGER = Logger.getLogger(SystemGroupService.class.getName());
 
+    private NamesService namesService;
+    private SystemService systemService;
     private ISystemGroupRepository iSystemGroupRepository;
     private ISystemRepository iSystemRepository;
+    private IAuditStructureRepository iAuditStructureRepository;
     private SystemGroupRepository systemGroupRepository;
-    private SystemService systemService;
-    private NamesService namesService;
+    private AuditStructureRepository auditStructureRepository;
 
     @Autowired
     public SystemGroupService(
+            NamesService namesService,
+            SystemService systemService,
             ISystemGroupRepository iSystemGroupRepository,
             ISystemRepository iSystemRepository,
+            IAuditStructureRepository iAuditStructureRepository,
             SystemGroupRepository systemGroupRepository,
-            SystemService systemService,
-            NamesService namesService) {
+            AuditStructureRepository auditStructureRepository) {
+        this.namesService = namesService;
+        this.systemService = systemService;
         this.iSystemGroupRepository = iSystemGroupRepository;
         this.iSystemRepository = iSystemRepository;
+        this.iAuditStructureRepository = iAuditStructureRepository;
         this.systemGroupRepository = systemGroupRepository;
-        this.systemService = systemService;
-        this.namesService = namesService;
+        this.auditStructureRepository = auditStructureRepository;
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     create structure - approved, latest, not deleted
+        //     create structure
+        //     create audit
         //     additional
         //         automatically create name when system structure is created
-        //         condition on name and structure entry
-        //             system structure should exist (uuid), one entry that is not deleted
-        //             name should not exist (system structure mnemonic path)
-        //         within current transaction
+        //         conditions on name and structure entry
+        //             system structure should exist - mnemonic
+        //             name should not exist         - system structure mnemonic path
         //     return
         //         structure element for created structure
         //         notification
-        //
-        // attributes
-        //     type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
+        UUID uuid = UUID.randomUUID();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // create
-        SystemGroup systemGroup = new SystemGroup(UUID.randomUUID(),
+        // create structure
+        // create audit
+        SystemGroup systemGroup = new SystemGroup(uuid,
                 mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
+                structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
                 when, username, null);
         systemGroupRepository.createSystemGroup(systemGroup);
+        auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, systemGroup));
 
         // additional
         boolean hasMnemonic = !StringUtils.isEmpty(systemGroup.getMnemonic());
         boolean existsName = hasMnemonic && namesService.existsName(StructureUtil.getMnemonicPath(systemGroup, holderStructures));
         if (hasMnemonic && !existsName) {
             NameElementCommand nameElement = new NameElementCommand(null, systemGroup.getUuid(), null, null, StructuresService.SYSTEM_STRUCTURE_ONLY);
-            namesService.createName(nameElement, when, username, holderStructures);
+            namesService.createName(nameElement, when, username, holderStructures, systemGroup);
         }
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
@@ -131,54 +137,43 @@ public class SystemGroupService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, not deleted
+        //     update structure
+        //     create audit
         //     previous for notification
-        //     additional - update related names
+        //     additional
+        //         update related names
         //     return
         //         structure element for updated structure
         //         notification
-        //
-        // attributes
-        //     uuid, type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
         String uuid = structureElementCommand.getUuid().toString();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // find
-        List<SystemGroup> systemGroups = systemGroupRepository.readSystemGroups(Boolean.FALSE, uuid, null, null, null, null, null);
-        SystemGroup systemGroup = null;
-        if (ValidateUtil.isSize(systemGroups, 1)) {
-            systemGroup = systemGroups.get(0);
-
-            // update not latest
-            systemGroup.setLatest(Boolean.FALSE);
-            systemGroupRepository.updateSystemGroup(systemGroup);
-        }
-
-        // create
-        systemGroup = new SystemGroup(structureElementCommand.getUuid(),
-                mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
-                when, username, null);
-        systemGroupRepository.createSystemGroup(systemGroup);
+        // update structure
+        // create audit
+        SystemGroup systemGroup = iSystemGroupRepository.findByUuid(uuid);
+        systemGroup.setMnemonic(mnemonic);
+        systemGroup.setMnemonicEquivalence(equivalenceClassRepresentative);
+        systemGroup.setOrdering(structureElementCommand.getOrdering());
+        systemGroup.setDescription(structureElementCommand.getDescription());
+        systemGroupRepository.updateSystemGroup(systemGroup);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, systemGroup);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<SystemGroup> previouses = iSystemGroupRepository.findPreviousByUuidAndId(uuid, systemGroup.getId());
-        SystemGroup previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SYSTEMGROUP.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        SystemGroup previous = new SystemGroup(previousAuditStructure);
 
         // additional
-        namesService.updateNames(previous, systemGroup, username);
+        namesService.updateNames(previous, systemGroup, username, holderStructures);
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
 
@@ -188,53 +183,43 @@ public class SystemGroupService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username, HolderStructures holderStructures) {
+    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, deleted
+        //     delete structure (update)
+        //     create audit
         //     previous for notification
-        //     additional - delete related names, delete sub structures (and related names)
+        //     additional
+        //         delete related names
+        //         delete sub structures (and related names)
         //     return
         //         structure element for deleted structure
         //         notification
-        //
-        // attributes
-        //     uuid
 
         String uuid = structureElementCommand.getUuid().toString();
 
-        // find
-        List<SystemGroup> systemGroups = systemGroupRepository.readSystemGroups(Boolean.FALSE, uuid, null, null, null, null, null);
-        SystemGroup systemGroup = null;
-        if (ValidateUtil.isSize(systemGroups, 1)) {
-            systemGroup = systemGroups.get(0);
-
-            // update not latest
-            systemGroup.setLatest(Boolean.FALSE);
-            systemGroupRepository.updateSystemGroup(systemGroup);
-        } else {
-            return null;
-        }
-
-        // create
-        systemGroup = new SystemGroup(systemGroup.getUuid(),
-                systemGroup.getMnemonic(), systemGroup.getMnemonicEquivalence(), systemGroup.getOrdering(),
-                systemGroup.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.TRUE,
-                when, username, null);
-        systemGroupRepository.createSystemGroup(systemGroup);
+        // delete structure
+        // create audit
+        SystemGroup systemGroup = iSystemGroupRepository.findByUuid(uuid);
+        systemGroup.setDeleted(Boolean.TRUE);
+        systemGroup.setAttributesProcessed(when, username, null);
+        systemGroupRepository.updateSystemGroup(systemGroup);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, systemGroup);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<SystemGroup> previouses = iSystemGroupRepository.findPreviousByUuidAndId(uuid, systemGroup.getId());
-        SystemGroup previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SYSTEMGROUP.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        SystemGroup previous = new SystemGroup(previousAuditStructure);
 
         // additional
         //     will propagate to sub structures
-        namesService.deleteNames(systemGroup, username);
+        namesService.deleteNames(systemGroup, username, holderStructures);
 
         List<StructureElementCommand> commands = Lists.newArrayList();
-        List<System> systems = iSystemRepository.findLatestNotDeletedByParent(uuid);
+        List<System> systems = iSystemRepository.findNotDeletedByParent(systemGroup.getId());
         for (System system : systems) {
             commands.add(new StructureElementCommand(system.getUuid(), Type.SYSTEM, null, null, null, null));
         }
diff --git a/src/main/java/org/openepics/names/service/SystemService.java b/src/main/java/org/openepics/names/service/SystemService.java
index 6d8794acd504fe86bc396f5948b6ec45eda94e63..d4480888738fbac0c75f014fe710a80e3c8f1aa8 100644
--- a/src/main/java/org/openepics/names/service/SystemService.java
+++ b/src/main/java/org/openepics/names/service/SystemService.java
@@ -26,11 +26,16 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.IAuditStructureRepository;
 import org.openepics.names.repository.ISubsystemRepository;
+import org.openepics.names.repository.ISystemGroupRepository;
 import org.openepics.names.repository.ISystemRepository;
+import org.openepics.names.repository.AuditStructureRepository;
 import org.openepics.names.repository.SystemRepository;
+import org.openepics.names.repository.model.AuditStructure;
 import org.openepics.names.repository.model.Subsystem;
 import org.openepics.names.repository.model.System;
+import org.openepics.names.repository.model.SystemGroup;
 import org.openepics.names.rest.beans.Status;
 import org.openepics.names.rest.beans.Type;
 import org.openepics.names.rest.beans.element.NameElementCommand;
@@ -42,8 +47,8 @@ import org.openepics.names.util.StructureCommand;
 import org.openepics.names.util.StructureElementUtil;
 import org.openepics.names.util.StructureUtil;
 import org.openepics.names.util.TextUtil;
-import org.openepics.names.util.ValidateUtil;
 import org.openepics.names.util.notification.NotificationUtil;
+import org.openepics.names.util.notification.StructureElementNotification;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -61,66 +66,74 @@ public class SystemService {
 
     private static final Logger LOGGER = Logger.getLogger(SystemService.class.getName());
 
+    private NamesService namesService;
+    private SubsystemService subsystemService;
+    private ISystemGroupRepository iSystemGroupRepository;
     private ISystemRepository iSystemRepository;
     private ISubsystemRepository iSubsystemRepository;
+    private IAuditStructureRepository iAuditStructureRepository;
     private SystemRepository systemRepository;
-    private SubsystemService subsystemService;
-    private NamesService namesService;
+    private AuditStructureRepository auditStructureRepository;
 
     @Autowired
     public SystemService(
+            NamesService namesService,
+            SubsystemService subsystemService,
+            ISystemGroupRepository iSystemGroupRepository,
             ISystemRepository iSystemRepository,
             ISubsystemRepository iSubsystemRepository,
+            IAuditStructureRepository iAuditStructureRepository,
             SystemRepository systemRepository,
-            SubsystemService subsystemService,
-            NamesService namesService) {
+            AuditStructureRepository auditStructureRepository) {
+        this.namesService = namesService;
+        this.subsystemService = subsystemService;
+        this.iSystemGroupRepository = iSystemGroupRepository;
         this.iSystemRepository = iSystemRepository;
         this.iSubsystemRepository = iSubsystemRepository;
+        this.iAuditStructureRepository = iAuditStructureRepository;
         this.systemRepository = systemRepository;
-        this.subsystemService = subsystemService;
-        this.namesService = namesService;
+        this.auditStructureRepository = auditStructureRepository;
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification createStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     create structure - approved, latest, not deleted
+        //     create structure
+        //     create audit
         //     additional
         //         automatically create name when system structure is created
-        //         condition on name and structure entry
-        //             system structure should exist (uuid), one entry that is not deleted
-        //             name should not exist (system structure mnemonic path)
-        //         within current transaction
+        //         conditions on name and structure entry
+        //             system structure should exist - mnemonic
+        //             name should not exist         - system structure mnemonic path
         //     return
         //         structure element for created structure
         //         notification
-        //
-        // attributes
-        //     type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
+        UUID uuid = UUID.randomUUID();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // create
-        System system = new System(UUID.randomUUID(), structureElementCommand.getParent(),
+        // create structure
+        // create audit
+        SystemGroup systemGroup = iSystemGroupRepository.findByUuid(structureElementCommand.getParent().toString());
+        System system = new System(uuid, systemGroup.getId(),
                 mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
+                structureElementCommand.getDescription(), Status.APPROVED, Boolean.FALSE,
                 when, username, null);
         systemRepository.createSystem(system);
+        auditStructureRepository.createAuditStructure(new AuditStructure(TextUtil.CREATE, system));
 
         // additional
         boolean hasMnemonic = !StringUtils.isEmpty(system.getMnemonic());
         boolean existsName = hasMnemonic && namesService.existsName(StructureUtil.getMnemonicPath(system, holderStructures));
         if (hasMnemonic && !existsName) {
             NameElementCommand nameElement = new NameElementCommand(null, system.getUuid(), null, null, StructuresService.SYSTEM_STRUCTURE_ONLY);
-            namesService.createName(nameElement, when, username, holderStructures);
+            namesService.createName(nameElement, when, username, holderStructures, system);
         }
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.CREATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.CREATE));
@@ -131,54 +144,42 @@ public class SystemService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username, EssNamingConvention namingConvention, HolderStructures holderStructures) {
+    public StructureElementNotification updateStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            EssNamingConvention namingConvention, HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, not deleted
+        //     update structure
+        //     create audit
         //     previous for notification
         //     additional - update related names
         //     return
         //         structure element for updated structure
         //         notification
-        //
-        // attributes
-        //     uuid, type, parent, mnemonic, ordering, description
-
-        // note
-        //     namingConvention.equivalenceClassRepresentative return null for null input
-        //     rules for mnemonic
 
         String uuid = structureElementCommand.getUuid().toString();
         String mnemonic = structureElementCommand.getMnemonic();
         mnemonic = StringUtils.isEmpty(mnemonic) ? null : mnemonic;
         String equivalenceClassRepresentative = namingConvention.equivalenceClassRepresentative(mnemonic);
 
-        // find
-        List<System> systems = systemRepository.readSystems(Boolean.FALSE, uuid, null, null, null, null, null, null);
-        System system = null;
-        if (ValidateUtil.isSize(systems, 1)) {
-            system = systems.get(0);
-
-            // update not latest
-            system.setLatest(Boolean.FALSE);
-            systemRepository.updateSystem(system);
-        }
-
-        // create
-        system = new System(structureElementCommand.getUuid(), structureElementCommand.getParent(),
-                mnemonic, equivalenceClassRepresentative, structureElementCommand.getOrdering(),
-                structureElementCommand.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.FALSE,
-                when, username, null);
-        systemRepository.createSystem(system);
+        // update structure
+        // create audit
+        System system = iSystemRepository.findByUuid(uuid);
+        system.setMnemonic(mnemonic);
+        system.setMnemonicEquivalence(equivalenceClassRepresentative);
+        system.setOrdering(structureElementCommand.getOrdering());
+        system.setDescription(structureElementCommand.getDescription());
+        systemRepository.updateSystem(system);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.UPDATE, system);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<System> previouses = iSystemRepository.findPreviousByUuidAndId(system.getUuid().toString(), system.getId());
-        System previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SYSTEM.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        System previous = new System(previousAuditStructure);
 
         // additional
-        namesService.updateNames(previous, system, username);
+        namesService.updateNames(previous, system, username, holderStructures);
 
         LOGGER.log(Level.FINE, () -> MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.UPDATE_STRUCTURE, TextUtil.COMMAND, StructureCommand.UPDATE));
 
@@ -188,53 +189,43 @@ public class SystemService {
     }
 
     @Transactional(propagation = Propagation.MANDATORY)
-    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username, HolderStructures holderStructures) {
+    public StructureElementNotification deleteStructure(StructureElementCommand structureElementCommand, Date when, String username,
+            HolderStructures holderStructures) {
+
         // validation outside method
         // transaction
         //     support a current transaction, throw an exception if none exists
-        //     update not latest
-        //     create structure - approved, latest, deleted
+        //     delete structure (update)
+        //     create audit
         //     previous for notification
-        //     additional - delete related names, delete sub structures (and related names)
+        //     additional
+        //         delete related names
+        //         delete sub structures (and related names)
         //     return
         //         structure element for deleted structure
         //         notification
-        //
-        // attributes
-        //     uuid
 
         String uuid = structureElementCommand.getUuid().toString();
 
-        // find
-        List<System> systems = systemRepository.readSystems(Boolean.FALSE, uuid, null, null, null, null, null, null);
-        System system = null;
-        if (ValidateUtil.isSize(systems, 1)) {
-            system = systems.get(0);
-
-            // update not latest
-            system.setLatest(Boolean.FALSE);
-            systemRepository.updateSystem(system);
-        } else {
-            return null;
-        }
-
-        // create
-        system = new System(system.getUuid(), system.getParentUuid(),
-                system.getMnemonic(), system.getMnemonicEquivalence(), system.getOrdering(),
-                system.getDescription(), Status.APPROVED, Boolean.TRUE, Boolean.TRUE,
-                when, username, null);
-        systemRepository.createSystem(system);
+        // delete structure
+        // create audit
+        System system = iSystemRepository.findByUuid(uuid);
+        system.setDeleted(Boolean.TRUE);
+        system.setAttributesProcessed(when, username, null);
+        systemRepository.updateSystem(system);
+        AuditStructure auditStructure = new AuditStructure(TextUtil.DELETE, system);
+        auditStructureRepository.createAuditStructure(auditStructure);
 
         // previous
-        List<System> previouses = iSystemRepository.findPreviousByUuidAndId(uuid, system.getId());
-        System previous = previouses != null && !previouses.isEmpty() ? previouses.get(0) : null;
+        AuditStructure previousAuditStructure = iAuditStructureRepository.findPreviousByAuditTableAndUuidAndAuditId(Type.SYSTEM.name().toLowerCase(), uuid, auditStructure.getAuditId());
+        System previous = new System(previousAuditStructure);
 
         // additional
         //     will propagate to sub structures
-        namesService.deleteNames(system, username);
+        namesService.deleteNames(system, username, holderStructures);
 
         List<StructureElementCommand> commands = Lists.newArrayList();
-        List<Subsystem> subsystems = iSubsystemRepository.findLatestNotDeletedByParent(uuid);
+        List<Subsystem> subsystems = iSubsystemRepository.findNotDeletedByParent(system.getId());
         for (Subsystem subsystem : subsystems) {
             commands.add(new StructureElementCommand(subsystem.getUuid(), Type.SUBSYSTEM, null, null, null, null));
         }
diff --git a/src/main/java/org/openepics/names/util/ExcelUtil.java b/src/main/java/org/openepics/names/util/ExcelUtil.java
index aa6765b0fc2f9769d646823b29ab1b3e33a02ee3..80c2ab75f5b31e37b9ceeb2265e794622205a80b 100644
--- a/src/main/java/org/openepics/names/util/ExcelUtil.java
+++ b/src/main/java/org/openepics/names/util/ExcelUtil.java
@@ -82,7 +82,6 @@ public class ExcelUtil {
             {"DeviceStructure",       "Mnemonic path for for the device structure."},
             {"Name",                  "Name (verbose) of the name entry."},
             {"Status",                "Status of the name entry."},
-            {"Latest",                "If the name entry is latest (with status APPROVED) in its line of entries."},
             {"Deleted",               "If the name entry is deleted."},
             {"When",                  "Date and time when the name entry was created."},
             {"Who",                   "Name (user) of who created the name entry."},
@@ -100,7 +99,6 @@ public class ExcelUtil {
             {"MnemonicPath",          "Mnemonic path of the structure entry."},
             {"Level",                 "Level of the structure entry."},
             {"Status",                "Status of the structure entry."},
-            {"Latest",                "If the structure entry is latest (with status APPROVED) in its line of entries."},
             {"Deleted",               "If the structure entry is deleted."},
             {"When",                  "Date and time when the structure entry was created."},
             {"Who",                   "Name (user) of who created the structure entry."},
@@ -492,18 +490,15 @@ public class ExcelUtil {
                         cell.setCellValue(nameElement.getStatus() != null ? nameElement.getStatus().toString() : null);
                         break;
                     case 9:
-                        cell.setCellValue(nameElement.isLatest());
-                        break;
-                    case 10:
                         cell.setCellValue(nameElement.isDeleted());
                         break;
-                    case 11:
+                    case 10:
                         cell.setCellValue(DateFormat.getDateTimeInstance().format(nameElement.getWhen()));
                         break;
-                    case 12:
+                    case 11:
                         cell.setCellValue(nameElement.getWho());
                         break;
-                    case 13:
+                    case 12:
                         cell.setCellValue(nameElement.getComment());
                         break;
                     default:
@@ -619,18 +614,15 @@ public class ExcelUtil {
                         cell.setCellValue(structureElement.getStatus() != null ? structureElement.getStatus().toString() : null);
                         break;
                     case 9:
-                        cell.setCellValue(structureElement.isLatest());
-                        break;
-                    case 10:
                         cell.setCellValue(structureElement.isDeleted());
                         break;
-                    case 11:
+                    case 10:
                         cell.setCellValue(DateFormat.getDateTimeInstance().format(structureElement.getWhen()));
                         break;
-                    case 12:
+                    case 11:
                         cell.setCellValue(structureElement.getWho());
                         break;
-                    case 13:
+                    case 12:
                         cell.setCellValue(structureElement.getComment());
                         break;
                     default:
diff --git a/src/main/java/org/openepics/names/util/HolderIRepositories.java b/src/main/java/org/openepics/names/util/HolderIRepositories.java
index 855fe2a52e08866dad742c4b527f94a29cd49b7f..b7d545e4821f1c49f8aa1f768eb83cb21e624275 100644
--- a/src/main/java/org/openepics/names/util/HolderIRepositories.java
+++ b/src/main/java/org/openepics/names/util/HolderIRepositories.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -18,6 +18,8 @@
 
 package org.openepics.names.util;
 
+import org.openepics.names.repository.IAuditNameRepository;
+import org.openepics.names.repository.IAuditStructureRepository;
 import org.openepics.names.repository.IDeviceGroupRepository;
 import org.openepics.names.repository.IDeviceTypeRepository;
 import org.openepics.names.repository.IDisciplineRepository;
@@ -38,4 +40,6 @@ public record HolderIRepositories (
         ISubsystemRepository subsystemRepository,
         IDisciplineRepository disciplineRepository,
         IDeviceGroupRepository deviceGroupRepository,
-        IDeviceTypeRepository deviceTypeRepository) {}
+        IDeviceTypeRepository deviceTypeRepository,
+        IAuditNameRepository auditNameRepository,
+        IAuditStructureRepository auditStructureRepository) {}
diff --git a/src/main/java/org/openepics/names/util/HolderRepositories.java b/src/main/java/org/openepics/names/util/HolderRepositories.java
index 11d2697d6edd0fd167ef79cddfe11923e933a9ee..acfb2835087d0c61821fec50241279d318917429 100644
--- a/src/main/java/org/openepics/names/util/HolderRepositories.java
+++ b/src/main/java/org/openepics/names/util/HolderRepositories.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -18,6 +18,8 @@
 
 package org.openepics.names.util;
 
+import org.openepics.names.repository.AuditNameRepository;
+import org.openepics.names.repository.AuditStructureRepository;
 import org.openepics.names.repository.DeviceGroupRepository;
 import org.openepics.names.repository.DeviceTypeRepository;
 import org.openepics.names.repository.DisciplineRepository;
@@ -38,4 +40,6 @@ public record HolderRepositories (
         SubsystemRepository subsystemRepository,
         DisciplineRepository disciplineRepository,
         DeviceGroupRepository deviceGroupRepository,
-        DeviceTypeRepository deviceTypeRepository) {}
+        DeviceTypeRepository deviceTypeRepository,
+        AuditNameRepository auditNameRepository,
+        AuditStructureRepository auditStructureRepository) {}
diff --git a/src/main/java/org/openepics/names/util/HolderStructures.java b/src/main/java/org/openepics/names/util/HolderStructures.java
index 087125c343f716d021aafb1640e7991a970edc62..bc292c049ffeb6311f7110ef2ca89443b61fdeed 100644
--- a/src/main/java/org/openepics/names/util/HolderStructures.java
+++ b/src/main/java/org/openepics/names/util/HolderStructures.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 European Spallation Source ERIC.
+ * Copyright (C) 2024 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
@@ -21,7 +21,6 @@ package org.openepics.names.util;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
 
 import org.openepics.names.repository.model.DeviceGroup;
 import org.openepics.names.repository.model.DeviceType;
@@ -40,24 +39,24 @@ import org.openepics.names.repository.model.SystemGroup;
  */
 public class HolderStructures {
 
-    private HashMap<UUID, SystemGroup> systemGroups;
-    private HashMap<UUID, System>      systems;
-    private HashMap<UUID, Subsystem>   subsystems;
+    private HashMap<Long, SystemGroup> systemGroups;
+    private HashMap<Long, System>      systems;
+    private HashMap<Long, Subsystem>   subsystems;
 
-    private HashMap<UUID, Discipline>  disciplines;
-    private HashMap<UUID, DeviceGroup> deviceGroups;
-    private HashMap<UUID, DeviceType>  deviceTypes;
+    private HashMap<Long, Discipline>  disciplines;
+    private HashMap<Long, DeviceGroup> deviceGroups;
+    private HashMap<Long, DeviceType>  deviceTypes;
 
     private boolean includeDeleted = true;
 
     /**
-    * Public constructor to prepare containers for system and device structure content.
-    *
-    * @param holderIRepositories
-    */
-   public HolderStructures (HolderIRepositories holderIRepositories) {
-       this(holderIRepositories, true);
-   }
+     * Public constructor to prepare containers for system and device structure content.
+     *
+     * @param holderIRepositories
+     */
+    public HolderStructures (HolderIRepositories holderIRepositories) {
+        this(holderIRepositories, true);
+    }
 
     /**
      * Public constructor to prepare containers for system and device structure content.
@@ -74,19 +73,19 @@ public class HolderStructures {
         List<DeviceType> deviceTypesRead = null;
 
         if (includeDeleted) {
-            systemGroupsRead = holderIRepositories.systemGroupRepository().findLatest();
-            systemsRead = holderIRepositories.systemRepository().findLatest();
-            subsystemsRead = holderIRepositories.subsystemRepository().findLatest();
-            disciplinesRead = holderIRepositories.disciplineRepository().findLatest();
-            deviceGroupsRead = holderIRepositories.deviceGroupRepository().findLatest();
-            deviceTypesRead = holderIRepositories.deviceTypeRepository().findLatest();
+            systemGroupsRead = holderIRepositories.systemGroupRepository().findAll();
+            systemsRead = holderIRepositories.systemRepository().findAll();
+            subsystemsRead = holderIRepositories.subsystemRepository().findAll();
+            disciplinesRead = holderIRepositories.disciplineRepository().findAll();
+            deviceGroupsRead = holderIRepositories.deviceGroupRepository().findAll();
+            deviceTypesRead = holderIRepositories.deviceTypeRepository().findAll();
         } else {
-            systemGroupsRead = holderIRepositories.systemGroupRepository().findLatestNotDeleted();
-            systemsRead = holderIRepositories.systemRepository().findLatestNotDeleted();
-            subsystemsRead = holderIRepositories.subsystemRepository().findLatestNotDeleted();
-            disciplinesRead = holderIRepositories.disciplineRepository().findLatestNotDeleted();
-            deviceGroupsRead = holderIRepositories.deviceGroupRepository().findLatestNotDeleted();
-            deviceTypesRead = holderIRepositories.deviceTypeRepository().findLatestNotDeleted();
+            systemGroupsRead = holderIRepositories.systemGroupRepository().findNotDeleted();
+            systemsRead = holderIRepositories.systemRepository().findNotDeleted();
+            subsystemsRead = holderIRepositories.subsystemRepository().findNotDeleted();
+            disciplinesRead = holderIRepositories.disciplineRepository().findNotDeleted();
+            deviceGroupsRead = holderIRepositories.deviceGroupRepository().findNotDeleted();
+            deviceTypesRead = holderIRepositories.deviceTypeRepository().findNotDeleted();
         }
 
         // initial capacity
@@ -102,79 +101,79 @@ public class HolderStructures {
         this.deviceTypes  = new HashMap<>((int)(deviceTypesRead.size()/loadFactor + 2), loadFactor);
 
         for (SystemGroup systemGroup : systemGroupsRead) {
-            this.systemGroups.put(systemGroup.getUuid(), systemGroup);
+            this.systemGroups.put(systemGroup.getId(), systemGroup);
         }
         for (System system : systemsRead) {
-            this.systems.put(system.getUuid(), system);
+            this.systems.put(system.getId(), system);
         }
         for (Subsystem subsystem : subsystemsRead) {
-            this.subsystems.put(subsystem.getUuid(), subsystem);
+            this.subsystems.put(subsystem.getId(), subsystem);
         }
         for (Discipline discipline : disciplinesRead) {
-            this.disciplines.put(discipline.getUuid(), discipline);
+            this.disciplines.put(discipline.getId(), discipline);
         }
         for (DeviceGroup deviceGroup : deviceGroupsRead) {
-            this.deviceGroups.put(deviceGroup.getUuid(), deviceGroup);
+            this.deviceGroups.put(deviceGroup.getId(), deviceGroup);
         }
         for (DeviceType deviceType : deviceTypesRead) {
-            this.deviceTypes.put(deviceType.getUuid(), deviceType);
+            this.deviceTypes.put(deviceType.getId(), deviceType);
         }
     }
 
     /**
      * Find system group name part by uuid.
      *
-     * @param uuid uuid
+     * @param id id
      * @return system group name part
      */
-    public SystemGroup findSystemGroupByUuid(UUID uuid) {
-        return systemGroups.get(uuid);
+    public SystemGroup findSystemGroupById(Long id) {
+        return systemGroups.get(id);
     }
     /**
      * Find system name part by uuid.
      *
-     * @param uuid uuid
+     * @param id id
      * @return system name part
      */
-    public System findSystemByUuid(UUID uuid) {
-        return systems.get(uuid);
+    public System findSystemById(Long id) {
+        return systems.get(id);
     }
     /**
      * Find subsystem name part by uuid.
      *
-     * @param uuid uuid
+     * @param id id
      * @return subsystem name part
      */
-    public Subsystem findSubsystemByUuid(UUID uuid) {
-        return subsystems.get(uuid);
+    public Subsystem findSubsystemById(Long id) {
+        return subsystems.get(id);
     }
 
     /**
      * Find discipline name part by uuid.
      *
-     * @param uuid uuid
+     * @param id id
      * @return discipline name part
      */
-    public Discipline findDisciplineByUuid(UUID uuid) {
-        return disciplines.get(uuid);
+    public Discipline findDisciplineById(Long id) {
+        return disciplines.get(id);
     }
     /**
      * Find device group name part by uuid.
      *
-     * @param uuid uuid
+     * @param id id
      * @return device group name part
      */
-    public DeviceGroup findDeviceGroupByUuid(UUID uuid) {
-        return deviceGroups.get(uuid);
+    public DeviceGroup findDeviceGroupById(Long id) {
+        return deviceGroups.get(id);
     }
     /**
      * Find device type name part by uuid.
      *
-     * @param uuid uuid
+     * @param id id
      * @return device type name part
      */
-    public DeviceType findDeviceTypeByUuid(UUID uuid) {
-        return deviceTypes.get(uuid);
+    public DeviceType findDeviceTypeById(Long id) {
+        return deviceTypes.get(id);
     }
 
     /**
@@ -187,56 +186,56 @@ public class HolderStructures {
     }
 
     /**
-     * Return map with key-value pairs (uuid and system group).
+     * Return map with key-value pairs (id and system group).
      *
-     * @return map with key-value pairs (uuid and system group)
+     * @return map with key-value pairs (id and system group)
      */
-    public Map<UUID, SystemGroup> getUuidSystemGroups() {
+    public Map<Long, SystemGroup> getIdSystemGroups() {
         return systemGroups;
     }
 
     /**
-     * Return map with key-value pairs (uuid and system).
+     * Return map with key-value pairs (id and system).
      *
-     * @return map with key-value pairs (uuid and system)
+     * @return map with key-value pairs (id and system)
      */
-    public Map<UUID, System> getUuidSystems() {
+    public Map<Long, System> getIdSystems() {
         return systems;
     }
 
     /**
-     * Return map with key-value pairs (uuid and subsystem).
+     * Return map with key-value pairs (id and subsystem).
      *
-     * @return map with key-value pairs (uuid and subsystem)
+     * @return map with key-value pairs (id and subsystem)
      */
-    public Map<UUID, Subsystem> getUuidSubsystems() {
+    public Map<Long, Subsystem> getIdSubsystems() {
         return subsystems;
     }
 
     /**
-     * Return map with key-value pairs (uuid and discipline).
+     * Return map with key-value pairs (id and discipline).
      *
-     * @return map with key-value pairs (uuid and discipline)
+     * @return map with key-value pairs (id and discipline)
      */
-    public Map<UUID, Discipline> getUuidDisciplines() {
+    public Map<Long, Discipline> getIdDisciplines() {
         return disciplines;
     }
 
     /**
-     * Return map with key-value pairs (uuid and device group).
+     * Return map with key-value pairs (id and device group).
      *
-     * @return map with key-value pairs (uuid and device group)
+     * @return map with key-value pairs (id and device group)
      */
-    public Map<UUID, DeviceGroup> getUuidDeviceGroups() {
+    public Map<Long, DeviceGroup> getIdDeviceGroups() {
         return deviceGroups;
     }
 
     /**
-     * Return map with key-value pairs (uuid and device type).
+     * Return map with key-value pairs (id and device type).
      *
-     * @return map with key-value pairs (uuid and device type)
+     * @return map with key-value pairs (id and device type)
      */
-    public Map<UUID, DeviceType> getUuidDeviceTypes() {
+    public Map<Long, DeviceType> getIdDeviceTypes() {
         return deviceTypes;
     }
 
diff --git a/src/main/java/org/openepics/names/util/NameElementUtil.java b/src/main/java/org/openepics/names/util/NameElementUtil.java
index 1e511320edccbecebb3fdce9937dadf390435569..7f60743238cd469d4fe172de4f5fef08857523c1 100644
--- a/src/main/java/org/openepics/names/util/NameElementUtil.java
+++ b/src/main/java/org/openepics/names/util/NameElementUtil.java
@@ -22,8 +22,10 @@ import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
+import org.openepics.names.repository.model.AuditName;
 import org.openepics.names.repository.model.DeviceType;
 import org.openepics.names.repository.model.Name;
+import org.openepics.names.repository.model.Structure;
 import org.openepics.names.repository.model.Subsystem;
 import org.openepics.names.repository.model.System;
 import org.openepics.names.repository.model.SystemGroup;
@@ -56,16 +58,31 @@ public class NameElementUtil {
         throw new IllegalStateException("Utility class");
     }
 
+    /**
+     * Populate and return list of name elements for list of names.
+     *
+     * @param auditNames audit names
+     * @param holderStructures container for system and device structure content
+     * @return list of name elements
+     */
+    public static List<NameElement> getNameElementsForAuditNames(List<AuditName> auditNames, HolderStructures holderStructures) {
+        List<NameElement> nameElements = Lists.newArrayList();
+        for (AuditName auditName : auditNames) {
+            nameElements.add(NameElementUtil.getNameElement(auditName.getNonAuditName(), holderStructures));
+        }
+        return nameElements;
+    }
     /**
      * Populate and return list of name elements for list of names.
      *
      * @param names names
+     * @param holderStructures container for system and device structure content
      * @return list of name elements
      */
-    public static List<NameElement> getNameElements(List<Name> names) {
+    public static List<NameElement> getNameElements(List<Name> names, HolderStructures holderStructures) {
         List<NameElement> nameElements = Lists.newArrayList();
         for (Name name : names) {
-            nameElements.add(NameElementUtil.getNameElement(name));
+            nameElements.add(NameElementUtil.getNameElement(name, holderStructures));
         }
         return nameElements;
     }
@@ -74,23 +91,140 @@ public class NameElementUtil {
      * Populate and return name element for name.
      *
      * @param name name
+     * @param holderStructures container for system and device structure content
+     * @return name element
+     */
+    public static NameElement getNameElement(Name name, HolderStructures holderStructures) {
+        return getNameElement(name, holderStructures, null);
+    }
+    /**
+     * Populate and return name element for name.
+     *
+     * @param name name
+     * @param structure (system) structure
+     * @return name element
+     */
+    public static NameElement getNameElement(Name name, Structure structure) {
+        return getNameElement(name, null, structure);
+    }
+    /**
+     * Populate and return name element for name.
+     *
+     * @param name name
+     * @param holderStructures container for system and device structure content
+     * @param structure (system) structure
      * @return name element
      */
-    public static NameElement getNameElement(Name name) {
-        if (name == null) {
+    public static NameElement getNameElement(Name name, HolderStructures holderStructures, Structure structure) {
+        if (name == null || (holderStructures == null && structure == null)) {
+            return null;
+        }
+        if (structure != null && !(structure instanceof SystemGroup || structure instanceof System || structure instanceof Subsystem)) {
             return null;
         }
 
+        UUID parentSystemStructureUuid = null;
+        UUID parentDeviceStructureUuid = null;
+
+        if (structure != null) {
+            parentSystemStructureUuid = structure.getUuid();
+        } else {
+            parentSystemStructureUuid = getParentSystemStructureUuid(name, holderStructures);
+            parentDeviceStructureUuid = name.getDeviceTypeId() != null ? holderStructures.findDeviceTypeById(name.getDeviceTypeId()).getUuid() : null;
+        }
+
         return getNameElement(
-                name.getUuid(), NameUtil.getParentSystemStructure(name), name.getDeviceTypeUuid(),
+                name.getUuid(), parentSystemStructureUuid, parentDeviceStructureUuid,
                 name.getInstanceIndex(), name.getDescription(),
                 NamingConventionUtil.extractMnemonicPathSystemStructure(name.getConventionName()),
                 NamingConventionUtil.extractMnemonicPathDeviceStructure(name.getConventionName()),
                 name.getConventionName(),
-                Status.APPROVED, name.isLatest(), name.isDeleted(),
+                name.getStatus(), name.isDeleted(),
                 name.getRequested(), name.getRequestedBy(), name.getRequestedComment());
     }
 
+    /**
+     * Return UUID for parent system structure.
+     *
+     * @param name name
+     * @param holderStructures container for system and device structure content
+     * @return uuid
+     */
+    public static UUID getParentSystemStructureUuid(Name name, HolderStructures holderStructures) {
+        return name.getSubsystemId() != null
+                ? holderStructures.findSubsystemById(name.getSubsystemId()).getUuid()
+                : name.getSystemId() != null
+                    ? holderStructures.findSystemById(name.getSystemId()).getUuid()
+                    : name.getSystemGroupId() != null
+                        ? holderStructures.findSystemGroupById(name.getSystemGroupId()).getUuid()
+                        : null;
+    }
+
+    /**
+     * Return UUID for system group or null if non-existent.
+     *
+     * @param name name
+     * @param holderStructures container for system and device structure content
+     * @return uuid
+     */
+    public static UUID getSystemGroupUuid(Name name, HolderStructures holderStructures) {
+        if (name == null || name.getSystemGroupId() == null ||  holderStructures == null) {
+            return null;
+        }
+
+        return name.getSystemGroupId() != null
+                ? holderStructures.findSystemGroupById(name.getSystemGroupId()).getUuid()
+                : null;
+    }
+    /**
+     * Return UUID for system or null if non-existent.
+     *
+     * @param name name
+     * @param holderStructures container for system and device structure content
+     * @return uuid
+     */
+    public static UUID getSystemUuid(Name name, HolderStructures holderStructures) {
+        if (name == null || name.getSystemId() == null ||  holderStructures == null) {
+            return null;
+        }
+
+        return name.getSystemId() != null
+                ? holderStructures.findSystemById(name.getSystemId()).getUuid()
+                : null;
+    }
+    /**
+     * Return UUID for subsystem or null if non-existent.
+     *
+     * @param name name
+     * @param holderStructures container for system and device structure content
+     * @return uuid
+     */
+    public static UUID getSubsystemUuid(Name name, HolderStructures holderStructures) {
+        if (name == null || name.getSubsystemId() == null ||  holderStructures == null) {
+            return null;
+        }
+
+        return name.getSubsystemId() != null
+                ? holderStructures.findSubsystemById(name.getSubsystemId()).getUuid()
+                : null;
+    }
+    /**
+     * Return UUID for device type or null if non-existent.
+     *
+     * @param name name
+     * @param holderStructures container for system and device structure content
+     * @return uuid
+     */
+    public static UUID getDeviceTypeUuid(Name name, HolderStructures holderStructures) {
+        if (name == null || name.getDeviceTypeId() == null || holderStructures == null) {
+            return null;
+        }
+
+        return name.getDeviceTypeId() != null
+                ? holderStructures.findDeviceTypeById(name.getDeviceTypeId()).getUuid()
+                : null;
+    }
+
     /**
      * Populate and return name element.
      *
@@ -103,7 +237,6 @@ public class NameElementUtil {
      * @param deviceStructure device structure mnemonic path
      * @param name name
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param when when
      * @param who who
@@ -114,14 +247,14 @@ public class NameElementUtil {
             UUID uuid, UUID parentSystemStructure, UUID parentDeviceStructure,
             String index,  String description,
             String systemStructure, String deviceStructure, String name,
-            Status status, Boolean latest, Boolean deleted,
+            Status status, Boolean deleted,
             Date when, String who, String comment) {
 
         return new NameElement(
                 uuid, parentSystemStructure, parentDeviceStructure,
                 index, description,
                 systemStructure, deviceStructure, name,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
     }
 
@@ -157,12 +290,12 @@ public class NameElementUtil {
         // find out system group, system, subsystem
         //     one of the three expected to be non-null, other two expected to be null
 
-        SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(nameElement.getParentSystemStructure().toString());
-        System      system      = holderIRepositories.systemRepository().findLatestByUuid(nameElement.getParentSystemStructure().toString());
-        Subsystem   subsystem   = holderIRepositories.subsystemRepository().findLatestByUuid(nameElement.getParentSystemStructure().toString());
+        SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findByUuid(nameElement.getParentSystemStructure().toString());
+        System      system      = holderIRepositories.systemRepository().findByUuid(nameElement.getParentSystemStructure().toString());
+        Subsystem   subsystem   = holderIRepositories.subsystemRepository().findByUuid(nameElement.getParentSystemStructure().toString());
         DeviceType  deviceType  = null;
         if (nameElement.getParentDeviceStructure() != null) {
-            deviceType = holderIRepositories.deviceTypeRepository().findLatestByUuid(nameElement.getParentDeviceStructure().toString());
+            deviceType = holderIRepositories.deviceTypeRepository().findByUuid(nameElement.getParentDeviceStructure().toString());
         }
 
         String derivedName = null;
diff --git a/src/main/java/org/openepics/names/util/NameUtil.java b/src/main/java/org/openepics/names/util/NameUtil.java
index a64f650a622e0845489500ff4498d2700d542437..edb79298e137052ef715df67edcb844975b07feb 100644
--- a/src/main/java/org/openepics/names/util/NameUtil.java
+++ b/src/main/java/org/openepics/names/util/NameUtil.java
@@ -18,11 +18,8 @@
 
 package org.openepics.names.util;
 
-import java.util.UUID;
-
 import org.apache.commons.lang3.StringUtils;
 import org.openepics.names.repository.model.DeviceType;
-import org.openepics.names.repository.model.Name;
 import org.openepics.names.repository.model.Subsystem;
 import org.openepics.names.repository.model.System;
 import org.openepics.names.repository.model.SystemGroup;
@@ -42,85 +39,22 @@ public class NameUtil {
     }
 
     /**
-     * Return level of system structure for name.
-     * <ul>
-     * <li>1  <--> system group</li>
-     * <li>2  <--> system</li>
-     * <li>3  <--> subsystem</li>
-     * <li>-1 <--> invalid</li>
-     * </ul>
-     *
-     * @param name name content
-     * @return level of system structure
-     */
-    public static int getLevelSystemStructure(Name name) {
-        if (name == null) {
-            return -1;
-        }
-
-        int count = 0;
-        if (name.getSystemGroupUuid() != null) {
-            count++;
-        }
-        if (name.getSystemUuid() != null) {
-            count++;
-        }
-        if (name.getSubsystemUuid() != null) {
-            count++;
-        }
-        if (count != 1) {
-            return -1;
-        }
-
-        return name.getSubsystemUuid() != null
-                ? 3
-                : name.getSystemUuid() != null
-                        ? 2
-                        : name.getSystemGroupUuid() != null
-                                ? 1
-                                : -1;
-    }
-
-    /**
-     * Return level of device structure for name.
-     * <ul>
-     * <li>3  <--> device type</li>
-     * <li>-1 <--> invalid</li>
-     * </ul>
+     * Return convention name for system and device structure mnemonic paths and index.
      *
-     * @param name content
-     * @return level of device structure
+     * @param systemStructure system structure mnemonic path
+     * @param deviceStructure device structure mnemonic path
+     * @param index index
+     * @return convention name
      */
-    public static int getLevelDeviceStructure(Name name) {
-        if (name == null) {
-            return -1;
-        }
-
-        return name.getDeviceTypeUuid() != null
-                ? 3
-                : -1;
+    public static String getName(String systemStructure, String deviceStructure, String index) {
+        return !StringUtils.isEmpty(systemStructure)
+                ? !StringUtils.isEmpty(deviceStructure) && !StringUtils.isEmpty(index)
+                    ? systemStructure + NamingConventionUtil.DELIMITER_EXTRA + deviceStructure + NamingConventionUtil.DELIMITER_INTRA + index
+                    : systemStructure
+                : null;
     }
 
-    /**
-     * Return UUID for parent system structure.
-     *
-     * @param name name
-     * @return uuid
-     */
-    public static UUID getParentSystemStructure(Name name) {
-        if (name == null) {
-            return null;
-        }
-
-        return name.getSubsystemUuid() != null
-                ? name.getSubsystemUuid()
-                : name.getSystemUuid() != null
-                    ? name.getSystemUuid()
-                    : name.getSystemGroupUuid() != null
-                        ? name.getSystemGroupUuid()
-                        : null;
-
-    }
+    // ----------------------------------------------------------------------------------------------------
 
     /**
      * Return convention name given system group, device type and index.
@@ -170,20 +104,4 @@ public class NameUtil {
                 index);
     }
 
-    /**
-     * Return convention name for system and device structure mnemonic paths and index.
-     *
-     * @param systemStructure system structure mnemonic path
-     * @param deviceStructure device structure mnemonic path
-     * @param index index
-     * @return convention name
-     */
-    public static String getName(String systemStructure, String deviceStructure, String index) {
-        return !StringUtils.isEmpty(systemStructure)
-                ? !StringUtils.isEmpty(deviceStructure) && !StringUtils.isEmpty(index)
-                    ? systemStructure + NamingConventionUtil.DELIMITER_EXTRA + deviceStructure + NamingConventionUtil.DELIMITER_INTRA + index
-                    : systemStructure
-                : null;
-    }
-
 }
diff --git a/src/main/java/org/openepics/names/util/StructureElementUtil.java b/src/main/java/org/openepics/names/util/StructureElementUtil.java
index dff1ff6d9f0f0fe8a8c8bb97b7edcd0ba07a7b1b..9c22f317d32c377531ee126af1e2671a179ce236 100644
--- a/src/main/java/org/openepics/names/util/StructureElementUtil.java
+++ b/src/main/java/org/openepics/names/util/StructureElementUtil.java
@@ -22,6 +22,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.UUID;
 
+import org.openepics.names.repository.model.AuditStructure;
 import org.openepics.names.repository.model.DeviceGroup;
 import org.openepics.names.repository.model.DeviceType;
 import org.openepics.names.repository.model.Discipline;
@@ -56,6 +57,24 @@ public class StructureElementUtil {
         throw new IllegalStateException("Utility class");
     }
 
+    /**
+     * Populate and return list of structure elements for audit structures.
+     *
+     * @param auditStructures audit structures
+     * @param holderStructures holder of system and device structure content
+     * @param structureChoice whether to consider content from structure perspective or history perspective.
+     *                        Structure perspective will give mnemonic path.
+     *                        History perspective may give empty mnemonic path as non-trivial to find out for history.
+     *                        If choice not given then default as structure perspective (processed).
+     * @return list of structure elements
+     */
+    public static List<StructureElement> getStructureElementsForAuditStructures(List<AuditStructure> auditStructures, HolderStructures holderStructures, StructureChoice structureChoice) {
+        List<StructureElement> structureElements = Lists.newArrayList();
+        for (AuditStructure auditStructure : auditStructures) {
+            structureElements.add(getStructureElementProcessed(auditStructure, holderStructures, structureChoice));
+        }
+        return structureElements;
+    }
     /**
      * Populate and return list of structure elements for system groups.
      *
@@ -166,6 +185,57 @@ public class StructureElementUtil {
         return structureElements;
     }
 
+    /**
+     * Populate and return structure element for audit structure with focus on processed.
+     *
+     * @param auditStructure audit structure
+     * @param holderStructures holder of system and device structure content
+     * @param structureChoice whether to consider content from structure perspective or history perspective
+     * @return structure element
+     */
+    public static StructureElement getStructureElementProcessed(AuditStructure auditStructure, HolderStructures holderStructures, StructureChoice structureChoice) {
+        if (auditStructure == null) {
+            return null;
+        }
+
+        // find out attributes as audit table is shared for system and device structure content
+        //     mnemonic path ambiguous if considered in past
+        Type type = null;
+        UUID parent = null;
+        String mnemonicPath = null;
+        Integer level = null;
+
+        if (TextUtil.SYSTEMGROUP.equals(auditStructure.getAuditTable())) {
+            type = Type.SYSTEMGROUP;
+            level = 1;
+        } else if (TextUtil.SYSTEM.equals(auditStructure.getAuditTable())) {
+            type = Type.SYSTEM;
+            parent = holderStructures.findSystemGroupById(auditStructure.getParentId()).getUuid();
+            level = 2;
+        } else if (TextUtil.SUBSYSTEM.equals(auditStructure.getAuditTable())) {
+            type = Type.SUBSYSTEM;
+            parent = holderStructures.findSystemById(auditStructure.getParentId()).getUuid();
+            level = 3;
+        } else if (TextUtil.DISCIPLINE.equals(auditStructure.getAuditTable())) {
+            type = Type.DISCIPLINE;
+            level = 1;
+        } else if (TextUtil.DEVICEGROUP.equals(auditStructure.getAuditTable())) {
+            type = Type.DEVICEGROUP;
+            parent = holderStructures.findDisciplineById(auditStructure.getParentId()).getUuid();
+            level = 2;
+        } else if (TextUtil.DEVICETYPE.equals(auditStructure.getAuditTable())) {
+            type = Type.DEVICETYPE;
+            parent = holderStructures.findDeviceGroupById(auditStructure.getParentId()).getUuid();
+            level = 3;
+        }
+
+        return getStructureElement(
+                auditStructure.getUuid(), type, parent,
+                auditStructure.getMnemonic(), auditStructure.getOrdering(), auditStructure.getDescription(),
+                mnemonicPath, level,
+                auditStructure.getStatus(), auditStructure.isDeleted(),
+                auditStructure.getProcessed(), auditStructure.getProcessedBy(), auditStructure.getProcessedComment());
+    }
     /**
      * Populate and return structure element for system group with focus on processed.
      *
@@ -181,9 +251,8 @@ public class StructureElementUtil {
 
         // mnemonic path
         //     ambiguous if considered in past (requested, processed)
-        //     not history of structure
-        //     latest & approved status
-        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !(systemGroup.isLatest() && Status.APPROVED.equals(systemGroup.getStatus()))
+        //     not for history of structure (obsolete)
+        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !Status.APPROVED.equals(systemGroup.getStatus())
                 ? null
                 : StructureUtil.getMnemonicPath(systemGroup, holderStructures);
 
@@ -191,7 +260,7 @@ public class StructureElementUtil {
                 systemGroup.getUuid(), Type.SYSTEMGROUP, null,
                 systemGroup.getMnemonic(), systemGroup.getOrdering(), systemGroup.getDescription(),
                 mnemonicPath, 1,
-                systemGroup.getStatus(), systemGroup.isLatest(), systemGroup.isDeleted(),
+                systemGroup.getStatus(), systemGroup.isDeleted(),
                 systemGroup.getProcessed(), systemGroup.getProcessedBy(), systemGroup.getProcessedComment());
     }
     /**
@@ -209,17 +278,16 @@ public class StructureElementUtil {
 
         // mnemonic path
         //     ambiguous if considered in past (requested, processed)
-        //     not history of structure
-        //     latest & approved status
-        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !(system.isLatest() && Status.APPROVED.equals(system.getStatus()))
+        //     not for history of structure (obsolete)
+        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !Status.APPROVED.equals(system.getStatus())
                 ? null
                 : StructureUtil.getMnemonicPath(system, holderStructures);
 
         return getStructureElement(
-                system.getUuid(), Type.SYSTEM, system.getParentUuid(),
+                system.getUuid(), Type.SYSTEM,   holderStructures.findSystemGroupById(system.getParentId()).getUuid(),
                 system.getMnemonic(), system.getOrdering(), system.getDescription(),
                 mnemonicPath, 2,
-                system.getStatus(), system.isLatest(), system.isDeleted(),
+                system.getStatus(), system.isDeleted(),
                 system.getProcessed(), system.getProcessedBy(), system.getProcessedComment());
     }
     /**
@@ -237,17 +305,16 @@ public class StructureElementUtil {
 
         // mnemonic path
         //     ambiguous if considered in past (requested, processed)
-        //     not history of structure
-        //     latest & approved status
-        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !(subsystem.isLatest() && Status.APPROVED.equals(subsystem.getStatus()))
+        //     not for history of structure (obsolete)
+        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !Status.APPROVED.equals(subsystem.getStatus())
                 ? null
                 : StructureUtil.getMnemonicPath(subsystem, holderStructures);
 
         return getStructureElement(
-                subsystem.getUuid(), Type.SUBSYSTEM, subsystem.getParentUuid(),
+                subsystem.getUuid(), Type.SUBSYSTEM, holderStructures.findSystemById(subsystem.getParentId()).getUuid(),
                 subsystem.getMnemonic(), subsystem.getOrdering(), subsystem.getDescription(),
                 mnemonicPath, 3,
-                subsystem.getStatus(), subsystem.isLatest(), subsystem.isDeleted(),
+                subsystem.getStatus(), subsystem.isDeleted(),
                 subsystem.getProcessed(), subsystem.getProcessedBy(), subsystem.getProcessedComment());
     }
 
@@ -266,9 +333,8 @@ public class StructureElementUtil {
 
         // mnemonic path
         //     ambiguous if considered in past (requested, processed)
-        //     not history of structure
-        //     latest & approved status
-        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !(discipline.isLatest() && Status.APPROVED.equals(discipline.getStatus()))
+        //     not for history of structure (obsolete)
+        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !Status.APPROVED.equals(discipline.getStatus())
                 ? null
                 : StructureUtil.getMnemonicPath(discipline, holderStructures);
 
@@ -276,7 +342,7 @@ public class StructureElementUtil {
                 discipline.getUuid(), Type.DISCIPLINE, null,
                 discipline.getMnemonic(), discipline.getOrdering(), discipline.getDescription(),
                 mnemonicPath, 1,
-                discipline.getStatus(), discipline.isLatest(), discipline.isDeleted(),
+                discipline.getStatus(), discipline.isDeleted(),
                 discipline.getProcessed(), discipline.getProcessedBy(), discipline.getProcessedComment());
     }
     /**
@@ -294,17 +360,16 @@ public class StructureElementUtil {
 
         // mnemonic path
         //     ambiguous if considered in past (requested, processed)
-        //     not history of structure
-        //     latest & approved status
-        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !(deviceGroup.isLatest() && Status.APPROVED.equals(deviceGroup.getStatus()))
+        //     not for history of structure (obsolete)
+        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !Status.APPROVED.equals(deviceGroup.getStatus())
                 ? null
                 : StructureUtil.getMnemonicPath(deviceGroup, holderStructures);
 
         return getStructureElement(
-                deviceGroup.getUuid(), Type.DEVICEGROUP, deviceGroup.getParentUuid(),
+                deviceGroup.getUuid(), Type.DEVICEGROUP, holderStructures.findDisciplineById(deviceGroup.getParentId()).getUuid(),
                 deviceGroup.getMnemonic(), deviceGroup.getOrdering(), deviceGroup.getDescription(),
                 mnemonicPath, 2,
-                deviceGroup.getStatus(), deviceGroup.isLatest(), deviceGroup.isDeleted(),
+                deviceGroup.getStatus(), deviceGroup.isDeleted(),
                 deviceGroup.getProcessed(), deviceGroup.getProcessedBy(), deviceGroup.getProcessedComment());
     }
     /**
@@ -322,20 +387,21 @@ public class StructureElementUtil {
 
         // mnemonic path
         //     ambiguous if considered in past (requested, processed)
-        //     not history of structure
-        //     latest & approved status
-        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !(deviceType.isLatest() && Status.APPROVED.equals(deviceType.getStatus()))
+        //     not for history of structure (obsolete)
+        String mnemonicPath = StructureChoice.HISTORY.equals(structureChoice) || !Status.APPROVED.equals(deviceType.getStatus())
                 ? null
                 : StructureUtil.getMnemonicPath(deviceType, holderStructures);
 
         return getStructureElement(
-                deviceType.getUuid(), Type.DEVICETYPE, deviceType.getParentUuid(),
+                deviceType.getUuid(), Type.DEVICETYPE, holderStructures.findDeviceGroupById(deviceType.getParentId()).getUuid(),
                 deviceType.getMnemonic(), deviceType.getOrdering(), deviceType.getDescription(),
                 mnemonicPath, 3,
-                deviceType.getStatus(), deviceType.isLatest(), deviceType.isDeleted(),
+                deviceType.getStatus(), deviceType.isDeleted(),
                 deviceType.getProcessed(), deviceType.getProcessedBy(), deviceType.getProcessedComment());
     }
 
+    // ----------------------------------------------------------------------------------------------------
+
     /**
      * Populate and return structure element.
      *
@@ -348,7 +414,6 @@ public class StructureElementUtil {
      * @param mnemonicPath mnemonic path
      * @param level level
      * @param status status
-     * @param latest latest
      * @param deleted deleted
      * @param when when
      * @param who who
@@ -359,14 +424,14 @@ public class StructureElementUtil {
             UUID uuid, Type type, UUID parent,
             String mnemonic, Integer ordering, String description,
             String mnemonicPath, Integer level,
-            Status status, Boolean latest, Boolean deleted,
+            Status status, Boolean deleted,
             Date when, String who, String comment) {
 
         return new StructureElement(
                 uuid, type, parent,
                 mnemonic, ordering, description,
                 mnemonicPath, level,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
     }
 
diff --git a/src/main/java/org/openepics/names/util/StructureUtil.java b/src/main/java/org/openepics/names/util/StructureUtil.java
index 45536727a3556b745790835d146f636d76c66647..de74b3b38b7d7de8f30662dcf716d6dc159a4503 100644
--- a/src/main/java/org/openepics/names/util/StructureUtil.java
+++ b/src/main/java/org/openepics/names/util/StructureUtil.java
@@ -91,7 +91,7 @@ public class StructureUtil {
             return null;
         }
 
-        System system = holderStructures.findSystemByUuid(subsystem.getParentUuid());
+        System system = holderStructures.findSystemById(subsystem.getParentId());
         return system != null
                 ? system.getMnemonic() + "-" + subsystem.getMnemonic()
                 : null;
@@ -124,7 +124,7 @@ public class StructureUtil {
             return null;
         }
 
-        Discipline discipline = holderStructures.findDisciplineByUuid(deviceGroup.getParentUuid());
+        Discipline discipline = holderStructures.findDisciplineById(deviceGroup.getParentId());
         return discipline != null
                 ? discipline.getMnemonic()
                 : null;
@@ -142,9 +142,9 @@ public class StructureUtil {
             return null;
         }
 
-        DeviceGroup deviceGroup = holderStructures.findDeviceGroupByUuid(deviceType.getParentUuid());
+        DeviceGroup deviceGroup = holderStructures.findDeviceGroupById(deviceType.getParentId());
         Discipline  discipline  = deviceGroup != null
-                ? holderStructures.findDisciplineByUuid(deviceGroup.getParentUuid())
+                ? holderStructures.findDisciplineById(deviceGroup.getParentId())
                 : null;
         return discipline != null && deviceGroup != null
                 ? discipline.getMnemonic() + "-" + deviceType.getMnemonic()
@@ -164,7 +164,7 @@ public class StructureUtil {
     public static List<String> getMnemonicPathsSystemGroup(HolderStructures holderStructures, boolean mnemonicEquivalence, EssNamingConvention namingConvention) {
         List<String> mnemonicPaths = new ArrayList<>();
         String value = null;
-        for (Entry<UUID, SystemGroup> entry : holderStructures.getUuidSystemGroups().entrySet()) {
+        for (Entry<Long, SystemGroup> entry : holderStructures.getIdSystemGroups().entrySet()) {
             if (!StringUtils.isEmpty(entry.getValue().getMnemonic())) {
                 value = entry.getValue().getMnemonic();
             }
@@ -189,7 +189,7 @@ public class StructureUtil {
     public static List<String> getMnemonicPathsSystem(HolderStructures holderStructures, boolean mnemonicEquivalence, EssNamingConvention namingConvention) {
         List<String> mnemonicPaths = new ArrayList<>();
         String value = null;
-        for (Entry<UUID, System> entry : holderStructures.getUuidSystems().entrySet()) {
+        for (Entry<Long, System> entry : holderStructures.getIdSystems().entrySet()) {
             value = entry.getValue().getMnemonic();
 
             if (mnemonicEquivalence) {
@@ -212,8 +212,8 @@ public class StructureUtil {
     public static List<String> getMnemonicPathsSubsystem(HolderStructures holderStructures, boolean mnemonicEquivalence, EssNamingConvention namingConvention) {
         List<String> mnemonicPaths = new ArrayList<>();
         String value = null;
-        for (Entry<UUID, Subsystem> entry : holderStructures.getUuidSubsystems().entrySet()) {
-            System system = holderStructures.findSystemByUuid(entry.getValue().getParentUuid());
+        for (Entry<Long, Subsystem> entry : holderStructures.getIdSubsystems().entrySet()) {
+            System system = holderStructures.findSystemById(entry.getValue().getParentId());
             value = system.getMnemonic() + "-" + entry.getValue().getMnemonic();
 
             if (mnemonicEquivalence) {
@@ -236,7 +236,7 @@ public class StructureUtil {
     public static List<String> getMnemonicPathsDiscipline(HolderStructures holderStructures, boolean mnemonicEquivalence, EssNamingConvention namingConvention) {
         List<String> mnemonicPaths = new ArrayList<>();
         String value = null;
-        for (Entry<UUID, Discipline> entry : holderStructures.getUuidDisciplines().entrySet()) {
+        for (Entry<Long, Discipline> entry : holderStructures.getIdDisciplines().entrySet()) {
             if (!StringUtils.isEmpty(entry.getValue().getMnemonic())) {
                 value = entry.getValue().getMnemonic();
             }
@@ -261,9 +261,9 @@ public class StructureUtil {
     public static List<String> getMnemonicPathsDeviceType(HolderStructures holderStructures, boolean mnemonicEquivalence, EssNamingConvention namingConvention) {
         List<String> mnemonicPaths = new ArrayList<>();
         String value = null;
-        for (Entry<UUID, DeviceType> entry : holderStructures.getUuidDeviceTypes().entrySet()) {
-            DeviceGroup deviceGroup = holderStructures.findDeviceGroupByUuid(entry.getValue().getParentUuid());
-            Discipline discipline = holderStructures.findDisciplineByUuid(deviceGroup.getParentUuid());
+        for (Entry<Long, DeviceType> entry : holderStructures.getIdDeviceTypes().entrySet()) {
+            DeviceGroup deviceGroup = holderStructures.findDeviceGroupById(entry.getValue().getParentId());
+            Discipline discipline = holderStructures.findDisciplineById(deviceGroup.getParentId());
             value = discipline.getMnemonic() + "-" + entry.getValue().getMnemonic();
 
             if (mnemonicEquivalence) {
diff --git a/src/main/java/org/openepics/names/util/TextUtil.java b/src/main/java/org/openepics/names/util/TextUtil.java
index 2dcf9e62c0583db19d882cae12c06156661a2630..b47222d11f7dd6417713a40006f8e10a71761601 100644
--- a/src/main/java/org/openepics/names/util/TextUtil.java
+++ b/src/main/java/org/openepics/names/util/TextUtil.java
@@ -29,18 +29,26 @@ public class TextUtil {
 
     public static final String NAMING                          = "Naming";
 
+    // database
+    //     table - see field
+    //     operation
+
+    public static final String CREATE = "create";
+    public static final String UPDATE = "update";
+    public static final String DELETE = "delete";
+
     // field
     //     name, structure
     //         name also field
 
     public static final String NAME                            = "name";
     public static final String STRUCTURE                       = "structure";
-    public static final String SYSTEMGROUP                     = "system group";
+    public static final String SYSTEMGROUP                     = "systemgroup";
     public static final String SYSTEM                          = "system";
     public static final String SUBSYSTEM                       = "subsystem";
     public static final String DISCIPLINE                      = "discipline";
-    public static final String DEVICEGROUP                     = "device group";
-    public static final String DEVICETYPE                      = "device type";
+    public static final String DEVICEGROUP                     = "devicegroup";
+    public static final String DEVICETYPE                      = "devicetype";
 
     public static final String DESCRIPTION                     = "description";
     public static final String INDEX                           = "index";
diff --git a/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java b/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java
index b149030c53add23a9295714b6f0b81106fb1f201..bb04c1a03faacd8869e82fb26da68d280443ab25 100644
--- a/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java
+++ b/src/main/java/org/openepics/names/util/ValidateNameElementUtil.java
@@ -21,7 +21,6 @@ import java.util.List;
 import java.util.UUID;
 
 import org.apache.commons.lang3.StringUtils;
-import org.openepics.names.repository.NameRepository;
 import org.openepics.names.repository.model.DeviceType;
 import org.openepics.names.repository.model.Name;
 import org.openepics.names.repository.model.Subsystem;
@@ -42,7 +41,7 @@ public class ValidateNameElementUtil {
     //         uuid,
     //         systemGroup, system, subsystem, deviceType, systemStructure, deviceStructure,
     //         index, description, name,
-    //         status, latest, deleted,
+    //         status, deleted,
     //         when, who, comment
     //
     //     NameElementCommand
@@ -87,7 +86,7 @@ public class ValidateNameElementUtil {
     }
 
     /**
-     * Validate name element command parameters (input) for create.
+     * Validate name element command input for create.
      *
      * @param nameElementCommand name element command
      */
@@ -96,7 +95,7 @@ public class ValidateNameElementUtil {
     }
 
     /**
-     * Validate name element command parameters (input) for update.
+     * Validate name element command input for update.
      *
      * @param nameElementCommand name element command
      */
@@ -105,16 +104,16 @@ public class ValidateNameElementUtil {
     }
 
     /**
-     * Validate name element command parameters (input) for delete.
+     * Validate name element command input for delete.
      *
-     * @param nameElement name element command
+     * @param nameElement name element command input for given task.
      */
     public static void validateNameElementInputDelete(NameElementCommand nameElementCommand) {
         validateNameElementInput(nameElementCommand, NameCommand.DELETE);
     }
 
     /**
-     * Validate name element command parameters (input).
+     * Validate name element command input for given task.
      *
      * @param nameElement name element command
      * @param nameCommand name command
@@ -175,11 +174,13 @@ public class ValidateNameElementUtil {
      * @param nameElementCommand name element command
      * @param namingConvention naming convention
      * @param holderIRepositories holder repositories
-     * @param nameRepository name repository
+     * @param holderRepositories holder repositories
      * @param holderStructures holder of system and device structure content
      */
-    public static void validateNameElementDataCreate(NameElementCommand nameElementCommand, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, NameRepository nameRepository, HolderStructures holderStructures) {
-        validateNameElementData(nameElementCommand, namingConvention, holderIRepositories, nameRepository, holderStructures, NameCommand.CREATE);
+    public static void validateNameElementDataCreate(NameElementCommand nameElementCommand, EssNamingConvention namingConvention,
+            HolderIRepositories holderIRepositories, HolderRepositories holderRepositories, HolderStructures holderStructures) {
+        validateNameElementData(nameElementCommand, NameCommand.CREATE, namingConvention,
+                holderIRepositories, holderRepositories, holderStructures);
     }
 
     /**
@@ -188,11 +189,13 @@ public class ValidateNameElementUtil {
      * @param nameElementCommand name element command
      * @param namingConvention naming convention
      * @param holderIRepositories holder repositories
-     * @param nameRepository name repositories
+     * @param holderRepositories holder repositories
      * @param holderStructures holder of system and device structure content
      */
-    public static void validateNameElementDataUpdate(NameElementCommand nameElementCommand, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, NameRepository nameRepository, HolderStructures holderStructures) {
-        validateNameElementData(nameElementCommand, namingConvention, holderIRepositories, nameRepository, holderStructures, NameCommand.UPDATE);
+    public static void validateNameElementDataUpdate(NameElementCommand nameElementCommand, EssNamingConvention namingConvention,
+            HolderIRepositories holderIRepositories, HolderRepositories holderRepositories, HolderStructures holderStructures) {
+        validateNameElementData(nameElementCommand, NameCommand.UPDATE, namingConvention,
+                holderIRepositories, holderRepositories, holderStructures);
     }
 
     /**
@@ -201,24 +204,27 @@ public class ValidateNameElementUtil {
      * @param nameElementCommand name element command
      * @param namingConvention naming convention
      * @param holderIRepositories holder repositories
-     * @param nameRepository name repositories
+     * @param holderRepositories holder repositories
      * @param holderStructures holder of system and device structure content
      */
-    public static void validateNameElementDataDelete(NameElementCommand nameElementCommand, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, NameRepository nameRepository, HolderStructures holderStructures) {
-        validateNameElementData(nameElementCommand, namingConvention, holderIRepositories, nameRepository, holderStructures, NameCommand.DELETE);
+    public static void validateNameElementDataDelete(NameElementCommand nameElementCommand, EssNamingConvention namingConvention,
+            HolderIRepositories holderIRepositories, HolderRepositories holderRepositories, HolderStructures holderStructures) {
+        validateNameElementData(nameElementCommand, NameCommand.DELETE, namingConvention,
+                holderIRepositories, holderRepositories, holderStructures);
     }
 
     /**
-     * Validate name element command data.
+     * Validate name element command data for given task.
      *
      * @param nameElementCommand name element command
+     * @param nameCommand name command
      * @param namingConvention naming convention
      * @param holderIRepositories holder repositories
-     * @param nameRepository name repository
+     * @param holderRepositories holder repositories
      * @param holderStructures holder of system and device structure content
-     * @param nameCommand name command
      */
-    private static void validateNameElementData(NameElementCommand nameElementCommand, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, NameRepository nameRepository, HolderStructures holderStructures, NameCommand nameCommand) {
+    private static void validateNameElementData(NameElementCommand nameElementCommand, NameCommand nameCommand, EssNamingConvention namingConvention,
+            HolderIRepositories holderIRepositories, HolderRepositories holderRepositories, HolderStructures holderStructures) {
         // command - attributes
         //     create -       parentSystemStructure, parentDeviceStructure, index, description
         //	   update - uuid, parentSystemStructure, parentDeviceStructure, index, description
@@ -231,7 +237,11 @@ public class ValidateNameElementUtil {
         //    ( - system structure uuid, device structure uuid )
         //      - system structure uuid, device structure uuid, index
 
-        if (ValidateUtil.isAnyNull(nameElementCommand, namingConvention, holderIRepositories, nameRepository, holderStructures, nameCommand)) {
+        if (ValidateUtil.isAnyNull(nameElementCommand, nameCommand, namingConvention,
+                holderIRepositories, holderRepositories, holderStructures)) {
+            return;
+        }
+        if (ValidateUtil.isAnyNull(holderIRepositories.nameRepository())) {
             return;
         }
 
@@ -251,7 +261,7 @@ public class ValidateNameElementUtil {
         //         index                 - index, name
 
         if (ValidateUtil.isAnyEqual(nameCommand, NameCommand.UPDATE, NameCommand.DELETE)) {
-            List<Name> names = nameRepository.readNames(false, uuid.toString(), null, null, null, null, null, null, null);
+            List<Name> names = holderRepositories.nameRepository().readNames(false, uuid.toString(), null, null, null, null, null, null, null);
             ExceptionUtil.validateConditionDataNotFoundException(ValidateUtil.isSize(names, 1),
                     TextUtil.DATA_IS_NOT_FOUND, details, TextUtil.UUID);
         }
@@ -283,14 +293,14 @@ public class ValidateNameElementUtil {
 
             // find out system group, system, subsystem
             //     one of the three expected to be non-null, other two expected to be null
-            systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(parentSystemstructure.toString());
-            system      = holderIRepositories.systemRepository().findLatestByUuid(parentSystemstructure.toString());
-            subsystem   = holderIRepositories.subsystemRepository().findLatestByUuid(parentSystemstructure.toString());
+            systemGroup = holderIRepositories.systemGroupRepository().findByUuid(parentSystemstructure.toString());
+            system      = holderIRepositories.systemRepository().findByUuid(parentSystemstructure.toString());
+            subsystem   = holderIRepositories.subsystemRepository().findByUuid(parentSystemstructure.toString());
 
             // device structure
             if (parentDevicestructure != null) {
                 countDevicestructureIndex++;
-                deviceType = holderIRepositories.deviceTypeRepository().findLatestByUuid(parentDevicestructure.toString());
+                deviceType = holderIRepositories.deviceTypeRepository().findByUuid(parentDevicestructure.toString());
                 ExceptionUtil.validateConditionDataNotFoundException(deviceType != null,
                         TextUtil.DATA_IS_NOT_FOUND, details, TextUtil.PARENTDEVICESTRUCTURE);
                 ExceptionUtil.validateConditionDataDeletedException(!deviceType.isDeleted(),
@@ -328,7 +338,7 @@ public class ValidateNameElementUtil {
 
             // name
             //     ok with same name, name equivalence if same uuid
-            List<Name> names = nameRepository.readNames(false, null, derivedName, null, null, null, null, null, null);
+            List<Name> names = holderRepositories.nameRepository().readNames(false, null, derivedName, null, null, null, null, null, null);
             if (NameCommand.CREATE.equals(nameCommand)) {
                 condition = ValidateUtil.isNullOrEmpty(names);
             } else {
@@ -338,7 +348,7 @@ public class ValidateNameElementUtil {
             ExceptionUtil.validateConditionDataConflictException(condition,
                     TextUtil.CONVENTION_NAME_EXISTS, details, TextUtil.PARENTSYSTEMSTRUCTURE);
 
-            names = nameRepository.readNames(false, null, null, namingConvention.equivalenceClassRepresentative(derivedName), null, null, null, null, null);
+            names = holderRepositories.nameRepository().readNames(false, null, null, namingConvention.equivalenceClassRepresentative(derivedName), null, null, null, null, null);
             if (NameCommand.CREATE.equals(nameCommand)) {
                 condition = ValidateUtil.isNullOrEmpty(names);
             } else {
@@ -364,9 +374,11 @@ public class ValidateNameElementUtil {
      * @param holderRepositories holder repositories
      * @param holderStructures holder of system and device structure content
      *
-     * @see ValidateUtil#validateNameDataCreate(NameElement, EssNamingConvention, HolderIRepositories, NameRepository, HolderStructures)
+     * @see ValidateNameElementUtil#validateNameElementDataCreate(NameElementCommand, EssNamingConvention,
+     *         HolderIRepositories, HolderRepositories, HolderStructures)
      */
-    public static void validateNameDataCreate(String name, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderStructures holderStructures) {
+    public static void validateNameDataCreate(String name, EssNamingConvention namingConvention,
+            HolderRepositories holderRepositories, HolderStructures holderStructures) {
         if (ValidateUtil.isAnyNull(name, namingConvention, holderRepositories, holderStructures)) {
             return;
         }
@@ -410,14 +422,7 @@ public class ValidateNameElementUtil {
             throw ExceptionUtil.createDataNotCorrectException(TextUtil.SYSTEM_STRUCTURE_IS_NOT_CORRECT, details, field);
         }
 
-        SystemGroup systemGroup = null;
-        System system           = null;
-        Subsystem subsystem     = null;
-        DeviceType deviceType   = null;
-
-        String derivedName = null;
-
-        // ensure that system structure parents and device structure parents are available, latest and not deleted
+        // ensure that system structure parents and device structure parents are available and not deleted
         //     if device type
         //     if system group
         //     else
@@ -426,6 +431,13 @@ public class ValidateNameElementUtil {
         //             (if not system then error)
         //         if subsystem
 
+        SystemGroup systemGroup = null;
+        System      system      = null;
+        Subsystem   subsystem   = null;
+        DeviceType  deviceType  = null;
+
+        String derivedName = null;
+
         // device structure
         if (!StringUtils.isEmpty(dt)) {
             List<DeviceType> deviceTypes = holderRepositories.deviceTypeRepository().readDeviceTypes(false, null, null, null, null, mnemonicPathDeviceStructure, null, null);
diff --git a/src/main/java/org/openepics/names/util/ValidateStructureElementUtil.java b/src/main/java/org/openepics/names/util/ValidateStructureElementUtil.java
index 93bda4b047c071b7de8fd07462650eb7aa46bb4e..8695fe5552dc3fe2347c2d7841f7fd5416d90b2b 100644
--- a/src/main/java/org/openepics/names/util/ValidateStructureElementUtil.java
+++ b/src/main/java/org/openepics/names/util/ValidateStructureElementUtil.java
@@ -43,7 +43,7 @@ public class ValidateStructureElementUtil {
     //         type, uuid, parent,
     //         mnemonic, ordering, description,
     //         mnemonic path, level,
-    //         status, latest, deleted,
+    //         status, deleted,
     //         when, who, comment
     //
     //     StructureElementCommand
@@ -121,39 +121,43 @@ public class ValidateStructureElementUtil {
     }
 
     /**
-     * Validate structure element command parameters (input) for create.
+     * Validate structure element command input for create.
      *
      * @param structureElementCommand structure element command
+     * @param namingConvention naming convention
      */
     public static void validateStructureElementInputCreate(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention) {
-        validateStructureElementInput(structureElementCommand, namingConvention, StructureCommand.CREATE);
+        validateStructureElementInput(structureElementCommand, StructureCommand.CREATE, namingConvention);
     }
 
     /**
-     * Validate structure element command parameters (input) for update.
+     * Validate structure element command input for update.
      *
      * @param structureElementCommand structure element command
+     * @param namingConvention naming convention
      */
     public static void validateStructureElementInputUpdate(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention) {
-        validateStructureElementInput(structureElementCommand, namingConvention, StructureCommand.UPDATE);
+        validateStructureElementInput(structureElementCommand, StructureCommand.UPDATE, namingConvention);
     }
 
     /**
-     * Validate structure element command parameters (input) for delete.
+     * Validate structure element command input for delete.
      *
      * @param structureElementCommand structure element command
+     * @param namingConvention naming convention
      */
     public static void validateStructureElementInputDelete(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention) {
-        validateStructureElementInput(structureElementCommand, namingConvention, StructureCommand.DELETE);
+        validateStructureElementInput(structureElementCommand, StructureCommand.DELETE, namingConvention);
     }
 
     /**
-     * Validate structure element command parameters (input).
+     * Validate structure element command input for given task.
      *
      * @param structureElementCommand structure element command
      * @param structureCommand structure command
+     * @param namingConvention naming convention
      */
-    private static void validateStructureElementInput(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention, StructureCommand structureCommand) {
+    private static void validateStructureElementInput(StructureElementCommand structureElementCommand, StructureCommand structureCommand, EssNamingConvention namingConvention) {
         // command - attributes
         //     create  -       type, parent, mnemonic, ordering, description
         //	   update  - uuid, type, parent, mnemonic, ordering, description
@@ -215,9 +219,11 @@ public class ValidateStructureElementUtil {
      * @param holderRepositories holder repositories
      * @param holderStructures holder of system and device structure content
      */
-    public static void validateStructureElementDataCreate(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderStructures holderStructures) {
-        validateStructureElementDataInItself(structureElementCommand, holderRepositories, StructureCommand.CREATE);
-        validateStructureElementDataRelativeOtherData(structureElementCommand, namingConvention, holderRepositories, holderStructures, StructureCommand.CREATE);
+    public static void validateStructureElementDataCreate(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention,
+            HolderRepositories holderRepositories, HolderStructures holderStructures) {
+        validateStructureElementDataInItself(structureElementCommand, StructureCommand.CREATE, holderRepositories);
+        validateStructureElementDataRelativeOtherData(structureElementCommand, StructureCommand.CREATE, namingConvention,
+                holderRepositories, holderStructures);
     }
 
     /**
@@ -228,9 +234,11 @@ public class ValidateStructureElementUtil {
      * @param holderRepositories holder repositories
      * @param holderStructures holder of system and device structure content
      */
-    public static void validateStructureElementDataUpdate(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderStructures holderStructures) {
-        validateStructureElementDataInItself(structureElementCommand, holderRepositories, StructureCommand.UPDATE);
-        validateStructureElementDataRelativeOtherData(structureElementCommand, namingConvention, holderRepositories, holderStructures, StructureCommand.UPDATE);
+    public static void validateStructureElementDataUpdate(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention,
+            HolderRepositories holderRepositories, HolderStructures holderStructures) {
+        validateStructureElementDataInItself(structureElementCommand, StructureCommand.UPDATE, holderRepositories);
+        validateStructureElementDataRelativeOtherData(structureElementCommand, StructureCommand.UPDATE, namingConvention,
+                holderRepositories, holderStructures);
     }
 
     /**
@@ -241,19 +249,22 @@ public class ValidateStructureElementUtil {
      * @param holderRepositories holder repositories
      * @param holderStructures holder of system and device structure content
      */
-    public static void validateStructureElementDataDelete(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderStructures holderStructures) {
-        validateStructureElementDataInItself(structureElementCommand, holderRepositories, StructureCommand.DELETE);
-        validateStructureElementDataRelativeOtherData(structureElementCommand, namingConvention, holderRepositories, holderStructures, StructureCommand.DELETE);
+    public static void validateStructureElementDataDelete(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention,
+            HolderRepositories holderRepositories, HolderStructures holderStructures) {
+        validateStructureElementDataInItself(structureElementCommand, StructureCommand.DELETE, holderRepositories);
+        validateStructureElementDataRelativeOtherData(structureElementCommand, StructureCommand.DELETE, namingConvention,
+                holderRepositories, holderStructures);
     }
 
     /**
-     * Validate structure element command data in itself.
+     * Validate structure element command data in itself for given task.
      *
      * @param structureElementCommand structure element command
-     * @param holderRepositories holder respositories
      * @param structureCommand structure command
+     * @param holderRepositories holder repositories
      */
-    public static void validateStructureElementDataInItself(StructureElementCommand structureElementCommand, HolderRepositories holderRepositories, StructureCommand structureCommand) {
+    public static void validateStructureElementDataInItself(StructureElementCommand structureElementCommand, StructureCommand structureCommand,
+            HolderRepositories holderRepositories) {
         // command - attributes
         //     create  -       type, parent, mnemonic, ordering, description
         //	   update  - uuid, type, parent, mnemonic, ordering, description
@@ -263,11 +274,9 @@ public class ValidateStructureElementUtil {
         //
         // check structure element data in itself
         //     update, delete
-        //         definitely (not possibly)
-        //             no pending entry waiting to be handled (pending with higher id than currently approved)
-        //         uuid - approved, latest, not deleted - list size 1
+        //         uuid - not deleted - list size 1
 
-        if (ValidateUtil.isAnyNull(structureElementCommand, holderRepositories, structureCommand)) {
+        if (ValidateUtil.isAnyNull(structureElementCommand, structureCommand, holderRepositories)) {
             return;
         }
 
@@ -325,15 +334,16 @@ public class ValidateStructureElementUtil {
     }
 
     /**
-     * Validate structure element command data relative other data.
+     * Validate structure element command data relative other data for given task.
      *
      * @param structureElementCommand structure element command
+     * @param structureCommand structure command
      * @param namingConvention naming convention
      * @param holderRepositories holder repositories
      * @param holderStructures holder of system and device structure content
-     * @param structureCommand structure command
      */
-    public static void validateStructureElementDataRelativeOtherData(StructureElementCommand structureElementCommand, EssNamingConvention namingConvention, HolderRepositories holderRepositories, HolderStructures holderStructures, StructureCommand structureCommand) {
+    public static void validateStructureElementDataRelativeOtherData(StructureElementCommand structureElementCommand, StructureCommand structureCommand, EssNamingConvention namingConvention,
+            HolderRepositories holderRepositories, HolderStructures holderStructures) {
         // command - attributes
         //     create  -       type, parent, mnemonic, ordering, description
         //	   update  - uuid, type, parent, mnemonic, ordering, description
@@ -343,11 +353,11 @@ public class ValidateStructureElementUtil {
         //
         // check structure element data in relation to other data
         //     create, update
-        //         parent               - (if applicable) approved, latest, not deleted
+        //         parent               - (if applicable) not deleted
         //         mnemonic             - (if not same)   not exists
         //         mnemonic equivalence - (if not same)   equivalence not exists
         //     approve
-        //         uuid - pending, not latest, deleted
+        //         uuid - pending, deleted
         //         no or less checks if entry to be deleted                - approve (delete)
         //         more or same checks as above if entry is not be deleted - approve (create), approve (update)
         //         need checks as content may have changed from time of create, update, delete to time of approve
@@ -355,7 +365,7 @@ public class ValidateStructureElementUtil {
         //     possibly
         //         additional checks if names are affected
 
-        if (ValidateUtil.isAnyNull(structureElementCommand, namingConvention, holderRepositories, holderStructures, structureCommand)) {
+        if (ValidateUtil.isAnyNull(structureElementCommand, structureCommand, namingConvention, holderRepositories, holderStructures)) {
             return;
         }
 
@@ -381,11 +391,11 @@ public class ValidateStructureElementUtil {
                     // mnemonic
                     message = TextUtil.SYSTEMGROUP_IS_NOT_CORRECT;
                     validateStructuresMnemonic(uuid, type, parent, mnemonic,
-                            namingConvention, holderRepositories, structureCommand, message, details, field);
+                            structureCommand, namingConvention, holderRepositories, message, details, field);
 
                     // mnemonic equivalence
                     validateStructuresMnemonicequivalence(uuid, type, parent, mnemonic,
-                            namingConvention, holderRepositories, structureCommand, message, details, field);
+                            structureCommand, namingConvention, holderRepositories, message, details, field);
                 }
             } else if (Type.SYSTEM.equals(type)) {
                 // parent
@@ -396,11 +406,11 @@ public class ValidateStructureElementUtil {
                 // mnemonic
                 message = TextUtil.SYSTEM_IS_NOT_CORRECT;
                 validateStructuresMnemonic(uuid, type, parent, mnemonic,
-                        namingConvention, holderRepositories, structureCommand, message, details, field);
+                        structureCommand, namingConvention, holderRepositories, message, details, field);
 
                 // mnemonic equivalence
                 validateStructuresMnemonicequivalence(uuid, type, parent, mnemonic,
-                        namingConvention, holderRepositories, structureCommand, message, details, field);
+                        structureCommand, namingConvention, holderRepositories, message, details, field);
             } else if (Type.SUBSYSTEM.equals(type)) {
                 // parent
                 message = TextUtil.SYSTEM_IS_NOT_CORRECT;
@@ -410,21 +420,21 @@ public class ValidateStructureElementUtil {
                 // mnemonic
                 message = TextUtil.SUBSYSTEM_IS_NOT_CORRECT;
                 validateStructuresMnemonic(uuid, type, parent, mnemonic,
-                        namingConvention, holderRepositories, structureCommand, message, details, field);
+                        structureCommand, namingConvention, holderRepositories, message, details, field);
 
                 // mnemonic equivalence
                 validateStructuresMnemonicequivalence(uuid, type, parent, mnemonic,
-                        namingConvention, holderRepositories, structureCommand, message, details, field);
+                        structureCommand, namingConvention, holderRepositories, message, details, field);
             } else if (Type.DISCIPLINE.equals(type)) {
                 message = TextUtil.DISCIPLINE_IS_NOT_CORRECT;
 
                 // mnemonic
                 validateStructuresMnemonic(uuid, type, parent, mnemonic,
-                        namingConvention, holderRepositories, structureCommand, message, details, field);
+                        structureCommand, namingConvention, holderRepositories, message, details, field);
 
                 // mnemonic equivalence
                 validateStructuresMnemonicequivalence(uuid, type, parent, mnemonic,
-                        namingConvention, holderRepositories, structureCommand, message, details, field);
+                        structureCommand, namingConvention, holderRepositories, message, details, field);
             } else if (Type.DEVICEGROUP.equals(type)) {
                 // parent
                 message = TextUtil.DISCIPLINE_IS_NOT_CORRECT;
@@ -447,11 +457,11 @@ public class ValidateStructureElementUtil {
                 // mnemonic
                 message = TextUtil.DEVICETYPE_IS_NOT_CORRECT;
                 validateStructuresMnemonic(uuid, type, parent, mnemonic,
-                        namingConvention, holderRepositories, structureCommand, message, details, field);
+                        structureCommand, namingConvention, holderRepositories, message, details, field);
 
                 // mnemonic equivalence
                 validateStructuresMnemonicequivalence(uuid, type, parent, mnemonic,
-                        namingConvention, holderRepositories, structureCommand, message, details, field);
+                        structureCommand, namingConvention, holderRepositories, message, details, field);
             }
         }
     }
@@ -464,7 +474,8 @@ public class ValidateStructureElementUtil {
                 getStructuresParentSize(type, parent, deleted, holderRepositories) == 1, message, details, field);
     }
     private static void validateStructuresMnemonic(UUID uuid, Type type, UUID parent, String mnemonic,
-            EssNamingConvention namingConvention, HolderRepositories holderRepositories, StructureCommand structureCommand,
+            StructureCommand structureCommand, EssNamingConvention namingConvention,
+            HolderRepositories holderRepositories,
             String message, String details, String field){
         // about finding out if structures are in place in order for structure operation to be allowed
 
@@ -476,7 +487,8 @@ public class ValidateStructureElementUtil {
         validateConditionIfStructureCommand(StructureCommand.UPDATE, structureCommand, ValidateUtil.isEmptyOrEquals(listUuid, uuid), message, details, field);
     }
     private static void validateStructuresMnemonicequivalence(UUID uuid, Type type, UUID parent, String mnemonic,
-            EssNamingConvention namingConvention, HolderRepositories holderRepositories, StructureCommand structureCommand,
+            StructureCommand structureCommand, EssNamingConvention namingConvention,
+            HolderRepositories holderRepositories,
             String message, String details, String field){
         // about finding out if structures are in place in order for structure operation to be allowed
 
@@ -581,7 +593,7 @@ public class ValidateStructureElementUtil {
 
     /**
      * Validate structure data.
-     * This method corresponds to structure element data for create, albeit in a different way.
+     * This method corresponds to validate structure element data for create, albeit in a different way.
      *
      * @param type type
      * @param mnemonicPath mnemonic path
@@ -589,7 +601,8 @@ public class ValidateStructureElementUtil {
      * @param holderIRepositories holder repositories
      * @param holderStructures holder of system and device structure content
      */
-    public static void validateStructureDataCreate(Type type, String mnemonicPath, EssNamingConvention namingConvention, HolderIRepositories holderIRepositories, HolderStructures holderStructures) {
+    public static void validateStructureDataCreate(Type type, String mnemonicPath, EssNamingConvention namingConvention,
+            HolderIRepositories holderIRepositories, HolderStructures holderStructures) {
         if (ValidateUtil.isAnyNull(type, mnemonicPath, namingConvention, holderIRepositories, holderStructures)) {
             return;
         }
@@ -610,11 +623,11 @@ public class ValidateStructureElementUtil {
             // system group may have empty path but there will be mnemonic path in this context
 
             // mnemonic path
-            SystemGroup sg = holderIRepositories.systemGroupRepository().findLatestNotDeletedByMnemonic(path[0]);
+            SystemGroup sg = holderIRepositories.systemGroupRepository().findNotDeletedByMnemonic(path[0]);
             validateStructuresMnemonicpathDuplicate(sg == null, type, details, field);
 
             // mnemonic path equivalence
-            List<SystemGroup> systemGroups = holderIRepositories.systemGroupRepository().findLatestNotDeleted();
+            List<SystemGroup> systemGroups = holderIRepositories.systemGroupRepository().findNotDeleted();
             for (SystemGroup systemGroup : systemGroups) {
                 validateStructuresMnemonicpathequivalenceDuplicate(
                         !StringUtils.equals(systemGroup.getMnemonicEquivalence(), namingConvention.equivalenceClassRepresentative(path[0])),
@@ -660,9 +673,9 @@ public class ValidateStructureElementUtil {
         } else if (Type.SUBSYSTEM.equals(type)) {
             validateStructuresMnemonicpathNotValid(path.length == 2, type, details, field);
 
-            System sys = holderIRepositories.systemRepository().findLatestNotDeletedByMnemonic(path[0]);
+            System sys = holderIRepositories.systemRepository().findNotDeletedByMnemonic(path[0]);
             validateStructuresMnemonicpathNotFound(sys != null, type, details, field);
-            SystemGroup sg = holderIRepositories.systemGroupRepository().findLatestNotDeletedByUuid(sys.getParentUuid().toString());
+            SystemGroup sg = holderIRepositories.systemGroupRepository().findNotDeletedById(sys.getParentId());
 
             // mnemonic path
             validateStructuresMnemonicpathDuplicate(!StringUtils.equals(path[0], path[1]), type, details, field);
@@ -699,11 +712,11 @@ public class ValidateStructureElementUtil {
             validateStructuresMnemonicpathNotValid(path.length == 1, type, details, field);
 
             // mnemonic path
-            Discipline di = holderIRepositories.disciplineRepository().findLatestNotDeletedByMnemonic(path[0]);
+            Discipline di = holderIRepositories.disciplineRepository().findNotDeletedByMnemonic(path[0]);
             validateStructuresMnemonicpathDuplicate(di == null, type, details, field);
 
             // mnemonic path equivalence
-            List<Discipline> disciplines = holderIRepositories.disciplineRepository().findLatestNotDeleted();
+            List<Discipline> disciplines = holderIRepositories.disciplineRepository().findNotDeleted();
             for (Discipline discipline : disciplines) {
                 validateStructuresMnemonicpathequivalenceDuplicate(
                         !StringUtils.equals(discipline.getMnemonicEquivalence(), namingConvention.equivalenceClassRepresentative(path[0])),
@@ -722,7 +735,7 @@ public class ValidateStructureElementUtil {
             validateStructuresMnemonicpathNotValid(path.length == 2, type, details, field);
 
             // discipline
-            Discipline discipline = holderIRepositories.disciplineRepository().findLatestNotDeletedByMnemonic(path[0]);
+            Discipline discipline = holderIRepositories.disciplineRepository().findNotDeletedByMnemonic(path[0]);
             ExceptionUtil.validateConditionDataNotFoundException(discipline != null,
                     TextUtil.DISCIPLINE_IS_NOT_FOUND, details, field);
 
diff --git a/src/main/java/org/openepics/names/util/notification/NotificationScheduler.java b/src/main/java/org/openepics/names/util/notification/NotificationScheduler.java
index 2124ae3c4f6aec1a8970ec8c88416e68d7d11a9a..8f88386665240c16ea41361c0ff2541da533eea6 100644
--- a/src/main/java/org/openepics/names/util/notification/NotificationScheduler.java
+++ b/src/main/java/org/openepics/names/util/notification/NotificationScheduler.java
@@ -29,8 +29,8 @@ import java.util.UUID;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import org.openepics.names.repository.INameRepository;
-import org.openepics.names.repository.model.Name;
+import org.openepics.names.repository.IAuditNameRepository;
+import org.openepics.names.repository.model.AuditName;
 import org.openepics.names.service.NotificationService;
 import org.openepics.names.util.NameCommand;
 import org.openepics.names.util.ValidateUtil;
@@ -54,10 +54,10 @@ public class NotificationScheduler {
 
     private static final String NOTIFY_NAMES_FROM_TO_CREATED_UPDATED_DELETED = "Notify names, {0} - {1}, # created: {2}, # updated: {3}, # deleted: {4}";
 
-    @Autowired
-    private INameRepository iNameRepository;
     @Autowired
     private NotificationService notificationService;
+    @Autowired
+    private IAuditNameRepository iAuditNameRepository;
 
     /**
      * Notify administrators about changes for names and structures.
@@ -101,9 +101,9 @@ public class NotificationScheduler {
         // find names for previous day
         //     uuid ascending, id ascending
         //     distinct uuids
-        List<Name> names = iNameRepository.findByRequestedBetween(from, to);
+        List<AuditName> names = iAuditNameRepository.findByRequestedBetween(from, to);
         Set<UUID> uuids = new TreeSet<>();
-        for (Name name : names) {
+        for (AuditName name : names) {
             uuids.add(name.getUuid());
         }
 
@@ -123,10 +123,10 @@ public class NotificationScheduler {
         //                 deleted
         for (UUID uuid : uuids) {
             // prepare
-            List<Name> extracted = extractByUuid(names, uuid);
-            List<Name> namesByUuid = iNameRepository.findByUuid(uuid.toString());
-            sortById(extracted);
-            sortById(namesByUuid);
+            List<AuditName> extracted = extractByUuid(names, uuid);
+            List<AuditName> namesByUuid = iAuditNameRepository.findByUuid(uuid.toString());
+            sortByAuditId(extracted);
+            sortByAuditId(namesByUuid);
 
             int index = -1;
             for (int i=0; i<namesByUuid.size(); i++) {
@@ -138,13 +138,11 @@ public class NotificationScheduler {
 
             // compare
             for (int i=0; i<extracted.size(); i++) {
-                // created - no previous
-                // updated - is not latest
-                // deleted - is latest and is deleted
-                Name name = extracted.get(i);
+                // find out what kind of change (may also use audit fields)
+                AuditName name = extracted.get(i);
                 if (i == 0 && index == 0) {
                     NotificationUtil.prepareAddNotification(created, NameCommand.CREATE, null, name);
-                } else if (Boolean.TRUE.equals(name.isLatest()) && Boolean.TRUE.equals(name.isDeleted())) {
+                } else if (Boolean.TRUE.equals(name.isDeleted())) {
                     NotificationUtil.prepareAddNotification(deleted, NameCommand.DELETE, null, name);
                 } else {
                     NotificationUtil.prepareAddNotification(updated, NameCommand.UPDATE, findPreviousByName(namesByUuid, name), name);
@@ -203,10 +201,10 @@ public class NotificationScheduler {
      * @param uuid uuid
      * @return list of names
      */
-    private List<Name> extractByUuid(List<Name> list, UUID uuid) {
-        List<Name> extracted = Lists.newArrayList();
+    private List<AuditName> extractByUuid(List<AuditName> list, UUID uuid) {
+        List<AuditName> extracted = Lists.newArrayList();
         if (list != null && !list.isEmpty() && uuid != null) {
-            for (Name name : list) {
+            for (AuditName name : list) {
                 if (uuid.equals(name.getUuid())) {
                     extracted.add(name);
                 }
@@ -220,8 +218,8 @@ public class NotificationScheduler {
      *
      * @param names names
      */
-    private void sortById(List<Name> names) {
-        Collections.sort(names, (Name arg0, Name arg1) -> arg0.getId().compareTo(arg1.getId()));
+    private void sortByAuditId(List<AuditName> names) {
+        Collections.sort(names, (AuditName arg0, AuditName arg1) -> arg0.getAuditId().compareTo(arg1.getAuditId()));
     }
 
     /**
@@ -231,14 +229,14 @@ public class NotificationScheduler {
      * @param name name
      * @return name
      */
-    private Name findPreviousByName(List<Name> names, Name name) {
+    private AuditName findPreviousByName(List<AuditName> names, AuditName name) {
         if (ValidateUtil.isAnyNull(names, name)) {
             return null;
         }
 
         // sorted list
         for (int i=0; i<names.size(); i++) {
-            if (name.getId().equals(names.get(i).getId())) {
+            if (name.getAuditId().equals(names.get(i).getAuditId())) {
                 return i > 0
                         ? names.get(i-1)
                         : null;
diff --git a/src/main/java/org/openepics/names/util/notification/NotificationUtil.java b/src/main/java/org/openepics/names/util/notification/NotificationUtil.java
index df7d8f4c4ba2b2ee117323ba947687e8c9405fe6..8fa01f91e38cf26103f8156c3eaf8dbef46ed24f 100644
--- a/src/main/java/org/openepics/names/util/notification/NotificationUtil.java
+++ b/src/main/java/org/openepics/names/util/notification/NotificationUtil.java
@@ -26,10 +26,10 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.commons.lang3.StringUtils;
+import org.openepics.names.repository.model.AuditName;
 import org.openepics.names.repository.model.DeviceGroup;
 import org.openepics.names.repository.model.DeviceType;
 import org.openepics.names.repository.model.Discipline;
-import org.openepics.names.repository.model.Name;
 import org.openepics.names.repository.model.Structure;
 import org.openepics.names.repository.model.Subsystem;
 import org.openepics.names.repository.model.System;
@@ -68,7 +68,7 @@ public class NotificationUtil {
      * @param previous previous (name)
      * @param name name
      */
-    public static void prepareAddNotification(List<NotificationName> notifications, NameCommand nameCommand, Name previous, Name name) {
+    public static void prepareAddNotification(List<NotificationName> notifications, NameCommand nameCommand, AuditName previous, AuditName name) {
         if (notifications == null) {
             return;
         }
@@ -88,7 +88,7 @@ public class NotificationUtil {
      * @param name name
      * @return notification
      */
-    public static NotificationName prepareNotification(NameCommand nameCommand, Name previous, Name name) {
+    public static NotificationName prepareNotification(NameCommand nameCommand, AuditName previous, AuditName name) {
         if (LOGGER.isLoggable(Level.FINER)) {
             LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.PREPARE_NOTIFICATION, "nameCommand", nameCommand));
             LOGGER.log(Level.FINER, MessageFormat.format(TextUtil.DESCRIPTION_NAME_VALUE, TextUtil.PREPARE_NOTIFICATION, "previous", previous));
@@ -140,29 +140,6 @@ public class NotificationUtil {
                 name.getRequestedBy());
     }
 
-    /**
-     * Prepare notification and add to list of notifications if notification is available.
-     *
-     * @param notifications list of notifications
-     * @param type type
-     * @param structureCommandCUD structure command (create update delete)
-     * @param previous previous (structure)
-     * @param structure structure
-     * @param holderStructures holder of system and device structure content
-     */
-    public static void prepareAddNotification(List<NotificationStructure> notifications,
-            Type type, StructureCommand structureCommandCUD,
-            Structure previous, Structure structure, HolderStructures holderStructures) {
-        if (notifications == null) {
-            return;
-        }
-
-        NotificationStructure notification = NotificationUtil.prepareNotification(type, structureCommandCUD, previous, structure, holderStructures);
-        if (notification != null) {
-            notifications.add(notification);
-        }
-    }
-
     /**
      * Prepare and return notification for system group with information about change.
      * If information is not correct, <tt>null</tt> is returned.
diff --git a/src/main/java/org/openepics/names/service/StructureElementNotification.java b/src/main/java/org/openepics/names/util/notification/StructureElementNotification.java
similarity index 81%
rename from src/main/java/org/openepics/names/service/StructureElementNotification.java
rename to src/main/java/org/openepics/names/util/notification/StructureElementNotification.java
index 7ce9a9a7dbe935e3303a279db3449cecf1a1f7d6..a7bfe72a4ecbc374c17e36e547df603970fd39b6 100644
--- a/src/main/java/org/openepics/names/service/StructureElementNotification.java
+++ b/src/main/java/org/openepics/names/util/notification/StructureElementNotification.java
@@ -16,10 +16,9 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 
-package org.openepics.names.service;
+package org.openepics.names.util.notification;
 
 import org.openepics.names.rest.beans.element.StructureElement;
-import org.openepics.names.util.notification.NotificationStructure;
 
 /**
  * Utility record to collect structure element and notification.
@@ -27,4 +26,4 @@ import org.openepics.names.util.notification.NotificationStructure;
  *
  * @author Lars Johansson
  */
-record StructureElementNotification (StructureElement structureElement, NotificationStructure notificationStructure) {}
+public record StructureElementNotification (StructureElement structureElement, NotificationStructure notificationStructure) {}
diff --git a/src/main/java/org/openepics/names/util/old/DeviceNameElementUtil.java b/src/main/java/org/openepics/names/util/old/DeviceNameElementUtil.java
index 805fb005b43e8410e5cc4fb92105ac9af8dec11a..79d84aeec926dd033fe7a9968bb3d067c4bc3f85 100644
--- a/src/main/java/org/openepics/names/util/old/DeviceNameElementUtil.java
+++ b/src/main/java/org/openepics/names/util/old/DeviceNameElementUtil.java
@@ -18,17 +18,16 @@
 
 package org.openepics.names.util.old;
 
-import org.openepics.names.repository.model.DeviceGroup;
-import org.openepics.names.repository.model.DeviceType;
-import org.openepics.names.repository.model.Discipline;
-import org.openepics.names.repository.model.Name;
-import org.openepics.names.repository.model.Subsystem;
-import org.openepics.names.repository.model.System;
-import org.openepics.names.repository.model.SystemGroup;
+import org.openepics.names.repository.model.wip.WipDeviceGroup;
+import org.openepics.names.repository.model.wip.WipDeviceType;
+import org.openepics.names.repository.model.wip.WipDiscipline;
+import org.openepics.names.repository.model.wip.WipName;
+import org.openepics.names.repository.model.wip.WipSubsystem;
+import org.openepics.names.repository.model.wip.WipSystem;
+import org.openepics.names.repository.model.wip.WipSystemGroup;
 import org.openepics.names.rest.beans.old.DeviceNameElement;
-import org.openepics.names.util.HolderIRepositories;
-import org.openepics.names.util.HolderStructures;
-import org.openepics.names.util.NameUtil;
+import org.openepics.names.util.wip.HolderIWipRepositories;
+import org.openepics.names.util.wip.HolderWipStructures;
 
 /**
  * Utility class to assist in populating device name elements based on repository content.
@@ -54,7 +53,7 @@ public class DeviceNameElementUtil {
      * @param holderStructures holder of system and device structure content
      * @return device name element
      */
-    public static DeviceNameElement getDeviceNameElement(Name name, HolderStructures holderStructures) {
+    public static DeviceNameElement getDeviceNameElement(WipName name, HolderWipStructures holderStructures) {
         if (name == null) {
             return null;
         }
@@ -63,8 +62,8 @@ public class DeviceNameElementUtil {
         //     for performance reasons to speed up preparation of what is to be returned
 
         // find out how to populate return element for system structure, device structure
-        int levelSystemStructure = NameUtil.getLevelSystemStructure(name);
-        int levelDeviceStructure = NameUtil.getLevelDeviceStructure(name);
+        int levelSystemStructure = DeviceNameElementUtil.getLevelSystemStructure(name);
+        int levelDeviceStructure = DeviceNameElementUtil.getLevelDeviceStructure(name);
 
         // levelSystemStructure -1 ---> error
         // levelDeviceStructure -1 ---> error
@@ -74,9 +73,9 @@ public class DeviceNameElementUtil {
         // populate return element for system structure
         switch (levelSystemStructure) {
         case 3: {
-            Subsystem   subsystem   = holderStructures.findSubsystemByUuid(name.getSubsystemUuid());
-            System      system      = holderStructures.findSystemByUuid(subsystem.getParentUuid());
-            SystemGroup systemGroup = holderStructures.findSystemGroupByUuid(system.getParentUuid());
+            WipSubsystem   subsystem   = holderStructures.findSubsystemByUuid(name.getSubsystemUuid());
+            WipSystem      system      = holderStructures.findSystemByUuid(subsystem.getParentUuid());
+            WipSystemGroup systemGroup = holderStructures.findSystemGroupByUuid(system.getParentUuid());
 
             deviceNameElement.setSubsystem(subsystem.getMnemonic());
             deviceNameElement.setSystem(system.getMnemonic());
@@ -84,15 +83,15 @@ public class DeviceNameElementUtil {
             break;
         }
         case 2: {
-            System      system      = holderStructures.findSystemByUuid(name.getSystemUuid());
-            SystemGroup systemGroup = holderStructures.findSystemGroupByUuid(system.getParentUuid());
+            WipSystem      system      = holderStructures.findSystemByUuid(name.getSystemUuid());
+            WipSystemGroup systemGroup = holderStructures.findSystemGroupByUuid(system.getParentUuid());
 
             deviceNameElement.setSystem(system.getMnemonic());
             deviceNameElement.setSystemGroup(systemGroup.getMnemonic());
             break;
         }
         case 1: {
-            SystemGroup systemGroup = holderStructures.findSystemGroupByUuid(name.getSystemGroupUuid());
+            WipSystemGroup systemGroup = holderStructures.findSystemGroupByUuid(name.getSystemGroupUuid());
 
             deviceNameElement.setSystemGroup(systemGroup.getMnemonic());
             break;
@@ -105,9 +104,9 @@ public class DeviceNameElementUtil {
         // populate return element for device structure
         switch (levelDeviceStructure) {
         case 3: {
-            DeviceType  deviceType  = holderStructures.findDeviceTypeByUuid(name.getDeviceTypeUuid());
-            DeviceGroup deviceGroup = holderStructures.findDeviceGroupByUuid(deviceType.getParentUuid());
-            Discipline  discipline  = holderStructures.findDisciplineByUuid(deviceGroup.getParentUuid());
+            WipDeviceType  deviceType  = holderStructures.findDeviceTypeByUuid(name.getDeviceTypeUuid());
+            WipDeviceGroup deviceGroup = holderStructures.findDeviceGroupByUuid(deviceType.getParentUuid());
+            WipDiscipline  discipline  = holderStructures.findDisciplineByUuid(deviceGroup.getParentUuid());
 
             deviceNameElement.setDeviceType(deviceType.getMnemonic());
             deviceNameElement.setDiscipline(discipline.getMnemonic());
@@ -131,17 +130,17 @@ public class DeviceNameElementUtil {
      * Populate and return device name element for name.
      *
      * @param name name
-     * @param holderIRepositories holder of references to repositories
+     * @param holderIWipRepositories holder of references to repositories
      * @return device name element
      */
-    public static DeviceNameElement getDeviceNameElement(Name name, HolderIRepositories holderIRepositories) {
+    public static DeviceNameElement getDeviceNameElement(WipName name, HolderIWipRepositories holderIWipRepositories) {
         if (name == null) {
             return null;
         }
 
         // find out how to populate return element for system structure, device structure
-        int levelSystemStructure = NameUtil.getLevelSystemStructure(name);
-        int levelDeviceStructure = NameUtil.getLevelDeviceStructure(name);
+        int levelSystemStructure = DeviceNameElementUtil.getLevelSystemStructure(name);
+        int levelDeviceStructure = DeviceNameElementUtil.getLevelDeviceStructure(name);
 
         // levelSystemStructure -1 ---> error
         // levelDeviceStructure -1 ---> error
@@ -151,9 +150,9 @@ public class DeviceNameElementUtil {
         // populate return element for system structure
         switch (levelSystemStructure) {
         case 3: {
-            Subsystem   subsystem   = holderIRepositories.subsystemRepository().findLatestByUuid(name.getSubsystemUuid().toString());
-            System      system      = holderIRepositories.systemRepository().findLatestByUuid(subsystem.getParentUuid().toString());
-            SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
+            WipSubsystem   subsystem   = holderIWipRepositories.subsystemRepository().findLatestByUuid(name.getSubsystemUuid().toString());
+            WipSystem      system      = holderIWipRepositories.systemRepository().findLatestByUuid(subsystem.getParentUuid().toString());
+            WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
 
             deviceNameElement.setSubsystem(subsystem.getMnemonic());
             deviceNameElement.setSystem(system.getMnemonic());
@@ -161,15 +160,15 @@ public class DeviceNameElementUtil {
             break;
         }
         case 2: {
-            System      system      = holderIRepositories.systemRepository().findLatestByUuid(name.getSystemUuid().toString());
-            SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
+            WipSystem      system      = holderIWipRepositories.systemRepository().findLatestByUuid(name.getSystemUuid().toString());
+            WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
 
             deviceNameElement.setSystem(system.getMnemonic());
             deviceNameElement.setSystemGroup(systemGroup.getMnemonic());
             break;
         }
         case 1: {
-            SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(name.getSystemGroupUuid().toString());
+            WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(name.getSystemGroupUuid().toString());
 
             deviceNameElement.setSystemGroup(systemGroup.getMnemonic());
             break;
@@ -182,9 +181,9 @@ public class DeviceNameElementUtil {
         // populate return element for device structure
         switch (levelDeviceStructure) {
         case 3: {
-            DeviceType  deviceType  = holderIRepositories.deviceTypeRepository().findLatestByUuid(name.getDeviceTypeUuid().toString());
-            DeviceGroup deviceGroup = holderIRepositories.deviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString());
-            Discipline  discipline  = holderIRepositories.disciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString());
+            WipDeviceType  deviceType  = holderIWipRepositories.deviceTypeRepository().findLatestByUuid(name.getDeviceTypeUuid().toString());
+            WipDeviceGroup deviceGroup = holderIWipRepositories.deviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString());
+            WipDiscipline  discipline  = holderIWipRepositories.disciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString());
 
             deviceNameElement.setDeviceType(deviceType.getMnemonic());
             deviceNameElement.setDiscipline(discipline.getMnemonic());
@@ -204,4 +203,64 @@ public class DeviceNameElementUtil {
         return deviceNameElement;
     }
 
+    /**
+     * Return level of system structure for name.
+     * <ul>
+     * <li>1  <--> system group</li>
+     * <li>2  <--> system</li>
+     * <li>3  <--> subsystem</li>
+     * <li>-1 <--> invalid</li>
+     * </ul>
+     *
+     * @param name name content
+     * @return level of system structure
+     */
+    private static int getLevelSystemStructure(WipName name) {
+        if (name == null) {
+            return -1;
+        }
+
+        int count = 0;
+        if (name.getSystemGroupUuid() != null) {
+            count++;
+        }
+        if (name.getSystemUuid() != null) {
+            count++;
+        }
+        if (name.getSubsystemUuid() != null) {
+            count++;
+        }
+        if (count != 1) {
+            return -1;
+        }
+
+        return name.getSubsystemUuid() != null
+                ? 3
+                : name.getSystemUuid() != null
+                        ? 2
+                        : name.getSystemGroupUuid() != null
+                                ? 1
+                                : -1;
+    }
+
+    /**
+     * Return level of device structure for name.
+     * <ul>
+     * <li>3  <--> device type</li>
+     * <li>-1 <--> invalid</li>
+     * </ul>
+     *
+     * @param name content
+     * @return level of device structure
+     */
+    private static int getLevelDeviceStructure(WipName name) {
+        if (name == null) {
+            return -1;
+        }
+
+        return name.getDeviceTypeUuid() != null
+                ? 3
+                : -1;
+    }
+
 }
diff --git a/src/main/java/org/openepics/names/util/old/HistoryElementUtil.java b/src/main/java/org/openepics/names/util/old/HistoryElementUtil.java
index 17f928fb2203bd49cf5889c3c5f4518056c07bce..c141cf0d2278c784e9787065bad5ba2ebdf78eab 100644
--- a/src/main/java/org/openepics/names/util/old/HistoryElementUtil.java
+++ b/src/main/java/org/openepics/names/util/old/HistoryElementUtil.java
@@ -22,13 +22,13 @@ import java.text.SimpleDateFormat;
 import java.util.UUID;
 
 import org.openepics.names.old.business.NameRevisionStatus;
-import org.openepics.names.repository.model.DeviceGroup;
-import org.openepics.names.repository.model.DeviceType;
-import org.openepics.names.repository.model.Discipline;
-import org.openepics.names.repository.model.Name;
-import org.openepics.names.repository.model.Subsystem;
-import org.openepics.names.repository.model.System;
-import org.openepics.names.repository.model.SystemGroup;
+import org.openepics.names.repository.model.wip.WipDeviceGroup;
+import org.openepics.names.repository.model.wip.WipDeviceType;
+import org.openepics.names.repository.model.wip.WipDiscipline;
+import org.openepics.names.repository.model.wip.WipName;
+import org.openepics.names.repository.model.wip.WipSubsystem;
+import org.openepics.names.repository.model.wip.WipSystem;
+import org.openepics.names.repository.model.wip.WipSystemGroup;
 import org.openepics.names.rest.beans.old.HistoryElement;
 
 /**
@@ -53,7 +53,7 @@ public class HistoryElementUtil {
      * @param systemGroup system group
      * @return history element
      */
-    public static HistoryElement getHistoryElementProcessed(SystemGroup systemGroup) {
+    public static HistoryElement getHistoryElementProcessed(WipSystemGroup systemGroup) {
         if (systemGroup == null) {
             return null;
         }
@@ -73,7 +73,7 @@ public class HistoryElementUtil {
      * @param systemGroup system group
      * @return history element
      */
-    public static HistoryElement getHistoryElementRequested(SystemGroup systemGroup) {
+    public static HistoryElement getHistoryElementRequested(WipSystemGroup systemGroup) {
         if (systemGroup == null) {
             return null;
         }
@@ -93,7 +93,7 @@ public class HistoryElementUtil {
      * @param system system
      * @return history element
      */
-    public static HistoryElement getHistoryElementProcessed(System system) {
+    public static HistoryElement getHistoryElementProcessed(WipSystem system) {
         if (system == null) {
             return null;
         }
@@ -113,7 +113,7 @@ public class HistoryElementUtil {
      * @param system system
      * @return history element
      */
-    public static HistoryElement getHistoryElementRequested(System system) {
+    public static HistoryElement getHistoryElementRequested(WipSystem system) {
         if (system == null) {
             return null;
         }
@@ -133,7 +133,7 @@ public class HistoryElementUtil {
      * @param subsystem subsystem
      * @return history element
      */
-    public static HistoryElement getHistoryElementProcessed(Subsystem subsystem) {
+    public static HistoryElement getHistoryElementProcessed(WipSubsystem subsystem) {
         if (subsystem == null) {
             return null;
         }
@@ -153,7 +153,7 @@ public class HistoryElementUtil {
      * @param subsystem subsystem
      * @return history element
      */
-    public static HistoryElement getHistoryElementRequested(Subsystem subsystem) {
+    public static HistoryElement getHistoryElementRequested(WipSubsystem subsystem) {
         if (subsystem == null) {
             return null;
         }
@@ -174,7 +174,7 @@ public class HistoryElementUtil {
      * @param discipline discipline
      * @return history element
      */
-    public static HistoryElement getHistoryElementProcessed(Discipline discipline) {
+    public static HistoryElement getHistoryElementProcessed(WipDiscipline discipline) {
         if (discipline == null) {
             return null;
         }
@@ -194,7 +194,7 @@ public class HistoryElementUtil {
      * @param discipline discipline
      * @return history element
      */
-    public static HistoryElement getHistoryElementRequested(Discipline discipline) {
+    public static HistoryElement getHistoryElementRequested(WipDiscipline discipline) {
         if (discipline == null) {
             return null;
         }
@@ -214,7 +214,7 @@ public class HistoryElementUtil {
      * @param deviceGroup device group
      * @return history element
      */
-    public static HistoryElement getHistoryElementProcessed(DeviceGroup deviceGroup) {
+    public static HistoryElement getHistoryElementProcessed(WipDeviceGroup deviceGroup) {
         if (deviceGroup == null) {
             return null;
         }
@@ -234,7 +234,7 @@ public class HistoryElementUtil {
      * @param deviceGroup device group
      * @return history element
      */
-    public static HistoryElement getHistoryElementRequested(DeviceGroup deviceGroup) {
+    public static HistoryElement getHistoryElementRequested(WipDeviceGroup deviceGroup) {
         if (deviceGroup == null) {
             return null;
         }
@@ -254,7 +254,7 @@ public class HistoryElementUtil {
      * @param deviceType device type
      * @return history element
      */
-    public static HistoryElement getHistoryElementProcessed(DeviceType deviceType) {
+    public static HistoryElement getHistoryElementProcessed(WipDeviceType deviceType) {
         if (deviceType == null) {
             return null;
         }
@@ -274,7 +274,7 @@ public class HistoryElementUtil {
      * @param deviceType device type
      * @return history element
      */
-    public static HistoryElement getHistoryElementRequested(DeviceType deviceType) {
+    public static HistoryElement getHistoryElementRequested(WipDeviceType deviceType) {
         if (deviceType == null) {
             return null;
         }
@@ -311,7 +311,7 @@ public class HistoryElementUtil {
      * @param name name
      * @return history element
      */
-    public static HistoryElement getHistoryElement(Name name) {
+    public static HistoryElement getHistoryElement(WipName name) {
         if (name == null) {
             return null;
         }
diff --git a/src/main/java/org/openepics/names/util/old/PartElementUtil.java b/src/main/java/org/openepics/names/util/old/PartElementUtil.java
index ffa861e0ac6950fc6c9c508c33606c9c826a5418..25f3b92caa3bb981bb9c5c84f4b69931c5dc6f92 100644
--- a/src/main/java/org/openepics/names/util/old/PartElementUtil.java
+++ b/src/main/java/org/openepics/names/util/old/PartElementUtil.java
@@ -18,15 +18,15 @@
 
 package org.openepics.names.util.old;
 
-import org.openepics.names.repository.model.DeviceGroup;
-import org.openepics.names.repository.model.DeviceType;
-import org.openepics.names.repository.model.Discipline;
-import org.openepics.names.repository.model.Subsystem;
-import org.openepics.names.repository.model.System;
-import org.openepics.names.repository.model.SystemGroup;
+import org.openepics.names.repository.model.wip.WipDeviceGroup;
+import org.openepics.names.repository.model.wip.WipDeviceType;
+import org.openepics.names.repository.model.wip.WipDiscipline;
+import org.openepics.names.repository.model.wip.WipSubsystem;
+import org.openepics.names.repository.model.wip.WipSystem;
+import org.openepics.names.repository.model.wip.WipSystemGroup;
 import org.openepics.names.rest.beans.old.PartElement;
-import org.openepics.names.util.HolderIRepositories;
 import org.openepics.names.util.NamingConventionUtil;
+import org.openepics.names.util.wip.HolderIWipRepositories;
 
 /**
  * Utility class to assist in populating part elements based on repository content.
@@ -56,7 +56,7 @@ public class PartElementUtil {
      * @param systemGroup system group
      * @return part element
      */
-    public static PartElement getPartElement(SystemGroup systemGroup) {
+    public static PartElement getPartElement(WipSystemGroup systemGroup) {
         if (systemGroup == null) {
             return null;
         }
@@ -79,12 +79,12 @@ public class PartElementUtil {
      * @param system system
      * @return part element
      */
-    public static PartElement getPartElement(System system, HolderIRepositories holderIRepositories) {
+    public static PartElement getPartElement(WipSystem system, HolderIWipRepositories holderIWipRepositories) {
         if (system == null) {
             return null;
         }
 
-        SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
+        WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
 
         return new PartElement(
                 SYSTEM_STRUCTURE,
@@ -104,13 +104,13 @@ public class PartElementUtil {
      * @param subsystem subsystem
      * @return part element
      */
-    public static PartElement getPartElement(Subsystem subsystem, HolderIRepositories holderIRepositories) {
+    public static PartElement getPartElement(WipSubsystem subsystem, HolderIWipRepositories holderIWipRepositories) {
         if (subsystem == null) {
             return null;
         }
 
-        System      system      = holderIRepositories.systemRepository().findLatestByUuid(subsystem.getParentUuid().toString());
-        SystemGroup systemGroup = holderIRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
+        WipSystem      system      = holderIWipRepositories.systemRepository().findLatestByUuid(subsystem.getParentUuid().toString());
+        WipSystemGroup systemGroup = holderIWipRepositories.systemGroupRepository().findLatestByUuid(system.getParentUuid().toString());
 
         return new PartElement(
                 SYSTEM_STRUCTURE,
@@ -130,7 +130,7 @@ public class PartElementUtil {
      * @param discipline discipline
      * @return part element
      */
-    public static PartElement getPartElement(Discipline discipline) {
+    public static PartElement getPartElement(WipDiscipline discipline) {
         if (discipline == null) {
             return null;
         }
@@ -153,13 +153,13 @@ public class PartElementUtil {
      * @param deviceType device type
      * @return part element
      */
-    public static PartElement getPartElement(DeviceType deviceType, HolderIRepositories holderIRepositories) {
+    public static PartElement getPartElement(WipDeviceType deviceType, HolderIWipRepositories holderIWipRepositories) {
         if (deviceType == null) {
             return null;
         }
 
-        DeviceGroup deviceGroup = holderIRepositories.deviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString());
-        Discipline  discipline  = holderIRepositories.disciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString());
+        WipDeviceGroup deviceGroup = holderIWipRepositories.deviceGroupRepository().findLatestByUuid(deviceType.getParentUuid().toString());
+        WipDiscipline  discipline  = holderIWipRepositories.disciplineRepository().findLatestByUuid(deviceGroup.getParentUuid().toString());
 
         return new PartElement(
                 DEVICE_STRUCTURE,
diff --git a/src/main/java/org/openepics/names/util/wip/HolderIWipRepositories.java b/src/main/java/org/openepics/names/util/wip/HolderIWipRepositories.java
new file mode 100644
index 0000000000000000000000000000000000000000..88de9c0ca3363012744819ff9474b10a5f17c1a2
--- /dev/null
+++ b/src/main/java/org/openepics/names/util/wip/HolderIWipRepositories.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.wip;
+
+import org.openepics.names.repository.wip.IWipDeviceGroupRepository;
+import org.openepics.names.repository.wip.IWipDeviceTypeRepository;
+import org.openepics.names.repository.wip.IWipDisciplineRepository;
+import org.openepics.names.repository.wip.IWipNameRepository;
+import org.openepics.names.repository.wip.IWipSubsystemRepository;
+import org.openepics.names.repository.wip.IWipSystemGroupRepository;
+import org.openepics.names.repository.wip.IWipSystemRepository;
+
+/**
+ * Utility record to collect references to repositories (interfaces).
+ *
+ * @author Lars Johansson
+ */
+public record HolderIWipRepositories (
+        IWipNameRepository nameRepository,
+        IWipSystemGroupRepository systemGroupRepository,
+        IWipSystemRepository systemRepository,
+        IWipSubsystemRepository subsystemRepository,
+        IWipDisciplineRepository disciplineRepository,
+        IWipDeviceGroupRepository deviceGroupRepository,
+        IWipDeviceTypeRepository deviceTypeRepository) {}
diff --git a/src/main/java/org/openepics/names/util/wip/HolderWipRepositories.java b/src/main/java/org/openepics/names/util/wip/HolderWipRepositories.java
new file mode 100644
index 0000000000000000000000000000000000000000..8117917d2f6f1f416d90c0a22d0d12431d23b3ce
--- /dev/null
+++ b/src/main/java/org/openepics/names/util/wip/HolderWipRepositories.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.wip;
+
+import org.openepics.names.repository.wip.WipDeviceGroupRepository;
+import org.openepics.names.repository.wip.WipDeviceTypeRepository;
+import org.openepics.names.repository.wip.WipDisciplineRepository;
+import org.openepics.names.repository.wip.WipNameRepository;
+import org.openepics.names.repository.wip.WipSubsystemRepository;
+import org.openepics.names.repository.wip.WipSystemGroupRepository;
+import org.openepics.names.repository.wip.WipSystemRepository;
+
+/**
+ * Utility record to collect references to repositories.
+ *
+ * @author Lars Johansson
+ */
+public record HolderWipRepositories (
+        WipNameRepository nameRepository,
+        WipSystemGroupRepository systemGroupRepository,
+        WipSystemRepository systemRepository,
+        WipSubsystemRepository subsystemRepository,
+        WipDisciplineRepository disciplineRepository,
+        WipDeviceGroupRepository deviceGroupRepository,
+        WipDeviceTypeRepository deviceTypeRepository) {}
diff --git a/src/main/java/org/openepics/names/util/wip/HolderWipStructures.java b/src/main/java/org/openepics/names/util/wip/HolderWipStructures.java
new file mode 100644
index 0000000000000000000000000000000000000000..e617c8ba90b8d600b23cbb2fba579b53a6f3844b
--- /dev/null
+++ b/src/main/java/org/openepics/names/util/wip/HolderWipStructures.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2021 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.wip;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import org.openepics.names.repository.model.wip.WipDeviceGroup;
+import org.openepics.names.repository.model.wip.WipDeviceType;
+import org.openepics.names.repository.model.wip.WipDiscipline;
+import org.openepics.names.repository.model.wip.WipSubsystem;
+import org.openepics.names.repository.model.wip.WipSystem;
+import org.openepics.names.repository.model.wip.WipSystemGroup;
+
+/**
+ * Utility class and holder of system and device structure content that are used to populate REST API return elements.
+ * <p>
+ * Class is used for performance reasons to speed up preparation of what is to be returned.
+ * </p>
+ *
+ * @author Lars Johansson
+ */
+public class HolderWipStructures {
+
+    private HashMap<UUID, WipSystemGroup> systemGroups;
+    private HashMap<UUID, WipSystem>      systems;
+    private HashMap<UUID, WipSubsystem>   subsystems;
+
+    private HashMap<UUID, WipDiscipline>  disciplines;
+    private HashMap<UUID, WipDeviceGroup> deviceGroups;
+    private HashMap<UUID, WipDeviceType>  deviceTypes;
+
+    private boolean includeDeleted = true;
+
+    /**
+     * Public constructor to prepare containers for system and device structure content.
+     *
+     * @param holderIWipRepositories
+     */
+    public HolderWipStructures (HolderIWipRepositories holderIWipRepositories) {
+        this(holderIWipRepositories, true);
+    }
+
+    /**
+     * Public constructor to prepare containers for system and device structure content.
+     *
+     * @param holderIWipRepositories holder of references to repositories
+     * @param includeDeleted include deleted structure entries
+     */
+    public HolderWipStructures (HolderIWipRepositories holderIWipRepositories, boolean includeDeleted) {
+        List<WipSystemGroup> systemGroupsRead = null;
+        List<WipSystem> systemsRead = null;
+        List<WipSubsystem> subsystemsRead = null;
+        List<WipDiscipline> disciplinesRead = null;
+        List<WipDeviceGroup> deviceGroupsRead = null;
+        List<WipDeviceType> deviceTypesRead = null;
+
+        if (includeDeleted) {
+            systemGroupsRead = holderIWipRepositories.systemGroupRepository().findLatest();
+            systemsRead = holderIWipRepositories.systemRepository().findLatest();
+            subsystemsRead = holderIWipRepositories.subsystemRepository().findLatest();
+            disciplinesRead = holderIWipRepositories.disciplineRepository().findLatest();
+            deviceGroupsRead = holderIWipRepositories.deviceGroupRepository().findLatest();
+            deviceTypesRead = holderIWipRepositories.deviceTypeRepository().findLatest();
+        } else {
+            systemGroupsRead = holderIWipRepositories.systemGroupRepository().findLatestNotDeleted();
+            systemsRead = holderIWipRepositories.systemRepository().findLatestNotDeleted();
+            subsystemsRead = holderIWipRepositories.subsystemRepository().findLatestNotDeleted();
+            disciplinesRead = holderIWipRepositories.disciplineRepository().findLatestNotDeleted();
+            deviceGroupsRead = holderIWipRepositories.deviceGroupRepository().findLatestNotDeleted();
+            deviceTypesRead = holderIWipRepositories.deviceTypeRepository().findLatestNotDeleted();
+        }
+
+        // initial capacity
+        //     default load factor 0.75
+        //     set at proper size to avoid rehashing
+        //     size/0.75+1 (may be rounded downwards so possibly +2 instead)
+        float loadFactor = 0.75f;
+        this.systemGroups = new HashMap<>((int)(systemGroupsRead.size()/loadFactor + 2), loadFactor);
+        this.systems      = new HashMap<>((int)(systemsRead.size()/loadFactor + 2), loadFactor);
+        this.subsystems   = new HashMap<>((int)(subsystemsRead.size()/loadFactor + 2), loadFactor);
+        this.disciplines  = new HashMap<>((int)(disciplinesRead.size()/loadFactor + 2), loadFactor);
+        this.deviceGroups = new HashMap<>((int)(deviceGroupsRead.size()/loadFactor + 2), loadFactor);
+        this.deviceTypes  = new HashMap<>((int)(deviceTypesRead.size()/loadFactor + 2), loadFactor);
+
+        for (WipSystemGroup systemGroup : systemGroupsRead) {
+            this.systemGroups.put(systemGroup.getUuid(), systemGroup);
+        }
+        for (WipSystem system : systemsRead) {
+            this.systems.put(system.getUuid(), system);
+        }
+        for (WipSubsystem subsystem : subsystemsRead) {
+            this.subsystems.put(subsystem.getUuid(), subsystem);
+        }
+        for (WipDiscipline discipline : disciplinesRead) {
+            this.disciplines.put(discipline.getUuid(), discipline);
+        }
+        for (WipDeviceGroup deviceGroup : deviceGroupsRead) {
+            this.deviceGroups.put(deviceGroup.getUuid(), deviceGroup);
+        }
+        for (WipDeviceType deviceType : deviceTypesRead) {
+            this.deviceTypes.put(deviceType.getUuid(), deviceType);
+        }
+    }
+
+    /**
+     * Find system group name part by uuid.
+     *
+     * @param uuid uuid
+     * @return system group name part
+     */
+    public WipSystemGroup findSystemGroupByUuid(UUID uuid) {
+        return systemGroups.get(uuid);
+    }
+    /**
+     * Find system name part by uuid.
+     *
+     * @param uuid uuid
+     * @return system name part
+     */
+    public WipSystem findSystemByUuid(UUID uuid) {
+        return systems.get(uuid);
+    }
+    /**
+     * Find subsystem name part by uuid.
+     *
+     * @param uuid uuid
+     * @return subsystem name part
+     */
+    public WipSubsystem findSubsystemByUuid(UUID uuid) {
+        return subsystems.get(uuid);
+    }
+
+    /**
+     * Find discipline name part by uuid.
+     *
+     * @param uuid uuid
+     * @return discipline name part
+     */
+    public WipDiscipline findDisciplineByUuid(UUID uuid) {
+        return disciplines.get(uuid);
+    }
+    /**
+     * Find device group name part by uuid.
+     *
+     * @param uuid uuid
+     * @return device group name part
+     */
+    public WipDeviceGroup findDeviceGroupByUuid(UUID uuid) {
+        return deviceGroups.get(uuid);
+    }
+    /**
+     * Find device type name part by uuid.
+     *
+     * @param uuid uuid
+     * @return device type name part
+     */
+    public WipDeviceType findDeviceTypeByUuid(UUID uuid) {
+        return deviceTypes.get(uuid);
+    }
+
+    /**
+     * Return if include deleted structure entries.
+     *
+     * @return if include deleted structure entries
+     */
+    public boolean getIncludeDeleted() {
+        return includeDeleted;
+    }
+
+    /**
+     * Return map with key-value pairs (uuid and system group).
+     *
+     * @return map with key-value pairs (uuid and system group)
+     */
+    public Map<UUID, WipSystemGroup> getUuidSystemGroups() {
+        return systemGroups;
+    }
+
+    /**
+     * Return map with key-value pairs (uuid and system).
+     *
+     * @return map with key-value pairs (uuid and system)
+     */
+    public Map<UUID, WipSystem> getUuidSystems() {
+        return systems;
+    }
+
+    /**
+     * Return map with key-value pairs (uuid and subsystem).
+     *
+     * @return map with key-value pairs (uuid and subsystem)
+     */
+    public Map<UUID, WipSubsystem> getUuidSubsystems() {
+        return subsystems;
+    }
+
+    /**
+     * Return map with key-value pairs (uuid and discipline).
+     *
+     * @return map with key-value pairs (uuid and discipline)
+     */
+    public Map<UUID, WipDiscipline> getUuidDisciplines() {
+        return disciplines;
+    }
+
+    /**
+     * Return map with key-value pairs (uuid and device group).
+     *
+     * @return map with key-value pairs (uuid and device group)
+     */
+    public Map<UUID, WipDeviceGroup> getUuidDeviceGroups() {
+        return deviceGroups;
+    }
+
+    /**
+     * Return map with key-value pairs (uuid and device type).
+     *
+     * @return map with key-value pairs (uuid and device type)
+     */
+    public Map<UUID, WipDeviceType> getUuidDeviceTypes() {
+        return deviceTypes;
+    }
+
+}
diff --git a/src/main/resources/db/migration/V4__Schema_data_migration.sql b/src/main/resources/db/migration/V4__Schema_data_migration.sql
index 6de5c5cac99cbac49ad9c2d227bca886f3e94aa2..6b42bb35a3ff4452f3c68b85074eb648089a09ac 100644
--- a/src/main/resources/db/migration/V4__Schema_data_migration.sql
+++ b/src/main/resources/db/migration/V4__Schema_data_migration.sql
@@ -1,4 +1,4 @@
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- About
 --     migration script
 --     postgresql 9.6.7
@@ -21,12 +21,13 @@
 -- Note
 --     order of items is important
 --     name and description are concatenated for structures
--- --------------------------------------------------------------------------------
+--     notice prefix "wip_" meaning "work in progress" as tables are temporary
+-- ----------------------------------------------------------------------------------------------------
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- structures
--- --------------------------------------------------------------------------------
-CREATE TABLE IF NOT EXISTS systemgroup (
+-- ----------------------------------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS wip_systemgroup (
     id bigint NOT NULL,
     version integer,
     uuid text NOT NULL,
@@ -45,7 +46,7 @@ CREATE TABLE IF NOT EXISTS systemgroup (
     processed_comment text
 );
 
-CREATE TABLE IF NOT EXISTS system (
+CREATE TABLE IF NOT EXISTS wip_system (
     id bigint NOT NULL,
     version integer,
     uuid text NOT NULL,
@@ -65,7 +66,7 @@ CREATE TABLE IF NOT EXISTS system (
     processed_comment text
 );
 
-CREATE TABLE IF NOT EXISTS subsystem (
+CREATE TABLE IF NOT EXISTS wip_subsystem (
     id bigint NOT NULL,
     version integer,
     uuid text NOT NULL,
@@ -85,8 +86,8 @@ CREATE TABLE IF NOT EXISTS subsystem (
     processed_comment text
 );
 
--- --------------------------------------------------------------------------------
-CREATE TABLE IF NOT EXISTS discipline (
+-- ----------------------------------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS wip_discipline (
     id bigint NOT NULL,
     version integer,
     uuid text NOT NULL,
@@ -105,7 +106,7 @@ CREATE TABLE IF NOT EXISTS discipline (
     processed_comment text
 );
 
-CREATE TABLE IF NOT EXISTS devicegroup (
+CREATE TABLE IF NOT EXISTS wip_devicegroup (
     id bigint NOT NULL,
     version integer,
     uuid text NOT NULL,
@@ -125,7 +126,7 @@ CREATE TABLE IF NOT EXISTS devicegroup (
     processed_comment text
 );
 
-CREATE TABLE IF NOT EXISTS devicetype (
+CREATE TABLE IF NOT EXISTS wip_devicetype (
     id bigint NOT NULL,
     version integer,
     uuid text NOT NULL,
@@ -145,10 +146,10 @@ CREATE TABLE IF NOT EXISTS devicetype (
     processed_comment text
 );
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- names
--- --------------------------------------------------------------------------------
-CREATE TABLE IF NOT EXISTS name (
+-- ----------------------------------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS wip_name (
     id bigint NOT NULL,
     version integer,
     uuid text NOT NULL,
@@ -171,12 +172,12 @@ CREATE TABLE IF NOT EXISTS name (
     processed_comment text
 );
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- data structures level 1
 --     from namepartrevision, level 1, SECTION     - no parent
 --     from namepartrevision, level 1, DEVICE_TYPE - no parent
--- --------------------------------------------------------------------------------
-insert into systemgroup (
+-- ----------------------------------------------------------------------------------------------------
+insert into wip_systemgroup (
     id,
     version,
     uuid,
@@ -202,7 +203,7 @@ left join useraccount ua_r on npr1.requestedby_id = ua_r.id
 left join useraccount ua_p on npr1.processedby_id = ua_p.id
 where np1.nameparttype = 'SECTION' and npr1.parent_id is null;
 
-insert into discipline (
+insert into wip_discipline (
     id,
     version,
     uuid,
@@ -228,12 +229,12 @@ left join useraccount ua_r on npr1.requestedby_id = ua_r.id
 left join useraccount ua_p on npr1.processedby_id = ua_p.id
 where np1.nameparttype = 'DEVICE_TYPE' and npr1.parent_id is null;
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- data structures level 2
 --     from namepartrevision, level 2, SECTION     - 1 parent level
 --     from namepartrevision, level 2, DEVICE_TYPE - 1 parent level
--- --------------------------------------------------------------------------------
-insert into system (
+-- ----------------------------------------------------------------------------------------------------
+insert into wip_system (
     id,
     version,
     uuid,
@@ -263,7 +264,7 @@ left join useraccount ua_p on npr2.processedby_id = ua_p.id
 where np2.nameparttype = 'SECTION' and npr2.parent_id in
 (select npr1.namepart_id from namepartrevision npr1, namepart np1 where npr1.namepart_id = np1.id and np1.nameparttype = 'SECTION' and npr1.parent_id is null);
 
-insert into devicegroup (
+insert into wip_devicegroup (
     id,
     version,
     uuid,
@@ -293,12 +294,12 @@ left join useraccount ua_p on npr2.processedby_id = ua_p.id
 where np2.nameparttype = 'DEVICE_TYPE' and npr2.parent_id in
 (select npr1.namepart_id from namepartrevision npr1, namepart np1 where npr1.namepart_id = np1.id and np1.nameparttype = 'DEVICE_TYPE' and npr1.parent_id is null);
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- data structures level 3
 --     from namepartrevision, level 3, SECTION     - 2 parent levels
 --     from namepartrevision, level 3, DEVICE_TYPE - 2 parent levels
--- --------------------------------------------------------------------------------
-insert into subsystem (
+-- ----------------------------------------------------------------------------------------------------
+insert into wip_subsystem (
     id,
     version,
     uuid,
@@ -331,7 +332,7 @@ select npr2.namepart_id from namepartrevision npr2, namepart np2 where npr2.name
 (select npr1.namepart_id from namepartrevision npr1, namepart np1 where npr1.namepart_id = np1.id and np1.nameparttype = 'SECTION' and npr1.parent_id is null)
 );
 
-insert into devicetype (
+insert into wip_devicetype (
     id,
     version,
     uuid,
@@ -364,13 +365,13 @@ select npr2.namepart_id from namepartrevision npr2, namepart np2 where npr2.name
 (select npr1.namepart_id from namepartrevision npr1, namepart np1 where npr1.namepart_id = np1.id and np1.nameparttype = 'DEVICE_TYPE' and npr1.parent_id is null)
 );
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- data names level 1
 --     from devicerevision
 --         referring to namepartrevision, level 1, SECTION
 --         referring to namepartrevision, level 3, DEVICE_TYPE
--- --------------------------------------------------------------------------------
-insert into name (
+-- ----------------------------------------------------------------------------------------------------
+insert into wip_name (
     id,
     version,
     uuid,
@@ -408,13 +409,13 @@ where dr.section_id in
 (
 select np.id from namepart np, namepartrevision npr where np.id = npr.namepart_id and npr.parent_id is null
 );
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- data names level 2
 --     from devicerevision
 --         referring to namepartrevision, level 2, SECTION
 --         referring to namepartrevision, level 3, DEVICE_TYPE
--- --------------------------------------------------------------------------------
-insert into name (
+-- ----------------------------------------------------------------------------------------------------
+insert into wip_name (
     id,
     version,
     uuid,
@@ -456,13 +457,13 @@ select np.id from namepart np, namepartrevision npr where np.id = npr.namepart_i
     )
 );
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- data names level 3
 --     from devicerevision
 --         referring to namepartrevision, level 3, SECTION
 --         referring to namepartrevision, level 3, DEVICE_TYPE
--- --------------------------------------------------------------------------------
-insert into name (
+-- ----------------------------------------------------------------------------------------------------
+insert into wip_name (
     id,
     version,
     uuid,
@@ -507,187 +508,187 @@ select np.id from namepart np, namepartrevision npr where np.id = npr.namepart_i
     )
 );
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- index
--- --------------------------------------------------------------------------------
-CREATE INDEX systemgroup_id_idx ON systemgroup (id);
-CREATE INDEX systemgroup_uuid_idx ON systemgroup (uuid);
-CREATE INDEX systemgroup_mnemonic_idx ON systemgroup (mnemonic);
-CREATE INDEX systemgroup_status_idx ON systemgroup (status);
-CREATE INDEX systemgroup_deleted_idx ON systemgroup (deleted);
-
-CREATE INDEX system_id_idx ON system (id);
-CREATE INDEX system_uuid_idx ON system (uuid);
-CREATE INDEX system_parent_uuid_idx ON system (parent_uuid);
-CREATE INDEX system_mnemonic_idx ON system (mnemonic);
-CREATE INDEX system_status_idx ON system (status);
-CREATE INDEX system_deleted_idx ON system (deleted);
-
-CREATE INDEX subsystem_id_idx ON subsystem (id);
-CREATE INDEX subsystem_uuid_idx ON subsystem (uuid);
-CREATE INDEX subsystem_parent_uuid_idx ON subsystem (parent_uuid);
-CREATE INDEX subsystem_mnemonic_idx ON subsystem (mnemonic);
-CREATE INDEX subsystem_status_idx ON subsystem (status);
-CREATE INDEX subsystem_deleted_idx ON subsystem (deleted);
-
-CREATE INDEX discipline_id_idx ON discipline (id);
-CREATE INDEX discipline_uuid_idx ON discipline (uuid);
-CREATE INDEX discipline_mnemonic_idx ON discipline (mnemonic);
-CREATE INDEX discipline_status_idx ON discipline (status);
-CREATE INDEX discipline_deleted_idx ON discipline (deleted);
-
-CREATE INDEX devicegroup_id_idx ON devicegroup (id);
-CREATE INDEX devicegroup_uuid_idx ON devicegroup (uuid);
-CREATE INDEX devicegroup_parent_uuid_idx ON devicegroup (parent_uuid);
-CREATE INDEX devicegroup_mnemonic_idx ON devicegroup (mnemonic);
-CREATE INDEX devicegroup_status_idx ON devicegroup (status);
-CREATE INDEX devicegroup_deleted_idx ON devicegroup (deleted);
-
-CREATE INDEX devicetype_id_idx ON devicetype (id);
-CREATE INDEX devicetype_uuid_idx ON devicetype (uuid);
-CREATE INDEX devicetype_parent_uuid_idx ON devicetype (parent_uuid);
-CREATE INDEX devicetype_mnemonic_idx ON devicetype (mnemonic);
-CREATE INDEX devicetype_status_idx ON devicetype (status);
-CREATE INDEX devicetype_deleted_idx ON devicetype (deleted);
-
-CREATE INDEX name_uuid_idx ON name (uuid);
-
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
+CREATE INDEX wip_systemgroup_id_idx ON wip_systemgroup (id);
+CREATE INDEX wip_systemgroup_uuid_idx ON wip_systemgroup (uuid);
+CREATE INDEX wip_systemgroup_mnemonic_idx ON wip_systemgroup (mnemonic);
+CREATE INDEX wip_systemgroup_status_idx ON wip_systemgroup (status);
+CREATE INDEX wip_systemgroup_deleted_idx ON wip_systemgroup (deleted);
+
+CREATE INDEX wip_system_id_idx ON wip_system (id);
+CREATE INDEX wip_system_uuid_idx ON wip_system (uuid);
+CREATE INDEX wip_system_parent_uuid_idx ON wip_system (parent_uuid);
+CREATE INDEX wip_system_mnemonic_idx ON wip_system (mnemonic);
+CREATE INDEX wip_system_status_idx ON wip_system (status);
+CREATE INDEX wip_system_deleted_idx ON wip_system (deleted);
+
+CREATE INDEX wip_subsystem_id_idx ON wip_subsystem (id);
+CREATE INDEX wip_subsystem_uuid_idx ON wip_subsystem (uuid);
+CREATE INDEX wip_subsystem_parent_uuid_idx ON wip_subsystem (parent_uuid);
+CREATE INDEX wip_subsystem_mnemonic_idx ON wip_subsystem (mnemonic);
+CREATE INDEX wip_subsystem_status_idx ON wip_subsystem (status);
+CREATE INDEX wip_subsystem_deleted_idx ON wip_subsystem (deleted);
+
+CREATE INDEX wip_discipline_id_idx ON wip_discipline (id);
+CREATE INDEX wip_discipline_uuid_idx ON wip_discipline (uuid);
+CREATE INDEX wip_discipline_mnemonic_idx ON wip_discipline (mnemonic);
+CREATE INDEX wip_discipline_status_idx ON wip_discipline (status);
+CREATE INDEX wip_discipline_deleted_idx ON wip_discipline (deleted);
+
+CREATE INDEX wip_devicegroup_id_idx ON wip_devicegroup (id);
+CREATE INDEX wip_devicegroup_uuid_idx ON wip_devicegroup (uuid);
+CREATE INDEX wip_devicegroup_parent_uuid_idx ON wip_devicegroup (parent_uuid);
+CREATE INDEX wip_devicegroup_mnemonic_idx ON wip_devicegroup (mnemonic);
+CREATE INDEX wip_devicegroup_status_idx ON wip_devicegroup (status);
+CREATE INDEX wip_devicegroup_deleted_idx ON wip_devicegroup (deleted);
+
+CREATE INDEX wip_devicetype_id_idx ON wip_devicetype (id);
+CREATE INDEX wip_devicetype_uuid_idx ON wip_devicetype (uuid);
+CREATE INDEX wip_devicetype_parent_uuid_idx ON wip_devicetype (parent_uuid);
+CREATE INDEX wip_devicetype_mnemonic_idx ON wip_devicetype (mnemonic);
+CREATE INDEX wip_devicetype_status_idx ON wip_devicetype (status);
+CREATE INDEX wip_devicetype_deleted_idx ON wip_devicetype (deleted);
+
+CREATE INDEX wip_name_uuid_idx ON wip_name (uuid);
+
+-- ----------------------------------------------------------------------------------------------------
 -- latest
--- --------------------------------------------------------------------------------
-update systemgroup sg set latest = true where sg.id = (
-  select max(sg2.id) from systemgroup sg2 where sg2.uuid = sg.uuid and sg2.status = 'APPROVED'
+-- ----------------------------------------------------------------------------------------------------
+update wip_systemgroup sg set latest = true where sg.id = (
+  select max(sg2.id) from wip_systemgroup sg2 where sg2.uuid = sg.uuid and sg2.status = 'APPROVED'
 );
-update system sys set latest = true where sys.id = (
-  select max(sys2.id) from system sys2 where sys2.uuid = sys.uuid and sys2.status = 'APPROVED'
+update wip_system sys set latest = true where sys.id = (
+  select max(sys2.id) from wip_system sys2 where sys2.uuid = sys.uuid and sys2.status = 'APPROVED'
 );
-update subsystem sub set latest = true where sub.id = (
-  select max(sub2.id) from subsystem sub2 where sub2.uuid = sub.uuid and sub2.status = 'APPROVED'
+update wip_subsystem sub set latest = true where sub.id = (
+  select max(sub2.id) from wip_subsystem sub2 where sub2.uuid = sub.uuid and sub2.status = 'APPROVED'
 );
 
-update discipline di set latest = true where di.id = (
-  select max(di2.id) from discipline di2 where di2.uuid = di.uuid and di2.status = 'APPROVED'
+update wip_discipline di set latest = true where di.id = (
+  select max(di2.id) from wip_discipline di2 where di2.uuid = di.uuid and di2.status = 'APPROVED'
 );
-update devicegroup dg set latest = true where dg.id = (
-  select max(dg2.id) from devicegroup dg2 where dg2.uuid = dg.uuid and dg2.status = 'APPROVED'
+update wip_devicegroup dg set latest = true where dg.id = (
+  select max(dg2.id) from wip_devicegroup dg2 where dg2.uuid = dg.uuid and dg2.status = 'APPROVED'
 );
-update devicetype dt set latest = true where dt.id = (
-  select max(dt2.id) from devicetype dt2 where dt2.uuid = dt.uuid and dt2.status = 'APPROVED'
+update wip_devicetype dt set latest = true where dt.id = (
+  select max(dt2.id) from wip_devicetype dt2 where dt2.uuid = dt.uuid and dt2.status = 'APPROVED'
 );
 
-update name en set latest = true where en.id = (
-  select max(en2.id) from name en2 where en2.uuid = en.uuid
+update wip_name en set latest = true where en.id = (
+  select max(en2.id) from wip_name en2 where en2.uuid = en.uuid
 );
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- index
--- --------------------------------------------------------------------------------
-CREATE INDEX name_id_idx ON name (id);
-CREATE INDEX name_systemgroup_uuid_idx ON name (systemgroup_uuid);
-CREATE INDEX name_system_uuid_idx ON name (system_uuid);
-CREATE INDEX name_subsystem_uuid_idx ON name (subsystem_uuid);
-CREATE INDEX name_devicetype_uuid_idx ON name (devicetype_uuid);
-CREATE INDEX name_convention_name_idx ON name (convention_name);
-CREATE INDEX name_status_idx ON name (status);
-CREATE INDEX name_deleted_idx ON name (deleted);
-
-CREATE INDEX systemgroup_latest_idx ON systemgroup (latest);
-CREATE INDEX system_latest_idx ON system (latest);
-CREATE INDEX subsystem_latest_idx ON subsystem (latest);
-CREATE INDEX discipline_latest_idx ON discipline (latest);
-CREATE INDEX devicegroup_latest_idx ON devicegroup (latest);
-CREATE INDEX devicetype_latest_idx ON devicetype (latest);
-CREATE INDEX name_latest_idx ON name (latest);
-
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
+CREATE INDEX wip_name_id_idx ON wip_name (id);
+CREATE INDEX wip_name_systemgroup_uuid_idx ON wip_name (systemgroup_uuid);
+CREATE INDEX wip_name_system_uuid_idx ON wip_name (system_uuid);
+CREATE INDEX wip_name_subsystem_uuid_idx ON wip_name (subsystem_uuid);
+CREATE INDEX wip_name_devicetype_uuid_idx ON wip_name (devicetype_uuid);
+CREATE INDEX wip_name_convention_name_idx ON wip_name (convention_name);
+CREATE INDEX wip_name_status_idx ON wip_name (status);
+CREATE INDEX wip_name_deleted_idx ON wip_name (deleted);
+
+CREATE INDEX wip_systemgroup_latest_idx ON wip_systemgroup (latest);
+CREATE INDEX wip_system_latest_idx ON wip_system (latest);
+CREATE INDEX wip_subsystem_latest_idx ON wip_subsystem (latest);
+CREATE INDEX wip_discipline_latest_idx ON wip_discipline (latest);
+CREATE INDEX wip_devicegroup_latest_idx ON wip_devicegroup (latest);
+CREATE INDEX wip_devicetype_latest_idx ON wip_devicetype (latest);
+CREATE INDEX wip_name_latest_idx ON wip_name (latest);
+
+-- ----------------------------------------------------------------------------------------------------
 -- sequence
--- --------------------------------------------------------------------------------
-CREATE SEQUENCE systemgroup_id_seq
+-- ----------------------------------------------------------------------------------------------------
+CREATE SEQUENCE wip_systemgroup_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;
-CREATE SEQUENCE system_id_seq
+CREATE SEQUENCE wip_system_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;
-CREATE SEQUENCE subsystem_id_seq
+CREATE SEQUENCE wip_subsystem_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;
-CREATE SEQUENCE discipline_id_seq
+CREATE SEQUENCE wip_discipline_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;
-CREATE SEQUENCE devicegroup_id_seq
+CREATE SEQUENCE wip_devicegroup_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;
-CREATE SEQUENCE devicetype_id_seq
+CREATE SEQUENCE wip_devicetype_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;
-CREATE SEQUENCE name_id_seq
+CREATE SEQUENCE wip_name_id_seq
     START WITH 1
     INCREMENT BY 1
     NO MINVALUE
     NO MAXVALUE
     CACHE 1;
 
-SELECT setval('systemgroup_id_seq', (select max(id) from systemgroup));
-SELECT setval('system_id_seq', (select max(id) from "system"));
-SELECT setval('subsystem_id_seq', (select max(id) from "subsystem"));
-SELECT setval('discipline_id_seq', (select max(id) from discipline));
-SELECT setval('devicegroup_id_seq', (select max(id) from devicegroup));
-SELECT setval('devicetype_id_seq', (select max(id) from devicetype));
-SELECT setval('name_id_seq', (select max(id) from "name"));
-
-ALTER SEQUENCE systemgroup_id_seq OWNED BY systemgroup.id;
-ALTER SEQUENCE system_id_seq OWNED BY system.id;
-ALTER SEQUENCE subsystem_id_seq OWNED BY subsystem.id;
-ALTER SEQUENCE discipline_id_seq OWNED BY discipline.id;
-ALTER SEQUENCE devicegroup_id_seq OWNED BY devicegroup.id;
-ALTER SEQUENCE devicetype_id_seq OWNED BY devicetype.id;
-ALTER SEQUENCE name_id_seq OWNED BY name.id;
-
-ALTER TABLE ONLY systemgroup ALTER COLUMN id SET DEFAULT nextval('systemgroup_id_seq'::regclass);
-ALTER TABLE ONLY system ALTER COLUMN id SET DEFAULT nextval('system_id_seq'::regclass);
-ALTER TABLE ONLY subsystem ALTER COLUMN id SET DEFAULT nextval('subsystem_id_seq'::regclass);
-ALTER TABLE ONLY discipline ALTER COLUMN id SET DEFAULT nextval('discipline_id_seq'::regclass);
-ALTER TABLE ONLY devicegroup ALTER COLUMN id SET DEFAULT nextval('devicegroup_id_seq'::regclass);
-ALTER TABLE ONLY devicetype ALTER COLUMN id SET DEFAULT nextval('devicetype_id_seq'::regclass);
-ALTER TABLE ONLY name ALTER COLUMN id SET DEFAULT nextval('name_id_seq'::regclass);
-
--- --------------------------------------------------------------------------------
+SELECT setval('wip_systemgroup_id_seq', (select max(id) from wip_systemgroup));
+SELECT setval('wip_system_id_seq', (select max(id) from wip_system));
+SELECT setval('wip_subsystem_id_seq', (select max(id) from wip_subsystem));
+SELECT setval('wip_discipline_id_seq', (select max(id) from wip_discipline));
+SELECT setval('wip_devicegroup_id_seq', (select max(id) from wip_devicegroup));
+SELECT setval('wip_devicetype_id_seq', (select max(id) from wip_devicetype));
+SELECT setval('wip_name_id_seq', (select max(id) from wip_name));
+
+ALTER SEQUENCE wip_systemgroup_id_seq OWNED BY wip_systemgroup.id;
+ALTER SEQUENCE wip_system_id_seq OWNED BY wip_system.id;
+ALTER SEQUENCE wip_subsystem_id_seq OWNED BY wip_subsystem.id;
+ALTER SEQUENCE wip_discipline_id_seq OWNED BY wip_discipline.id;
+ALTER SEQUENCE wip_devicegroup_id_seq OWNED BY wip_devicegroup.id;
+ALTER SEQUENCE wip_devicetype_id_seq OWNED BY wip_devicetype.id;
+ALTER SEQUENCE wip_name_id_seq OWNED BY wip_name.id;
+
+ALTER TABLE ONLY wip_systemgroup ALTER COLUMN id SET DEFAULT nextval('wip_systemgroup_id_seq'::regclass);
+ALTER TABLE ONLY wip_system ALTER COLUMN id SET DEFAULT nextval('wip_system_id_seq'::regclass);
+ALTER TABLE ONLY wip_subsystem ALTER COLUMN id SET DEFAULT nextval('wip_subsystem_id_seq'::regclass);
+ALTER TABLE ONLY wip_discipline ALTER COLUMN id SET DEFAULT nextval('wip_discipline_id_seq'::regclass);
+ALTER TABLE ONLY wip_devicegroup ALTER COLUMN id SET DEFAULT nextval('wip_devicegroup_id_seq'::regclass);
+ALTER TABLE ONLY wip_devicetype ALTER COLUMN id SET DEFAULT nextval('wip_devicetype_id_seq'::regclass);
+ALTER TABLE ONLY wip_name ALTER COLUMN id SET DEFAULT nextval('wip_name_id_seq'::regclass);
+
+-- ----------------------------------------------------------------------------------------------------
 -- primary key
--- --------------------------------------------------------------------------------
-ALTER TABLE systemgroup ADD CONSTRAINT systemgroup_pk PRIMARY KEY (id);
-ALTER TABLE system ADD CONSTRAINT system_pk PRIMARY KEY (id);
-ALTER TABLE subsystem ADD CONSTRAINT subsystem_pk PRIMARY KEY (id);
-ALTER TABLE discipline ADD CONSTRAINT discipline_pk PRIMARY KEY (id);
-ALTER TABLE devicegroup ADD CONSTRAINT devicegroup_pk PRIMARY KEY (id);
-ALTER TABLE devicetype ADD CONSTRAINT devicetype_pk PRIMARY KEY (id);
-ALTER TABLE name ADD CONSTRAINT name_pk PRIMARY KEY (id);
-
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
+ALTER TABLE wip_systemgroup ADD CONSTRAINT wip_systemgroup_pk PRIMARY KEY (id);
+ALTER TABLE wip_system ADD CONSTRAINT wip_system_pk PRIMARY KEY (id);
+ALTER TABLE wip_subsystem ADD CONSTRAINT wip_subsystem_pk PRIMARY KEY (id);
+ALTER TABLE wip_discipline ADD CONSTRAINT wip_discipline_pk PRIMARY KEY (id);
+ALTER TABLE wip_devicegroup ADD CONSTRAINT wip_devicegroup_pk PRIMARY KEY (id);
+ALTER TABLE wip_devicetype ADD CONSTRAINT wip_devicetype_pk PRIMARY KEY (id);
+ALTER TABLE wip_name ADD CONSTRAINT wip_name_pk PRIMARY KEY (id);
+
+-- ----------------------------------------------------------------------------------------------------
 -- foreign key
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- function
--- --------------------------------------------------------------------------------
-CREATE OR REPLACE FUNCTION get_mnemonic_path_system_structure(convention_name text)
+-- ----------------------------------------------------------------------------------------------------
+CREATE OR REPLACE FUNCTION wip_get_mnemonic_path_system_structure(convention_name text)
     RETURNS text
     LANGUAGE plpgsql
 AS
@@ -703,7 +704,7 @@ BEGIN
 END;
 $$;
 
-CREATE OR REPLACE FUNCTION get_mnemonic_path_device_structure(convention_name text)
+CREATE OR REPLACE FUNCTION wip_get_mnemonic_path_device_structure(convention_name text)
     RETURNS text
     LANGUAGE plpgsql
 AS
@@ -731,7 +732,7 @@ BEGIN
 END;
 $$;
 
-CREATE OR REPLACE FUNCTION get_instance_index(convention_name text)
+CREATE OR REPLACE FUNCTION wip_get_instance_index(convention_name text)
  RETURNS text
  LANGUAGE plpgsql
 AS
@@ -760,7 +761,7 @@ BEGIN
 END;
 $$;
 
-CREATE OR REPLACE FUNCTION get_mnemonic_path_system(system_uuid text)
+CREATE OR REPLACE FUNCTION wip_get_mnemonic_path_system(system_uuid text)
     RETURNS text
     LANGUAGE plpgsql
 AS
@@ -768,7 +769,7 @@ $$
 DECLARE
     system_mnemonic text;
 BEGIN
-    select mnemonic into system_mnemonic from "system" where uuid = system_uuid and latest = true;
+    select mnemonic into system_mnemonic from wip_system where uuid = system_uuid and latest = true;
 
     if system_mnemonic is not null then
         return system_mnemonic;
@@ -778,7 +779,7 @@ BEGIN
 END;
 $$;
 
-CREATE OR REPLACE FUNCTION get_mnemonic_path_subsystem(subsystem_uuid text)
+CREATE OR REPLACE FUNCTION wip_get_mnemonic_path_subsystem(subsystem_uuid text)
     RETURNS text
     LANGUAGE plpgsql
 AS
@@ -788,8 +789,8 @@ DECLARE
     system_uuid text;
     system_mnemonic text;
 BEGIN
-    select parent_uuid, mnemonic into system_uuid, subsystem_mnemonic from subsystem where uuid = subsystem_uuid and latest = true;
-    select mnemonic into system_mnemonic from "system" where uuid = system_uuid and latest = true;
+    select parent_uuid, mnemonic into system_uuid, subsystem_mnemonic from wip_subsystem where uuid = subsystem_uuid and latest = true;
+    select mnemonic into system_mnemonic from wip_system where uuid = system_uuid and latest = true;
 
     if system_mnemonic is not null and subsystem_mnemonic is not null then
         return concat(system_mnemonic, '-', subsystem_mnemonic);
@@ -799,7 +800,7 @@ BEGIN
 END;
 $$;
 
-CREATE OR REPLACE FUNCTION get_mnemonic_path_devicegroup(devicegroup_uuid text)
+CREATE OR REPLACE FUNCTION wip_get_mnemonic_path_devicegroup(devicegroup_uuid text)
     RETURNS text
     LANGUAGE plpgsql
 AS
@@ -808,8 +809,8 @@ DECLARE
     discipline_uuid text;
     discipline_mnemonic text;
 BEGIN
-    select parent_uuid into discipline_uuid from devicegroup where uuid = devicegroup_uuid and latest = true;
-    select mnemonic into discipline_mnemonic from discipline where uuid = discipline_uuid and latest = true;
+    select parent_uuid into discipline_uuid from wip_devicegroup where uuid = devicegroup_uuid and latest = true;
+    select mnemonic into discipline_mnemonic from wip_discipline where uuid = discipline_uuid and latest = true;
 
     if discipline_mnemonic is not null then
         return discipline_mnemonic;
@@ -819,7 +820,7 @@ BEGIN
 END;
 $$;
 
-CREATE OR REPLACE FUNCTION get_mnemonic_path_devicetype(devicetype_uuid text)
+CREATE OR REPLACE FUNCTION wip_get_mnemonic_path_devicetype(devicetype_uuid text)
     RETURNS text
     LANGUAGE plpgsql
 AS
@@ -830,9 +831,9 @@ DECLARE
     discipline_uuid text;
     discipline_mnemonic text;
 BEGIN
-    select parent_uuid, mnemonic into devicegroup_uuid, devicetype_mnemonic from devicetype where uuid = devicetype_uuid and latest = true;
-    select parent_uuid, mnemonic into discipline_uuid from devicegroup where uuid = devicegroup_uuid and latest = true;
-    select mnemonic into discipline_mnemonic from discipline where uuid = discipline_uuid and latest = true;
+    select parent_uuid, mnemonic into devicegroup_uuid, devicetype_mnemonic from wip_devicetype where uuid = devicetype_uuid and latest = true;
+    select parent_uuid, mnemonic into discipline_uuid from wip_devicegroup where uuid = devicegroup_uuid and latest = true;
+    select mnemonic into discipline_mnemonic from wip_discipline where uuid = discipline_uuid and latest = true;
 
     if discipline_mnemonic is not null and devicetype_mnemonic is not null then
         return concat(discipline_mnemonic, '-', devicetype_mnemonic);
diff --git a/src/main/resources/db/migration/V5.1__Data_transformation_status_deleted.sql b/src/main/resources/db/migration/V5.1__Data_transformation_status_deleted.sql
index 5a172a122931b9c2f70dfeec3a8d57289225ed4e..1d416d580d1ae7189f78e2318d390b97ffefeb46 100644
--- a/src/main/resources/db/migration/V5.1__Data_transformation_status_deleted.sql
+++ b/src/main/resources/db/migration/V5.1__Data_transformation_status_deleted.sql
@@ -1,4 +1,4 @@
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- About
 --     transformation script
 --     postgresql 9.6.7
@@ -11,9 +11,10 @@
 --         will not affect entries considered history
 --     strong (!) recommendation to make sure that no items with status pending exist prior to running this script (any such to be approved, cancelled, rejected)
 --     order of items is important
--- --------------------------------------------------------------------------------
+--     notice prefix "wip_" meaning "work in progress" as tables are temporary
+-- ----------------------------------------------------------------------------------------------------
 
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 -- structures
 --     systemgroup
 --     system
@@ -21,28 +22,28 @@
 --     discipline
 --     devicegroup
 --     devicetype
--- --------------------------------------------------------------------------------
+-- ----------------------------------------------------------------------------------------------------
 
-update systemgroup s set latest = true, deleted = true where (
-                 not exists (select s2.id from systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false)
+update wip_systemgroup s set latest = true, deleted = true where (
+                 not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false)
 );
 
-update system s set latest = true, deleted = true where (
-                 not exists (select s2.id from system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from system s2 where s2."uuid" = s."uuid" and s2.latest=false)
+update wip_system s set latest = true, deleted = true where (
+                 not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false)
 );
 
-update subsystem s set latest = true, deleted = true where (
-                 not exists (select s2.id from subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false)
+update wip_subsystem s set latest = true, deleted = true where (
+                 not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false)
 );
 
-update discipline s set latest = true, deleted = true where (
-                 not exists (select s2.id from discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from discipline s2 where s2."uuid" = s."uuid" and s2.latest=false)
+update wip_discipline s set latest = true, deleted = true where (
+                 not exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=false)
 );
 
-update devicegroup s set latest = true, deleted = true where (
-                 not exists (select s2.id from devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=false)
+update wip_devicegroup s set latest = true, deleted = true where (
+                 not exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=false)
 );
 
-update devicetype s set latest = true, deleted = true where (
-                 not exists (select s2.id from devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false)
+update wip_devicetype s set latest = true, deleted = true where (
+                 not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false)
 );
diff --git a/src/main/resources/db/migration/V5.2__Data_transformation_status_deleted.sql b/src/main/resources/db/migration/V5.2__Data_transformation_status_deleted.sql
index 5b86c90271af5b330c05f2d9a52dc7e85cbbe7f1..33dd1b6c104607530d6bd77f830e7d301435fa75 100644
--- a/src/main/resources/db/migration/V5.2__Data_transformation_status_deleted.sql
+++ b/src/main/resources/db/migration/V5.2__Data_transformation_status_deleted.sql
@@ -10,7 +10,7 @@
 --         may affect entries with statuses PENDING, CANCELLED, REJECTED
 --         will not affect entries considered history
 --     reason is that such entries have never been active and while removing them will delete some part of history,
---         the benefit is unambiguous content is database. Alternative is deleted entries with statuses
+--         the benefit is unambiguous content in database. Alternative is deleted entries with statuses
 --         pending, cancelled, rejected which may be ambiguous.
 --     strong (!) requirement to make sure that no items with status pending exist prior to running this script (any such to be approved, cancelled, rejected)
 --     order of items is important
@@ -26,38 +26,38 @@
 --     devicetype
 -- --------------------------------------------------------------------------------
 
-delete from systemgroup where uuid in (
-    select s.uuid from systemgroup s where (
-                 not exists (select s2.id from systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false)
+delete from wip_systemgroup where uuid in (
+    select s.uuid from wip_systemgroup s where (
+                 not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false)
     )
 );
 
-delete from system where uuid in (
-    select s.uuid from system s where (
-                 not exists (select s2.id from system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from system s2 where s2."uuid" = s."uuid" and s2.latest=false)
+delete from wip_system where uuid in (
+    select s.uuid from wip_system s where (
+                 not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false)
     )
 );
 
-delete from subsystem where uuid in (
-    select s.uuid from subsystem s where (
-                 not exists (select s2.id from subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false)
+delete from wip_subsystem where uuid in (
+    select s.uuid from wip_subsystem s where (
+                 not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false)
     )
 );
 
-delete from discipline where uuid in (
-    select s.uuid from discipline s where (
-                 not exists (select s2.id from discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from discipline s2 where s2."uuid" = s."uuid" and s2.latest=false)
+delete from wip_discipline where uuid in (
+    select s.uuid from wip_discipline s where (
+                 not exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=false)
     )
 );
 
-delete from devicegroup where uuid in (
-    select s.uuid from devicegroup s where (
-                 not exists (select s2.id from devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=false)
+delete from wip_devicegroup where uuid in (
+    select s.uuid from wip_devicegroup s where (
+                 not exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=false)
     )
 );
 
-delete from devicetype s0 where s0."uuid" in (
-    select s.uuid from devicetype s where (
-                 not exists (select s2.id from devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false)
+delete from wip_devicetype s0 where s0."uuid" in (
+    select s.uuid from wip_devicetype s where (
+                 not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id = (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false)
     )
 );
diff --git a/src/main/resources/db/migration/V6.1__Schema_data_migration_audit.sql b/src/main/resources/db/migration/V6.1__Schema_data_migration_audit.sql
new file mode 100644
index 0000000000000000000000000000000000000000..0c314278fd8b95b6fa63dbdccddc9796c1b7106d
--- /dev/null
+++ b/src/main/resources/db/migration/V6.1__Schema_data_migration_audit.sql
@@ -0,0 +1,1666 @@
+-- ----------------------------------------------------------------------------------------------------
+-- About
+--     migration script
+--     postgresql 9.6.7
+-- Content
+--     structures
+--     names
+--     data structures level 1
+--         systemgroup    +    audit
+--         discipline     +    audit
+--     data structures level 2
+--         system         +    audit
+--         devicegroup    +    audit
+--     data structures level 3
+--         subsystem      +    audit
+--         devicetype     +    audit
+--     data names
+--         systemgroup_id    and    not devicetype_id    +    audit
+--         system_id         and    not devicetype_id    +    audit
+--         subsystem_id      and    not devicetype_id    +    audit
+--         systemgroup_id    and    devicetype_id        +    audit
+--         system_id         and    devicetype_id        +    audit
+--         subsystem_id      and    devicetype_id        +    audit
+--     index
+--     sequence
+--     primary key
+--     foreign key
+--     function
+-- Note
+--     about audit tables and data
+--         data comes from "wip" tables
+--     order of items is important
+--     notice prefix "wip_" meaning "work in progress" as tables are temporary
+-- ----------------------------------------------------------------------------------------------------
+--     data structures (parent_id)
+--     data names
+--         selection of proper id to refer to - systemgroup, system, subsystem, devicetype
+--                     exclude content (with latest) before latest
+--                     exclude content (with latest) after  latest (cancelled, rejected)
+--                     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
+--             <-->
+--                     select * from structure s
+--                     where (
+--                                 not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
+--                             and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+--                             and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
+--                     )
+-- ----------------------------------------------------------------------------------------------------
+--     retrieve parent id for audit structure
+--         1 or 2 or 3
+--                     1.  get id from parent that is approved and was processed prior to child or within 10 seconds
+--                     2.  get id from parent that is approved and was requested prior to child or within 10 minutes
+--                     3.  get id from parent that was requested prior to child or within 10 minutes
+--             <-->
+--                     coalesce (
+--                     (select max(s3.id) from parent s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+--                     (select max(s3.id) from parent s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+--                     (select max(s3.id) from parent s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+--                     )
+-- ----------------------------------------------------------------------------------------------------
+--     non-audit tables contain valid
+--     audit tables contain obsolete     <---
+-- ----------------------------------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------------------------------
+-- structures
+-- ----------------------------------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS systemgroup (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS system (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS subsystem (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+-- ----------------------------------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS discipline (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS devicegroup (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS devicetype (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+-- ----------------------------------------------------------------------------------------------------
+-- name
+-- ----------------------------------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS name (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    systemgroup_id bigint,
+    system_id bigint,
+    subsystem_id bigint,
+    devicetype_id bigint,
+    instance_index text,
+    convention_name text,
+    convention_name_equivalence text,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+-- ----------------------------------------------------------------------------------------------------
+-- audit
+-- ----------------------------------------------------------------------------------------------------
+
+CREATE TABLE IF NOT EXISTS audit_structure (
+    audit_id bigint NOT NULL,
+    audit_version integer,
+    audit_table text NOT NULL,
+    audit_operation text,
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS audit_name (
+    audit_id bigint NOT NULL,
+    audit_version integer,
+    audit_table text NOT NULL,
+    audit_operation text,
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    systemgroup_id bigint,
+    system_id bigint,
+    subsystem_id bigint,
+    devicetype_id bigint,
+    instance_index text,
+    convention_name text,
+    convention_name_equivalence text,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+-- ----------------------------------------------------------------------------------------------------
+-- data structures level 1
+--     systemgroup    +    audit
+--     discipline     +    audit
+-- ----------------------------------------------------------------------------------------------------
+--     from wip_systemgroup
+--     from wip_discipline
+-- ----------------------------------------------------------------------------------------------------
+insert into systemgroup (
+    id,
+    version,
+    uuid,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid, s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_systemgroup s
+where (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'systemgroup', null,
+s.id, s.version, s.uuid, null, s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_systemgroup s
+where not (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+-- ----------------------------------------------------------------------------------------------------
+insert into discipline (
+    id,
+    version,
+    uuid,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid, s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_discipline s
+where (
+            not (exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'discipline', null,
+s.id, s.version, s.uuid, null, s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_discipline s
+where not (
+            not (exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+-- ----------------------------------------------------------------------------------------------------
+-- data structures level 2
+--     system         +    audit
+--     devicegroup    +    audit
+-- ----------------------------------------------------------------------------------------------------
+--     from wip_system
+--     from wip_devicegroup
+-- ----------------------------------------------------------------------------------------------------
+insert into system (
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid,
+(select sg.id from wip_systemgroup sg
+where sg.uuid = s.parent_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true) and sg.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true) and sg.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true) and sg.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true) and sg.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=false))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_system s
+where (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'system', null,
+s.id, s.version, s.uuid,
+(coalesce (
+(select max(s3.id) from wip_systemgroup s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+(select max(s3.id) from wip_systemgroup s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+(select max(s3.id) from wip_systemgroup s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_system s
+where not (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+-- ----------------------------------------------------------------------------------------------------
+insert into devicegroup (
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid,
+(select di.id from wip_discipline di
+where di.uuid = s.parent_uuid and (
+            not (exists (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true) and di.id < (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true) and di.id > (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true) and di.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true) and di.id < (select max(s2.id) from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=false))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_devicegroup s
+where (
+            not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'devicegroup', null,
+s.id, s.version, s.uuid,
+(coalesce (
+(select max(s3.id) from wip_discipline s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+(select max(s3.id) from wip_discipline s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+(select max(s3.id) from wip_discipline s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_devicegroup s
+where not (
+            not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+-- ----------------------------------------------------------------------------------------------------
+-- data structures level 3
+--     subsystem      +    audit
+--     devicetype     +    audit
+-- ----------------------------------------------------------------------------------------------------
+--     from wip_subsystem
+--     from wip_devicetype
+-- ----------------------------------------------------------------------------------------------------
+insert into subsystem (
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid,
+(select sys.id from wip_system sys
+where sys.uuid = s.parent_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true) and sys.id < (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true) and sys.id > (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true) and sys.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true) and sys.id < (select max(s2.id) from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=false))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_subsystem s
+where (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'subsystem', null,
+s.id, s.version, s.uuid,
+(coalesce (
+(select max(s3.id) from wip_system s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+(select max(s3.id) from wip_system s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+(select max(s3.id) from wip_system s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_subsystem s
+where not (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+-- ----------------------------------------------------------------------------------------------------
+insert into devicetype (
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid,
+(select dg.id from wip_devicegroup dg
+where dg.uuid = s.parent_uuid and (
+            not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true) and dg.id < (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true) and dg.id > (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true) and dg.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true) and dg.id < (select max(s2.id) from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=false))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_devicetype s
+where (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'devicetype', null,
+s.id, s.version, s.uuid,
+(coalesce (
+(select max(s3.id) from wip_devicegroup s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+(select max(s3.id) from wip_devicegroup s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+(select max(s3.id) from wip_devicegroup s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_devicetype s
+where not (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+-- ----------------------------------------------------------------------------------------------------
+-- data names
+--     1) systemgroup_id    and    not devicetype_id    +    audit
+--     2) system_id         and    not devicetype_id    +    audit
+--     3) subsystem_id      and    not devicetype_id    +    audit
+--     4) systemgroup_id    and    devicetype_id        +    audit
+--     5) system_id         and    devicetype_id        +    audit
+--     6) subsystem_id      and    devicetype_id        +    audit
+-- ----------------------------------------------------------------------------------------------------
+--     from wip_systemgroup
+--     from wip_systemg
+--     from wip_subsystem
+--     from wip_systemgroup    +    wip_devicetype
+--     from wip_systemg        +    wip_devicetype
+--     from wip_subsystem      +    wip_devicetype
+-- ----------------------------------------------------------------------------------------------------
+-- 1)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+(select s.id from wip_systemgroup s
+where s.uuid = n.systemgroup_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is not null and n.system_uuid is null and n.subsystem_uuid is null and n.devicetype_uuid is null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+(select s.id from wip_systemgroup s
+where s.uuid = n.systemgroup_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+(n.latest = false) and
+n.systemgroup_uuid is not null and n.system_uuid is null and n.subsystem_uuid is null and n.devicetype_uuid is null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 2)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+null,
+(select s.id from wip_system s
+where s.uuid = n.system_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is null and n.system_uuid is not null and n.subsystem_uuid is null and n.devicetype_uuid is null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+null,
+(select s.id from wip_system s
+where s.uuid = n.system_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+(n.latest = false) and
+n.systemgroup_uuid is null and n.system_uuid is not null and n.subsystem_uuid is null and n.devicetype_uuid is null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 3)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+null,
+null,
+(select s.id from wip_subsystem s
+where s.uuid = n.subsystem_uuid and (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is null and n.system_uuid is null and n.subsystem_uuid is not null and n.devicetype_uuid is null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+null,
+null,
+(select s.id from wip_subsystem s
+where s.uuid = n.subsystem_uuid and (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+(n.latest = false) and
+n.systemgroup_uuid is null and n.system_uuid is null and n.subsystem_uuid is not null and n.devicetype_uuid is null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 4)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+(select s.id from wip_systemgroup s
+where s.uuid = n.systemgroup_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is not null and n.system_uuid is null and n.subsystem_uuid is null and n.devicetype_uuid is not null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+(select s.id from wip_systemgroup s
+where s.uuid = n.systemgroup_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+(select s.id from devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+(n.latest = false) and
+n.systemgroup_uuid is not null and n.system_uuid is null and n.subsystem_uuid is null and n.devicetype_uuid is not null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 5)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+null,
+(select s.id from wip_system s
+where s.uuid = n.system_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is null and n.system_uuid is not null and n.subsystem_uuid is null and n.devicetype_uuid is not null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+null,
+(select s.id from wip_system s
+where s.uuid = n.system_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+(n.latest = false) and
+n.systemgroup_uuid is null and n.system_uuid is not null and n.subsystem_uuid is null and n.devicetype_uuid is not null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 6)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+null,
+null,
+(select s.id from wip_subsystem s
+where s.uuid = n.subsystem_uuid and (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is null and n.system_uuid is null and n.subsystem_uuid is not null and n.devicetype_uuid is not null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+null,
+null,
+(select s.id from wip_subsystem s
+where s.uuid = n.subsystem_uuid and (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+(n.latest = false) and
+n.systemgroup_uuid is null and n.system_uuid is null and n.subsystem_uuid is not null and n.devicetype_uuid is not null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- index
+-- ----------------------------------------------------------------------------------------------------
+CREATE INDEX systemgroup_id_idx ON systemgroup (id);
+CREATE INDEX systemgroup_uuid_idx ON systemgroup (uuid);
+CREATE INDEX systemgroup_mnemonic_idx ON systemgroup (mnemonic);
+CREATE INDEX systemgroup_status_idx ON systemgroup (status);
+CREATE INDEX systemgroup_deleted_idx ON systemgroup (deleted);
+
+CREATE INDEX system_id_idx ON system (id);
+CREATE INDEX system_uuid_idx ON system (uuid);
+CREATE INDEX system_parent_id_idx ON system (parent_id);
+CREATE INDEX system_mnemonic_idx ON system (mnemonic);
+CREATE INDEX system_status_idx ON system (status);
+CREATE INDEX system_deleted_idx ON system (deleted);
+
+CREATE INDEX subsystem_id_idx ON subsystem (id);
+CREATE INDEX subsystem_uuid_idx ON subsystem (uuid);
+CREATE INDEX subsystem_parent_id_idx ON subsystem (parent_id);
+CREATE INDEX subsystem_mnemonic_idx ON subsystem (mnemonic);
+CREATE INDEX subsystem_status_idx ON subsystem (status);
+CREATE INDEX subsystem_deleted_idx ON subsystem (deleted);
+
+CREATE INDEX discipline_id_idx ON discipline (id);
+CREATE INDEX discipline_uuid_idx ON discipline (uuid);
+CREATE INDEX discipline_mnemonic_idx ON discipline (mnemonic);
+CREATE INDEX discipline_status_idx ON discipline (status);
+CREATE INDEX discipline_deleted_idx ON discipline (deleted);
+
+CREATE INDEX devicegroup_id_idx ON devicegroup (id);
+CREATE INDEX devicegroup_uuid_idx ON devicegroup (uuid);
+CREATE INDEX devicegroup_parent_id_idx ON devicegroup (parent_id);
+CREATE INDEX devicegroup_mnemonic_idx ON devicegroup (mnemonic);
+CREATE INDEX devicegroup_status_idx ON devicegroup (status);
+CREATE INDEX devicegroup_deleted_idx ON devicegroup (deleted);
+
+CREATE INDEX devicetype_id_idx ON devicetype (id);
+CREATE INDEX devicetype_uuid_idx ON devicetype (uuid);
+CREATE INDEX devicetype_parent_id_idx ON devicetype (parent_id);
+CREATE INDEX devicetype_mnemonic_idx ON devicetype (mnemonic);
+CREATE INDEX devicetype_status_idx ON devicetype (status);
+CREATE INDEX devicetype_deleted_idx ON devicetype (deleted);
+
+CREATE INDEX name_id_idx ON name (id);
+CREATE INDEX name_uuid_idx ON name (uuid);
+CREATE INDEX name_systemgroup_id_idx ON name (systemgroup_id);
+CREATE INDEX name_system_id_idx ON name (system_id);
+CREATE INDEX name_subsystem_id_idx ON name (subsystem_id);
+CREATE INDEX name_devicetype_id_idx ON name (devicetype_id);
+CREATE INDEX name_convention_name_idx ON name (convention_name);
+CREATE INDEX name_status_idx ON name (status);
+CREATE INDEX name_deleted_idx ON name (deleted);
+
+CREATE INDEX audit_structure_audit_id_idx ON audit_structure (audit_id);
+CREATE INDEX audit_structure_audit_table_idx ON audit_structure (audit_table);
+CREATE INDEX audit_structure_audit_operation_idx ON audit_structure (audit_operation);
+CREATE INDEX audit_structure_id_idx ON audit_structure (id);
+CREATE INDEX audit_structure_uuid_idx ON audit_structure (uuid);
+CREATE INDEX audit_structure_parent_id_idx ON audit_structure (parent_id);
+CREATE INDEX audit_structure_mnemonic_idx ON audit_structure (mnemonic);
+CREATE INDEX audit_structure_status_idx ON audit_structure (status);
+CREATE INDEX audit_structure_deleted_idx ON audit_structure (deleted);
+
+CREATE INDEX audit_name_audit_id_idx ON audit_name (audit_id);
+CREATE INDEX audit_name_audit_table_idx ON audit_name (audit_table);
+CREATE INDEX audit_name_audit_operation_idx ON audit_name (audit_operation);
+CREATE INDEX audit_name_id_idx ON audit_name (id);
+CREATE INDEX audit_name_uuid_idx ON audit_name (uuid);
+CREATE INDEX audit_name_systemgroup_id_idx ON audit_name (systemgroup_id);
+CREATE INDEX audit_name_system_id_idx on audit_name (system_id);
+CREATE INDEX audit_name_subsystem_id_idx ON audit_name (subsystem_id);
+CREATE INDEX audit_name_devicetype_id_idx ON audit_name (devicetype_id);
+CREATE INDEX audit_name_convention_name_idx ON audit_name (convention_name);
+CREATE INDEX audit_name_status_idx ON audit_name (status);
+CREATE INDEX audit_name_deleted_idx ON audit_name (deleted);
+
+-- ----------------------------------------------------------------------------------------------------
+-- sequence
+-- ----------------------------------------------------------------------------------------------------
+CREATE SEQUENCE systemgroup_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE system_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE subsystem_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE discipline_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE devicegroup_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE devicetype_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE name_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE audit_structure_audit_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE audit_name_audit_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+SELECT setval('systemgroup_id_seq', (select max(id) from systemgroup));
+SELECT setval('system_id_seq', (select max(id) from system));
+SELECT setval('subsystem_id_seq', (select max(id) from subsystem));
+SELECT setval('discipline_id_seq', (select max(id) from discipline));
+SELECT setval('devicegroup_id_seq', (select max(id) from devicegroup));
+SELECT setval('devicetype_id_seq', (select max(id) from devicetype));
+SELECT setval('name_id_seq', (select max(id) from name));
+SELECT setval('audit_structure_audit_id_seq', (select max(audit_id) from audit_structure));
+SELECT setval('audit_name_audit_id_seq', (select max(audit_id) from audit_name));
+
+ALTER SEQUENCE systemgroup_id_seq OWNED BY systemgroup.id;
+ALTER SEQUENCE system_id_seq OWNED BY system.id;
+ALTER SEQUENCE subsystem_id_seq OWNED BY subsystem.id;
+ALTER SEQUENCE discipline_id_seq OWNED BY discipline.id;
+ALTER SEQUENCE devicegroup_id_seq OWNED BY devicegroup.id;
+ALTER SEQUENCE devicetype_id_seq OWNED BY devicetype.id;
+ALTER SEQUENCE name_id_seq OWNED BY name.id;
+ALTER SEQUENCE audit_structure_audit_id_seq OWNED BY audit_structure.audit_id;
+ALTER SEQUENCE audit_name_audit_id_seq OWNED BY audit_name.audit_id;
+
+ALTER TABLE ONLY systemgroup ALTER COLUMN id SET DEFAULT nextval('systemgroup_id_seq'::regclass);
+ALTER TABLE ONLY system ALTER COLUMN id SET DEFAULT nextval('system_id_seq'::regclass);
+ALTER TABLE ONLY subsystem ALTER COLUMN id SET DEFAULT nextval('subsystem_id_seq'::regclass);
+ALTER TABLE ONLY discipline ALTER COLUMN id SET DEFAULT nextval('discipline_id_seq'::regclass);
+ALTER TABLE ONLY devicegroup ALTER COLUMN id SET DEFAULT nextval('devicegroup_id_seq'::regclass);
+ALTER TABLE ONLY devicetype ALTER COLUMN id SET DEFAULT nextval('devicetype_id_seq'::regclass);
+ALTER TABLE ONLY name ALTER COLUMN id SET DEFAULT nextval('name_id_seq'::regclass);
+ALTER TABLE ONLY audit_structure ALTER COLUMN audit_id SET DEFAULT nextval('audit_structure_audit_id_seq'::regclass);
+ALTER TABLE ONLY audit_name ALTER COLUMN audit_id SET DEFAULT nextval('audit_name_audit_id_seq'::regclass);
+
+-- ----------------------------------------------------------------------------------------------------
+-- primary key
+-- ----------------------------------------------------------------------------------------------------
+ALTER TABLE systemgroup ADD CONSTRAINT systemgroup_pk PRIMARY KEY (id);
+ALTER TABLE system ADD CONSTRAINT system_pk PRIMARY KEY (id);
+ALTER TABLE subsystem ADD CONSTRAINT subsystem_pk PRIMARY KEY (id);
+ALTER TABLE discipline ADD CONSTRAINT discipline_pk PRIMARY KEY (id);
+ALTER TABLE devicegroup ADD CONSTRAINT devicegroup_pk PRIMARY KEY (id);
+ALTER TABLE devicetype ADD CONSTRAINT devicetype_pk PRIMARY KEY (id);
+ALTER TABLE name ADD CONSTRAINT name_pk PRIMARY KEY (id);
+ALTER TABLE audit_structure ADD CONSTRAINT audit_structure_pk PRIMARY KEY (audit_id);
+ALTER TABLE audit_name ADD CONSTRAINT audit_name_pk PRIMARY KEY (audit_id);
+
+-- ----------------------------------------------------------------------------------------------------
+-- foreign key
+-- ----------------------------------------------------------------------------------------------------
+ALTER TABLE ONLY system ADD CONSTRAINT fk_system_systemgroup FOREIGN KEY (parent_id) REFERENCES systemgroup(id);
+ALTER TABLE ONLY subsystem ADD CONSTRAINT fk_subsystem_system FOREIGN KEY (parent_id) REFERENCES system(id);
+ALTER TABLE ONLY devicegroup ADD CONSTRAINT fk_devicegroup_discipline FOREIGN KEY (parent_id) REFERENCES discipline(id);
+ALTER TABLE ONLY devicetype ADD CONSTRAINT fk_devicetype_devicegroup FOREIGN KEY (parent_id) REFERENCES devicegroup(id);
+ALTER TABLE ONLY name ADD CONSTRAINT fk_name_systemgroup FOREIGN KEY (systemgroup_id) REFERENCES systemgroup(id);
+ALTER TABLE ONLY name ADD CONSTRAINT fk_name_system FOREIGN KEY (system_id) REFERENCES system(id);
+ALTER TABLE ONLY name ADD CONSTRAINT fk_name_subsystem FOREIGN KEY (subsystem_id) REFERENCES subsystem(id);
+ALTER TABLE ONLY name ADD CONSTRAINT fk_name_devicetype FOREIGN KEY (devicetype_id) REFERENCES devicetype(id);
+
+-- ----------------------------------------------------------------------------------------------------
+-- function
+-- ----------------------------------------------------------------------------------------------------
+-- same as V4
+--     get_mnemonic_path_system_structure(convention_name text)
+--     get_mnemonic_path_device_structure(convention_name text)
+--     get_instance_index(convention_name text)
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_system_structure(convention_name text)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    pos int;
+BEGIN
+    pos = strpos(convention_name, ':');
+    IF pos > 0  THEN
+        RETURN substr(convention_name, 1, pos-1);
+    END IF;
+    RETURN convention_name;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_device_structure(convention_name text)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    pos int;
+    mnemonic_path text;
+    nbr_delimiters int;
+BEGIN
+    pos = strpos(convention_name, ':');
+    IF pos > 0  THEN
+        mnemonic_path = substr(convention_name, pos+1);
+        nbr_delimiters = array_length(string_to_array(mnemonic_path, '-'), 1) - 1;
+        IF nbr_delimiters = 2 then
+            mnemonic_path = reverse(mnemonic_path);
+            mnemonic_path = substr(mnemonic_path, strpos(mnemonic_path, '-')+1);
+            RETURN reverse(mnemonic_path);
+        ELSIF nbr_delimiters = 1 then
+            return mnemonic_path;
+        ELSE
+            RETURN null;
+        END IF;
+    END IF;
+    RETURN null;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_instance_index(convention_name text)
+ RETURNS text
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    len int;
+    pos int;
+    mnemonic_path text;
+    nbr_delimiters int;
+BEGIN
+    pos = strpos(convention_name, ':');
+    IF pos > 0  THEN
+        mnemonic_path = substr(convention_name, pos+1);
+        nbr_delimiters = array_length(string_to_array(mnemonic_path, '-'), 1) - 1;
+        IF nbr_delimiters = 2 then
+            mnemonic_path = reverse(mnemonic_path);
+            len = length(mnemonic_path);
+            pos = strpos(mnemonic_path, '-');
+            mnemonic_path = reverse(mnemonic_path);
+            RETURN substr(mnemonic_path, len - pos + 2);
+        ELSE
+            RETURN null;
+        END IF;
+    END IF;
+    RETURN null;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_parent_uuid_system(system_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    parent_uuid text;
+BEGIN
+    select uuid into parent_uuid from systemgroup where id = (select parent_id from system where id = system_id);
+
+    if parent_uuid is not null then
+        return parent_uuid;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_parent_uuid_subsystem(subsystem_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    parent_uuid text;
+BEGIN
+    select uuid into parent_uuid from system where id = (select parent_id from subsystem where id = subsystem_id);
+
+    if parent_uuid is not null then
+        return parent_uuid;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_parent_uuid_devicegroup(devicegroup_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    parent_uuid text;
+BEGIN
+    select uuid into parent_uuid from discipline where id = (select parent_id from devicegroup where id = devicegroup_id);
+
+    if parent_uuid is not null then
+        return parent_uuid;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_parent_uuid_devicetype(devicetype_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    parent_uuid text;
+BEGIN
+    select uuid into parent_uuid from devicegroup where id = (select parent_id from devicetype where id = devicetype_id);
+
+    if parent_uuid is not null then
+        return parent_uuid;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_system(system_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    system_mnemonic text;
+BEGIN
+    select mnemonic into system_mnemonic from system where id = system_id;
+
+    if system_mnemonic is not null then
+        return system_mnemonic;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_subsystem(subsystem_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    subsystem_mnemonic text;
+    system_id bigint;
+    system_mnemonic text;
+BEGIN
+    select parent_id, mnemonic into system_id, subsystem_mnemonic from subsystem where id = subsystem_id;
+    select mnemonic into system_mnemonic from system where id = system_id;
+
+    if system_mnemonic is not null and subsystem_mnemonic is not null then
+        return concat(system_mnemonic, '-', subsystem_mnemonic);
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_devicegroup(devicegroup_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    discipline_id bigint;
+    discipline_mnemonic text;
+BEGIN
+    select parent_id into discipline_id from devicegroup where id = devicegroup_id;
+    select mnemonic into discipline_mnemonic from discipline where id = discipline_id;
+
+    if discipline_mnemonic is not null then
+        return discipline_mnemonic;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_devicetype(devicetype_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    devicetype_mnemonic text;
+    devicegroup_id bigint;
+    discipline_id bigint;
+    discipline_mnemonic text;
+BEGIN
+    select parent_id, mnemonic into devicegroup_id, devicetype_mnemonic from devicetype where id = devicetype_id;
+    select parent_id, mnemonic into discipline_id from devicegroup where id = devicegroup_id;
+    select mnemonic into discipline_mnemonic from discipline where id = discipline_id;
+
+    if discipline_mnemonic is not null and devicetype_mnemonic is not null then
+        return concat(discipline_mnemonic, '-', devicetype_mnemonic);
+    elsif devicetype_mnemonic is not null then
+        return devicetype_mnemonic;
+    else
+        return null;
+    end if;
+END;
+$$;
diff --git a/src/main/resources/db/migration/V6.2__Schema_data_migration_audit.sql b/src/main/resources/db/migration/V6.2__Schema_data_migration_audit.sql
new file mode 100644
index 0000000000000000000000000000000000000000..bdd76fca9c21f8ce78cf0d63485d4d0f38c85445
--- /dev/null
+++ b/src/main/resources/db/migration/V6.2__Schema_data_migration_audit.sql
@@ -0,0 +1,1672 @@
+-- ----------------------------------------------------------------------------------------------------
+-- About
+--     migration script
+--     postgresql 9.6.7
+-- Content
+--     structures
+--     names
+--     data structures level 1
+--         systemgroup    +    audit
+--         discipline     +    audit
+--     data structures level 2
+--         system         +    audit
+--         devicegroup    +    audit
+--     data structures level 3
+--         subsystem      +    audit
+--         devicetype     +    audit
+--     data names
+--         systemgroup_id    and    not devicetype_id    +    audit
+--         system_id         and    not devicetype_id    +    audit
+--         subsystem_id      and    not devicetype_id    +    audit
+--         systemgroup_id    and    devicetype_id        +    audit
+--         system_id         and    devicetype_id        +    audit
+--         subsystem_id      and    devicetype_id        +    audit
+--     index
+--     sequence
+--     primary key
+--     foreign key
+--     function
+-- Note
+--     about audit tables and data
+--         data comes from "wip" tables
+--     order of items is important
+--     notice prefix "wip_" meaning "work in progress" as tables are temporary
+-- ----------------------------------------------------------------------------------------------------
+--     data structures (parent_id)
+--     data names
+--         selection of proper id to refer to - systemgroup, system, subsystem, devicetype
+--                     exclude content (with latest) before latest
+--                     exclude content (with latest) after  latest (cancelled, rejected)
+--                     keep most recent content (without latest)   (to have most recent in line of uuid without latest)
+--             <-->
+--                     select * from structure s
+--                     where (
+--                                 not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true))
+--                             and not (exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+--                             and not (not exists (select s2.id from structure s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from structure s2 where s2."uuid" = s."uuid" and s2.latest=false))
+--                     )
+-- ----------------------------------------------------------------------------------------------------
+--     retrieve parent id for audit structure
+--         1 or 2 or 3
+--                     1.  get id from parent that is approved and was processed prior to child or within 10 seconds
+--                     2.  get id from parent that is approved and was requested prior to child or within 10 minutes
+--                     3.  get id from parent that was requested prior to child or within 10 minutes
+--             <-->
+--                     coalesce (
+--                     (select max(s3.id) from parent s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+--                     (select max(s3.id) from parent s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+--                     (select max(s3.id) from parent s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+--                     )
+-- ----------------------------------------------------------------------------------------------------
+--     non-audit tables contain valid
+--     audit tables contain all          <---
+-- ----------------------------------------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------------------------------------
+-- structures
+-- ----------------------------------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS systemgroup (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS system (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS subsystem (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+-- ----------------------------------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS discipline (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS devicegroup (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS devicetype (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint NOT NULL,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+-- ----------------------------------------------------------------------------------------------------
+-- name
+-- ----------------------------------------------------------------------------------------------------
+CREATE TABLE IF NOT EXISTS name (
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    systemgroup_id bigint,
+    system_id bigint,
+    subsystem_id bigint,
+    devicetype_id bigint,
+    instance_index text,
+    convention_name text,
+    convention_name_equivalence text,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+-- ----------------------------------------------------------------------------------------------------
+-- audit
+-- ----------------------------------------------------------------------------------------------------
+
+CREATE TABLE IF NOT EXISTS audit_structure (
+    audit_id bigint NOT NULL,
+    audit_version integer,
+    audit_table text NOT NULL,
+    audit_operation text,
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    parent_id bigint,
+    mnemonic text,
+    mnemonic_equivalence text,
+    ordering integer,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+CREATE TABLE IF NOT EXISTS audit_name (
+    audit_id bigint NOT NULL,
+    audit_version integer,
+    audit_table text NOT NULL,
+    audit_operation text,
+    id bigint NOT NULL,
+    version integer,
+    uuid text NOT NULL,
+    systemgroup_id bigint,
+    system_id bigint,
+    subsystem_id bigint,
+    devicetype_id bigint,
+    instance_index text,
+    convention_name text,
+    convention_name_equivalence text,
+    description text,
+    status text,
+    -- latest boolean NOT NULL,
+    deleted boolean NOT NULL,
+    requested timestamp without time zone,
+    requested_by text,
+    requested_comment text,
+    processed timestamp without time zone,
+    processed_by text,
+    processed_comment text
+);
+
+-- ----------------------------------------------------------------------------------------------------
+-- data structures level 1
+--     systemgroup    +    audit
+--     discipline     +    audit
+-- ----------------------------------------------------------------------------------------------------
+--     from wip_systemgroup
+--     from wip_discipline
+-- ----------------------------------------------------------------------------------------------------
+insert into systemgroup (
+    id,
+    version,
+    uuid,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid, s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_systemgroup s
+where (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'systemgroup', null,
+s.id, s.version, s.uuid, null, s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_systemgroup s
+-- where not (
+--             not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+--         and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+--         and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+-- )
+;
+
+-- ----------------------------------------------------------------------------------------------------
+insert into discipline (
+    id,
+    version,
+    uuid,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid, s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_discipline s
+where (
+            not (exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'discipline', null,
+s.id, s.version, s.uuid, null, s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_discipline s
+-- where not (
+--             not (exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true))
+--         and not (exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+--         and not (not exists (select s2.id from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_discipline s2 where s2."uuid" = s."uuid" and s2.latest=false))
+-- )
+;
+
+-- ----------------------------------------------------------------------------------------------------
+-- data structures level 2
+--     system         +    audit
+--     devicegroup    +    audit
+-- ----------------------------------------------------------------------------------------------------
+--     from wip_system
+--     from wip_devicegroup
+-- ----------------------------------------------------------------------------------------------------
+insert into system (
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid,
+(select sg.id from wip_systemgroup sg
+where sg.uuid = s.parent_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true) and sg.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true) and sg.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true) and sg.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=true) and sg.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = sg."uuid" and s2.latest=false))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_system s
+where (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'system', null,
+s.id, s.version, s.uuid,
+(coalesce (
+(select max(s3.id) from wip_systemgroup s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+(select max(s3.id) from wip_systemgroup s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+(select max(s3.id) from wip_systemgroup s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_system s
+-- where not (
+--             not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+--         and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+--         and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+-- )
+;
+
+-- ----------------------------------------------------------------------------------------------------
+insert into devicegroup (
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid,
+(select di.id from wip_discipline di
+where di.uuid = s.parent_uuid and (
+            not (exists (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true) and di.id < (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true) and di.id > (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true) and di.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=true) and di.id < (select max(s2.id) from wip_discipline s2 where s2."uuid" = di."uuid" and s2.latest=false))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_devicegroup s
+where (
+            not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'devicegroup', null,
+s.id, s.version, s.uuid,
+(coalesce (
+(select max(s3.id) from wip_discipline s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+(select max(s3.id) from wip_discipline s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+(select max(s3.id) from wip_discipline s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_devicegroup s
+-- where not (
+--             not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+--         and not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+--         and not (not exists (select s2.id from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicegroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+-- )
+;
+
+-- ----------------------------------------------------------------------------------------------------
+-- data structures level 3
+--     subsystem      +    audit
+--     devicetype     +    audit
+-- ----------------------------------------------------------------------------------------------------
+--     from wip_subsystem
+--     from wip_devicetype
+-- ----------------------------------------------------------------------------------------------------
+insert into subsystem (
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid,
+(select sys.id from wip_system sys
+where sys.uuid = s.parent_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true) and sys.id < (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true) and sys.id > (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true) and sys.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=true) and sys.id < (select max(s2.id) from wip_system s2 where s2."uuid" = sys."uuid" and s2.latest=false))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_subsystem s
+where (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'subsystem', null,
+s.id, s.version, s.uuid,
+(coalesce (
+(select max(s3.id) from wip_system s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+(select max(s3.id) from wip_system s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+(select max(s3.id) from wip_system s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_subsystem s
+-- where not (
+--             not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+--         and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+--         and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+-- )
+;
+
+-- ----------------------------------------------------------------------------------------------------
+insert into devicetype (
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select
+s.id, s."version", s.uuid,
+(select dg.id from wip_devicegroup dg
+where dg.uuid = s.parent_uuid and (
+            not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true) and dg.id < (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true) and dg.id > (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true) and dg.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=true) and dg.id < (select max(s2.id) from wip_devicegroup s2 where s2."uuid" = dg."uuid" and s2.latest=false))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_devicetype s
+where (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+);
+
+insert into audit_structure (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    parent_id,
+    mnemonic,
+    mnemonic_equivalence,
+    ordering,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select s.id, s."version", 'devicetype', null,
+s.id, s.version, s.uuid,
+(coalesce (
+(select max(s3.id) from wip_devicegroup s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.processed < (s.processed + interval '10 seconds')),
+(select max(s3.id) from wip_devicegroup s3 where s3."uuid" = s.parent_uuid and s3.status = 'APPROVED' and s3.requested < (s.processed + interval '10 minutes')),
+(select max(s3.id) from wip_devicegroup s3 where s3."uuid" = s.parent_uuid and s3.requested < (s.processed + interval '10 minutes'))
+)),
+s.mnemonic, s.mnemonic_equivalence, s.ordering, s.description, s.status, s.deleted,
+s.requested, s.requested_by, s.requested_comment, s.processed, s.processed_by, s.processed_comment from wip_devicetype s
+-- where not (
+--             not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+--         and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+--         and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+-- )
+;
+
+-- ----------------------------------------------------------------------------------------------------
+-- data names
+--     1) systemgroup_id    and    not devicetype_id    +    audit
+--     2) system_id         and    not devicetype_id    +    audit
+--     3) subsystem_id      and    not devicetype_id    +    audit
+--     4) systemgroup_id    and    devicetype_id        +    audit
+--     5) system_id         and    devicetype_id        +    audit
+--     6) subsystem_id      and    devicetype_id        +    audit
+-- ----------------------------------------------------------------------------------------------------
+--     from wip_systemgroup
+--     from wip_systemg
+--     from wip_subsystem
+--     from wip_systemgroup    +    wip_devicetype
+--     from wip_systemg        +    wip_devicetype
+--     from wip_subsystem      +    wip_devicetype
+-- ----------------------------------------------------------------------------------------------------
+-- 1)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+(select s.id from wip_systemgroup s
+where s.uuid = n.systemgroup_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is not null and n.system_uuid is null and n.subsystem_uuid is null and n.devicetype_uuid is null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+(select s.id from wip_systemgroup s
+where s.uuid = n.systemgroup_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+-- (n.latest = false) and
+n.systemgroup_uuid is not null and n.system_uuid is null and n.subsystem_uuid is null and n.devicetype_uuid is null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 2)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+null,
+(select s.id from wip_system s
+where s.uuid = n.system_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is null and n.system_uuid is not null and n.subsystem_uuid is null and n.devicetype_uuid is null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+null,
+(select s.id from wip_system s
+where s.uuid = n.system_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+-- (n.latest = false) and
+n.systemgroup_uuid is null and n.system_uuid is not null and n.subsystem_uuid is null and n.devicetype_uuid is null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 3)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+null,
+null,
+(select s.id from wip_subsystem s
+where s.uuid = n.subsystem_uuid and (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is null and n.system_uuid is null and n.subsystem_uuid is not null and n.devicetype_uuid is null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+null,
+null,
+(select s.id from wip_subsystem s
+where s.uuid = n.subsystem_uuid and (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+-- (n.latest = false) and
+n.systemgroup_uuid is null and n.system_uuid is null and n.subsystem_uuid is not null and n.devicetype_uuid is null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 4)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+(select s.id from wip_systemgroup s
+where s.uuid = n.systemgroup_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is not null and n.system_uuid is null and n.subsystem_uuid is null and n.devicetype_uuid is not null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+(select s.id from wip_systemgroup s
+where s.uuid = n.systemgroup_uuid and (
+            not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_systemgroup s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+null,
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+-- (n.latest = false) and
+n.systemgroup_uuid is not null and n.system_uuid is null and n.subsystem_uuid is null and n.devicetype_uuid is not null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 5)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+null,
+(select s.id from wip_system s
+where s.uuid = n.system_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is null and n.system_uuid is not null and n.subsystem_uuid is null and n.devicetype_uuid is not null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+null,
+(select s.id from wip_system s
+where s.uuid = n.system_uuid and (
+            not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_system s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+null,
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+-- (n.latest = false) and
+n.systemgroup_uuid is null and n.system_uuid is not null and n.subsystem_uuid is null and n.devicetype_uuid is not null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- 6)
+insert into name (
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", n.uuid,
+null,
+null,
+(select s.id from wip_subsystem s
+where s.uuid = n.subsystem_uuid and (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where not (n.latest = false)
+and n.systemgroup_uuid is null and n.system_uuid is null and n.subsystem_uuid is not null and n.devicetype_uuid is not null;
+
+insert into audit_name (
+    audit_id,
+    audit_version,
+    audit_table,
+    audit_operation,
+    id,
+    version,
+    uuid,
+    systemgroup_id,
+    system_id,
+    subsystem_id,
+    devicetype_id,
+    instance_index,
+    convention_name,
+    convention_name_equivalence,
+    description,
+    status,
+    -- latest,
+    deleted,
+    requested,
+    requested_by,
+    requested_comment,
+    processed,
+    processed_by,
+    processed_comment
+)
+select n.id, n."version", 'name', null,
+n.id, n."version", n.uuid,
+null,
+null,
+(select s.id from wip_subsystem s
+where s.uuid = n.subsystem_uuid and (
+            not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_subsystem s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+(select s.id from wip_devicetype s
+where s.uuid = n.devicetype_uuid and (
+            not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true))
+        and not (exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id > (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.status in ('CANCELLED', 'REJECTED'))
+        and not (not exists (select s2.id from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=true) and s.id < (select max(s2.id) from wip_devicetype s2 where s2."uuid" = s."uuid" and s2.latest=false))
+)),
+n.instance_index, n.convention_name, n.convention_name_equivalence, n.description, n.status, n.deleted,
+n.requested, n.requested_by, n.requested_comment, n.processed, n.processed_by, n.processed_comment from wip_name n
+where
+-- (n.latest = false) and
+n.systemgroup_uuid is null and n.system_uuid is null and n.subsystem_uuid is not null and n.devicetype_uuid is not null;
+
+-- ----------------------------------------------------------------------------------------------------
+-- index
+-- ----------------------------------------------------------------------------------------------------
+CREATE INDEX systemgroup_id_idx ON systemgroup (id);
+CREATE INDEX systemgroup_uuid_idx ON systemgroup (uuid);
+CREATE INDEX systemgroup_mnemonic_idx ON systemgroup (mnemonic);
+CREATE INDEX systemgroup_status_idx ON systemgroup (status);
+CREATE INDEX systemgroup_deleted_idx ON systemgroup (deleted);
+
+CREATE INDEX system_id_idx ON system (id);
+CREATE INDEX system_uuid_idx ON system (uuid);
+CREATE INDEX system_parent_id_idx ON system (parent_id);
+CREATE INDEX system_mnemonic_idx ON system (mnemonic);
+CREATE INDEX system_status_idx ON system (status);
+CREATE INDEX system_deleted_idx ON system (deleted);
+
+CREATE INDEX subsystem_id_idx ON subsystem (id);
+CREATE INDEX subsystem_uuid_idx ON subsystem (uuid);
+CREATE INDEX subsystem_parent_id_idx ON subsystem (parent_id);
+CREATE INDEX subsystem_mnemonic_idx ON subsystem (mnemonic);
+CREATE INDEX subsystem_status_idx ON subsystem (status);
+CREATE INDEX subsystem_deleted_idx ON subsystem (deleted);
+
+CREATE INDEX discipline_id_idx ON discipline (id);
+CREATE INDEX discipline_uuid_idx ON discipline (uuid);
+CREATE INDEX discipline_mnemonic_idx ON discipline (mnemonic);
+CREATE INDEX discipline_status_idx ON discipline (status);
+CREATE INDEX discipline_deleted_idx ON discipline (deleted);
+
+CREATE INDEX devicegroup_id_idx ON devicegroup (id);
+CREATE INDEX devicegroup_uuid_idx ON devicegroup (uuid);
+CREATE INDEX devicegroup_parent_id_idx ON devicegroup (parent_id);
+CREATE INDEX devicegroup_mnemonic_idx ON devicegroup (mnemonic);
+CREATE INDEX devicegroup_status_idx ON devicegroup (status);
+CREATE INDEX devicegroup_deleted_idx ON devicegroup (deleted);
+
+CREATE INDEX devicetype_id_idx ON devicetype (id);
+CREATE INDEX devicetype_uuid_idx ON devicetype (uuid);
+CREATE INDEX devicetype_parent_id_idx ON devicetype (parent_id);
+CREATE INDEX devicetype_mnemonic_idx ON devicetype (mnemonic);
+CREATE INDEX devicetype_status_idx ON devicetype (status);
+CREATE INDEX devicetype_deleted_idx ON devicetype (deleted);
+
+CREATE INDEX name_id_idx ON name (id);
+CREATE INDEX name_uuid_idx ON name (uuid);
+CREATE INDEX name_systemgroup_id_idx ON name (systemgroup_id);
+CREATE INDEX name_system_id_idx ON name (system_id);
+CREATE INDEX name_subsystem_id_idx ON name (subsystem_id);
+CREATE INDEX name_devicetype_id_idx ON name (devicetype_id);
+CREATE INDEX name_convention_name_idx ON name (convention_name);
+CREATE INDEX name_status_idx ON name (status);
+CREATE INDEX name_deleted_idx ON name (deleted);
+
+CREATE INDEX audit_structure_audit_id_idx ON audit_structure (audit_id);
+CREATE INDEX audit_structure_audit_table_idx ON audit_structure (audit_table);
+CREATE INDEX audit_structure_audit_operation_idx ON audit_structure (audit_operation);
+CREATE INDEX audit_structure_id_idx ON audit_structure (id);
+CREATE INDEX audit_structure_uuid_idx ON audit_structure (uuid);
+CREATE INDEX audit_structure_parent_id_idx ON audit_structure (parent_id);
+CREATE INDEX audit_structure_mnemonic_idx ON audit_structure (mnemonic);
+CREATE INDEX audit_structure_status_idx ON audit_structure (status);
+CREATE INDEX audit_structure_deleted_idx ON audit_structure (deleted);
+
+CREATE INDEX audit_name_audit_id_idx ON audit_name (audit_id);
+CREATE INDEX audit_name_audit_table_idx ON audit_name (audit_table);
+CREATE INDEX audit_name_audit_operation_idx ON audit_name (audit_operation);
+CREATE INDEX audit_name_id_idx ON audit_name (id);
+CREATE INDEX audit_name_uuid_idx ON audit_name (uuid);
+CREATE INDEX audit_name_systemgroup_id_idx ON audit_name (systemgroup_id);
+CREATE INDEX audit_name_system_id_idx on audit_name (system_id);
+CREATE INDEX audit_name_subsystem_id_idx ON audit_name (subsystem_id);
+CREATE INDEX audit_name_devicetype_id_idx ON audit_name (devicetype_id);
+CREATE INDEX audit_name_convention_name_idx ON audit_name (convention_name);
+CREATE INDEX audit_name_status_idx ON audit_name (status);
+CREATE INDEX audit_name_deleted_idx ON audit_name (deleted);
+
+-- ----------------------------------------------------------------------------------------------------
+-- sequence
+-- ----------------------------------------------------------------------------------------------------
+CREATE SEQUENCE systemgroup_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE system_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE subsystem_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE discipline_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE devicegroup_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE devicetype_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE name_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE audit_structure_audit_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+CREATE SEQUENCE audit_name_audit_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+SELECT setval('systemgroup_id_seq', (select max(id) from systemgroup));
+SELECT setval('system_id_seq', (select max(id) from system));
+SELECT setval('subsystem_id_seq', (select max(id) from subsystem));
+SELECT setval('discipline_id_seq', (select max(id) from discipline));
+SELECT setval('devicegroup_id_seq', (select max(id) from devicegroup));
+SELECT setval('devicetype_id_seq', (select max(id) from devicetype));
+SELECT setval('name_id_seq', (select max(id) from name));
+SELECT setval('audit_structure_audit_id_seq', (select max(audit_id) from audit_structure));
+SELECT setval('audit_name_audit_id_seq', (select max(audit_id) from audit_name));
+
+ALTER SEQUENCE systemgroup_id_seq OWNED BY systemgroup.id;
+ALTER SEQUENCE system_id_seq OWNED BY system.id;
+ALTER SEQUENCE subsystem_id_seq OWNED BY subsystem.id;
+ALTER SEQUENCE discipline_id_seq OWNED BY discipline.id;
+ALTER SEQUENCE devicegroup_id_seq OWNED BY devicegroup.id;
+ALTER SEQUENCE devicetype_id_seq OWNED BY devicetype.id;
+ALTER SEQUENCE name_id_seq OWNED BY name.id;
+ALTER SEQUENCE audit_structure_audit_id_seq OWNED BY audit_structure.audit_id;
+ALTER SEQUENCE audit_name_audit_id_seq OWNED BY audit_name.audit_id;
+
+ALTER TABLE ONLY systemgroup ALTER COLUMN id SET DEFAULT nextval('systemgroup_id_seq'::regclass);
+ALTER TABLE ONLY system ALTER COLUMN id SET DEFAULT nextval('system_id_seq'::regclass);
+ALTER TABLE ONLY subsystem ALTER COLUMN id SET DEFAULT nextval('subsystem_id_seq'::regclass);
+ALTER TABLE ONLY discipline ALTER COLUMN id SET DEFAULT nextval('discipline_id_seq'::regclass);
+ALTER TABLE ONLY devicegroup ALTER COLUMN id SET DEFAULT nextval('devicegroup_id_seq'::regclass);
+ALTER TABLE ONLY devicetype ALTER COLUMN id SET DEFAULT nextval('devicetype_id_seq'::regclass);
+ALTER TABLE ONLY name ALTER COLUMN id SET DEFAULT nextval('name_id_seq'::regclass);
+ALTER TABLE ONLY audit_structure ALTER COLUMN audit_id SET DEFAULT nextval('audit_structure_audit_id_seq'::regclass);
+ALTER TABLE ONLY audit_name ALTER COLUMN audit_id SET DEFAULT nextval('audit_name_audit_id_seq'::regclass);
+
+-- ----------------------------------------------------------------------------------------------------
+-- primary key
+-- ----------------------------------------------------------------------------------------------------
+ALTER TABLE systemgroup ADD CONSTRAINT systemgroup_pk PRIMARY KEY (id);
+ALTER TABLE system ADD CONSTRAINT system_pk PRIMARY KEY (id);
+ALTER TABLE subsystem ADD CONSTRAINT subsystem_pk PRIMARY KEY (id);
+ALTER TABLE discipline ADD CONSTRAINT discipline_pk PRIMARY KEY (id);
+ALTER TABLE devicegroup ADD CONSTRAINT devicegroup_pk PRIMARY KEY (id);
+ALTER TABLE devicetype ADD CONSTRAINT devicetype_pk PRIMARY KEY (id);
+ALTER TABLE name ADD CONSTRAINT name_pk PRIMARY KEY (id);
+ALTER TABLE audit_structure ADD CONSTRAINT audit_structure_pk PRIMARY KEY (audit_id);
+ALTER TABLE audit_name ADD CONSTRAINT audit_name_pk PRIMARY KEY (audit_id);
+
+-- ----------------------------------------------------------------------------------------------------
+-- foreign key
+-- ----------------------------------------------------------------------------------------------------
+ALTER TABLE ONLY system ADD CONSTRAINT fk_system_systemgroup FOREIGN KEY (parent_id) REFERENCES systemgroup(id);
+ALTER TABLE ONLY subsystem ADD CONSTRAINT fk_subsystem_system FOREIGN KEY (parent_id) REFERENCES system(id);
+ALTER TABLE ONLY devicegroup ADD CONSTRAINT fk_devicegroup_discipline FOREIGN KEY (parent_id) REFERENCES discipline(id);
+ALTER TABLE ONLY devicetype ADD CONSTRAINT fk_devicetype_devicegroup FOREIGN KEY (parent_id) REFERENCES devicegroup(id);
+ALTER TABLE ONLY name ADD CONSTRAINT fk_name_systemgroup FOREIGN KEY (systemgroup_id) REFERENCES systemgroup(id);
+ALTER TABLE ONLY name ADD CONSTRAINT fk_name_system FOREIGN KEY (system_id) REFERENCES system(id);
+ALTER TABLE ONLY name ADD CONSTRAINT fk_name_subsystem FOREIGN KEY (subsystem_id) REFERENCES subsystem(id);
+ALTER TABLE ONLY name ADD CONSTRAINT fk_name_devicetype FOREIGN KEY (devicetype_id) REFERENCES devicetype(id);
+
+-- ----------------------------------------------------------------------------------------------------
+-- function
+-- ----------------------------------------------------------------------------------------------------
+-- same as V4
+--     get_mnemonic_path_system_structure(convention_name text)
+--     get_mnemonic_path_device_structure(convention_name text)
+--     get_instance_index(convention_name text)
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_system_structure(convention_name text)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    pos int;
+BEGIN
+    pos = strpos(convention_name, ':');
+    IF pos > 0  THEN
+        RETURN substr(convention_name, 1, pos-1);
+    END IF;
+    RETURN convention_name;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_device_structure(convention_name text)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    pos int;
+    mnemonic_path text;
+    nbr_delimiters int;
+BEGIN
+    pos = strpos(convention_name, ':');
+    IF pos > 0  THEN
+        mnemonic_path = substr(convention_name, pos+1);
+        nbr_delimiters = array_length(string_to_array(mnemonic_path, '-'), 1) - 1;
+        IF nbr_delimiters = 2 then
+            mnemonic_path = reverse(mnemonic_path);
+            mnemonic_path = substr(mnemonic_path, strpos(mnemonic_path, '-')+1);
+            RETURN reverse(mnemonic_path);
+        ELSIF nbr_delimiters = 1 then
+            return mnemonic_path;
+        ELSE
+            RETURN null;
+        END IF;
+    END IF;
+    RETURN null;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_instance_index(convention_name text)
+ RETURNS text
+ LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    len int;
+    pos int;
+    mnemonic_path text;
+    nbr_delimiters int;
+BEGIN
+    pos = strpos(convention_name, ':');
+    IF pos > 0  THEN
+        mnemonic_path = substr(convention_name, pos+1);
+        nbr_delimiters = array_length(string_to_array(mnemonic_path, '-'), 1) - 1;
+        IF nbr_delimiters = 2 then
+            mnemonic_path = reverse(mnemonic_path);
+            len = length(mnemonic_path);
+            pos = strpos(mnemonic_path, '-');
+            mnemonic_path = reverse(mnemonic_path);
+            RETURN substr(mnemonic_path, len - pos + 2);
+        ELSE
+            RETURN null;
+        END IF;
+    END IF;
+    RETURN null;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_parent_uuid_system(system_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    parent_uuid text;
+BEGIN
+    select uuid into parent_uuid from systemgroup where id = (select parent_id from system where id = system_id);
+
+    if parent_uuid is not null then
+        return parent_uuid;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_parent_uuid_subsystem(subsystem_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    parent_uuid text;
+BEGIN
+    select uuid into parent_uuid from system where id = (select parent_id from subsystem where id = subsystem_id);
+
+    if parent_uuid is not null then
+        return parent_uuid;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_parent_uuid_devicegroup(devicegroup_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    parent_uuid text;
+BEGIN
+    select uuid into parent_uuid from discipline where id = (select parent_id from devicegroup where id = devicegroup_id);
+
+    if parent_uuid is not null then
+        return parent_uuid;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_parent_uuid_devicetype(devicetype_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    parent_uuid text;
+BEGIN
+    select uuid into parent_uuid from devicegroup where id = (select parent_id from devicetype where id = devicetype_id);
+
+    if parent_uuid is not null then
+        return parent_uuid;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_system(system_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    system_mnemonic text;
+BEGIN
+    select mnemonic into system_mnemonic from system where id = system_id;
+
+    if system_mnemonic is not null then
+        return system_mnemonic;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_subsystem(subsystem_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    subsystem_mnemonic text;
+    system_id bigint;
+    system_mnemonic text;
+BEGIN
+    select parent_id, mnemonic into system_id, subsystem_mnemonic from subsystem where id = subsystem_id;
+    select mnemonic into system_mnemonic from system where id = system_id;
+
+    if system_mnemonic is not null and subsystem_mnemonic is not null then
+        return concat(system_mnemonic, '-', subsystem_mnemonic);
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_devicegroup(devicegroup_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    discipline_id bigint;
+    discipline_mnemonic text;
+BEGIN
+    select parent_id into discipline_id from devicegroup where id = devicegroup_id;
+    select mnemonic into discipline_mnemonic from discipline where id = discipline_id;
+
+    if discipline_mnemonic is not null then
+        return discipline_mnemonic;
+    else
+        return null;
+    end if;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION get_mnemonic_path_devicetype(devicetype_id bigint)
+    RETURNS text
+    LANGUAGE plpgsql
+AS
+$$
+DECLARE
+    devicetype_mnemonic text;
+    devicegroup_id bigint;
+    discipline_id bigint;
+    discipline_mnemonic text;
+BEGIN
+    select parent_id, mnemonic into devicegroup_id, devicetype_mnemonic from devicetype where id = devicetype_id;
+    select parent_id, mnemonic into discipline_id from devicegroup where id = devicegroup_id;
+    select mnemonic into discipline_mnemonic from discipline where id = discipline_id;
+
+    if discipline_mnemonic is not null and devicetype_mnemonic is not null then
+        return concat(discipline_mnemonic, '-', devicetype_mnemonic);
+    elsif devicetype_mnemonic is not null then
+        return devicetype_mnemonic;
+    else
+        return null;
+    end if;
+END;
+$$;
diff --git a/src/main/resources/static/images/naming_backend_lifecycle.png b/src/main/resources/static/images/naming_backend_lifecycle.png
index b2f012d3590b7c15d31ced5ae9bb3d965eca2109..6bb3f904885546c2da2e29e5ee40806cbd2ab8c4 100644
Binary files a/src/main/resources/static/images/naming_backend_lifecycle.png and b/src/main/resources/static/images/naming_backend_lifecycle.png differ
diff --git a/src/test/java/org/openepics/names/docker/ITUtilNames.java b/src/test/java/org/openepics/names/docker/ITUtilNames.java
index fa427dc576e9e8f4b571fd10124371a439e319d2..a35297f51e61ce02283a365c0cfc7a24158aa44c 100644
--- a/src/test/java/org/openepics/names/docker/ITUtilNames.java
+++ b/src/test/java/org/openepics/names/docker/ITUtilNames.java
@@ -19,7 +19,6 @@
 package org.openepics.names.docker;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
@@ -27,14 +26,9 @@ import static org.junit.jupiter.api.Assertions.fail;
 import java.io.File;
 import java.io.IOException;
 import java.net.HttpURLConnection;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.UUID;
-import java.util.Map.Entry;
 
 import org.openepics.names.docker.ITUtil.AuthorizationChoice;
 import org.openepics.names.docker.ITUtil.EndpointChoice;
-import org.openepics.names.rest.beans.Status;
 import org.openepics.names.rest.beans.element.NameElement;
 import org.openepics.names.rest.beans.element.NameElementCommandConfirm;
 import org.openepics.names.rest.beans.element.NameElementCommandCreate;
@@ -216,9 +210,6 @@ public class ITUtilNames {
             if (HttpURLConnection.HTTP_OK == expectedResponseCode) {
                 assertTrue(responsePageNameElements.getListSize() > 0);
                 assertNotNull(responsePageNameElements.getList().get(0));
-
-                // expected value for latest
-                assertLatest(responsePageNameElements.getList().get(0));
             } else if (HttpURLConnection.HTTP_NOT_FOUND == expectedResponseCode){
                 assertEquals(0, responsePageNameElements.getListSize());
             }
@@ -277,9 +268,6 @@ public class ITUtilNames {
                 if (expectedLessThanOrEqual >= 0) {
                     assertTrue(responsePageNameElements.getListSize() <= expectedLessThanOrEqual);
                 }
-
-                // expected value for latest for items in list
-                assertLatest(responsePageNameElements);
             }
 
             return responsePageNameElements;
@@ -291,40 +279,6 @@ public class ITUtilNames {
         return null;
     }
 
-    /**
-     * Assert that given response name element is latest and not have status {@link Status#PENDING}.
-     *
-     * @param actual response name element
-     */
-    public static void assertLatest(NameElement actual) {
-        assertNotNull(actual);
-        assertTrue(actual.isLatest());
-    }
-
-    /**
-     * Assert that response page with list of name elements has maximum one entry that is latest
-     * for any given uuid, which may not have status {@link Status#PENDING}.
-     *
-     * @param actual response page with list of name elements
-     */
-    public static void assertLatest(ResponsePageNameElements actual) {
-        // latest
-        //     status pending not with latest
-        //     maximum one item for any given uuid in list may be latest
-
-        assertNotNull(actual);
-        Map<UUID, Long> mapUuidCountLatest = new TreeMap<>();
-        for (NameElement nameElement : actual.getList()) {
-            if (nameElement.isLatest()) {
-                ITUtil.addOne(nameElement.getUuid(), mapUuidCountLatest);
-                assertNotEquals(Status.PENDING, nameElement.getStatus());
-            }
-        }
-        for (Entry<UUID, Long> entry : mapUuidCountLatest.entrySet()) {
-            assertTrue(entry.getValue() <= 1);
-        }
-    }
-
     /**
      * @see ITUtilNames#assertHistory(String, int, int)
      */
@@ -359,10 +313,6 @@ public class ITUtilNames {
                 if (expectedEqual >= 0) {
                     assertTrue(responsePageNameElements.getListSize() <= expectedEqual);
                 }
-
-                // expected value for latest for items in list
-
-                ITUtilNames.assertLatest(responsePageNameElements);
             }
 
             return responsePageNameElements;
@@ -572,7 +522,6 @@ public class ITUtilNames {
 
                 for (NameElement createdNameElement : nameElements) {
                     assertNotNull(createdNameElement.getUuid());
-                    assertEquals(Boolean.TRUE, createdNameElement.isLatest());
                     assertEquals(Boolean.FALSE, createdNameElement.isDeleted());
                     assertNotNull(createdNameElement.getWhen());
                 }
@@ -639,7 +588,6 @@ public class ITUtilNames {
 
                 for (NameElement updatedNameElement : nameElements) {
                     assertNotNull(updatedNameElement.getUuid());
-                    assertEquals(Boolean.TRUE, updatedNameElement.isLatest());
                     assertEquals(Boolean.FALSE, updatedNameElement.isDeleted());
                     assertNotNull(updatedNameElement.getWhen());
                 }
diff --git a/src/test/java/org/openepics/names/docker/ITUtilStructures.java b/src/test/java/org/openepics/names/docker/ITUtilStructures.java
index 5c3fc955c8739f2e99a3d9f2258bd532760660da..6a7a28cdb0d8a2e31326d8138d43b94a8c746a9f 100644
--- a/src/test/java/org/openepics/names/docker/ITUtilStructures.java
+++ b/src/test/java/org/openepics/names/docker/ITUtilStructures.java
@@ -19,7 +19,6 @@
 package org.openepics.names.docker;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
@@ -27,10 +26,6 @@ import static org.junit.jupiter.api.Assertions.fail;
 import java.io.File;
 import java.io.IOException;
 import java.net.HttpURLConnection;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-import java.util.UUID;
 
 import org.openepics.names.docker.ITUtil.AuthorizationChoice;
 import org.openepics.names.docker.ITUtil.EndpointChoice;
@@ -217,9 +212,6 @@ public class ITUtilStructures {
             if (HttpURLConnection.HTTP_OK == expectedResponseCode) {
                 assertTrue(responsePageStructureElements.getListSize() > 0);
                 assertNotNull(responsePageStructureElements.getList().get(0));
-
-                // expected value for latest
-                assertLatest(responsePageStructureElements.getList().get(0));
             } else if (HttpURLConnection.HTTP_NOT_FOUND == expectedResponseCode){
                 assertEquals(0, responsePageStructureElements.getListSize());
             }
@@ -280,9 +272,6 @@ public class ITUtilStructures {
                 if (expectedLessThanOrEqual >= 0) {
                     assertTrue(responsePageStructureElements.getListSize() <= expectedLessThanOrEqual);
                 }
-
-                // expected value for latest for items in list
-                assertLatest(responsePageStructureElements);
             }
 
             return responsePageStructureElements;
@@ -294,45 +283,6 @@ public class ITUtilStructures {
         return null;
     }
 
-    /**
-     * Assert that given response structure element is either latest with status {@link Status#APPROVED}
-     * or latest with status {@link Status#PENDING}.
-     *
-     * @param actual response structure element
-     */
-    public static void assertLatest(StructureElement actual) {
-        assertNotNull(actual);
-        assertTrue(actual.isLatest() && Status.APPROVED.equals(actual.getStatus())
-                || !actual.isLatest() && (
-                        Status.PENDING.equals(actual.getStatus())
-                        || Status.CANCELLED.equals(actual.getStatus())
-                        || Status.REJECTED.equals(actual.getStatus())));
-    }
-
-    /**
-     * Assert that response page with list of structure elements has maximum one entry that is latest
-     * for any given uuid, which may not have status {@link Status#PENDING}.
-     *
-     * @param actual response page with list of structure elements
-     */
-    public static void assertLatest(ResponsePageStructureElements actual) {
-        // latest
-        //     status pending not with latest
-        //     maximum one item for any given uuid in list may be latest
-
-        assertNotNull(actual);
-        Map<UUID, Long> mapUuidCountLatest = new TreeMap<>();
-        for (StructureElement structureElement : actual.getList()) {
-            if (structureElement.isLatest()) {
-                ITUtil.addOne(structureElement.getUuid(), mapUuidCountLatest);
-                assertNotEquals(Status.PENDING, structureElement.getStatus());
-            }
-        }
-        for (Entry<UUID, Long> entry : mapUuidCountLatest.entrySet()) {
-            assertTrue(entry.getValue() <= 1);
-        }
-    }
-
     /**
      * @see ITUtilStructures#assertHistory(String, int, int)
      */
@@ -367,9 +317,6 @@ public class ITUtilStructures {
                 if (expectedEqual >= 0) {
                     assertTrue(responsePageStructureElements.getListSize() <= expectedEqual);
                 }
-
-                // expected value for latest for items in list
-                ITUtilStructures.assertLatest(responsePageStructureElements);
             }
 
             return responsePageStructureElements;
@@ -576,7 +523,6 @@ public class ITUtilStructures {
                 for (StructureElement createdStructureElement : structureElements) {
                     assertNotNull(createdStructureElement.getUuid());
                     assertEquals(Status.APPROVED, createdStructureElement.getStatus());
-                    assertEquals(Boolean.TRUE,    createdStructureElement.isLatest());
                     assertEquals(Boolean.FALSE,   createdStructureElement.isDeleted());
                     assertNotNull(createdStructureElement.getWhen());
                 }
@@ -644,7 +590,6 @@ public class ITUtilStructures {
                 for (StructureElement updatedStructureElement : structureElements) {
                     assertNotNull(updatedStructureElement.getUuid());
                     assertEquals(Status.APPROVED, updatedStructureElement.getStatus());
-                    assertEquals(Boolean.TRUE,    updatedStructureElement.isLatest());
                     assertEquals(Boolean.FALSE,   updatedStructureElement.isDeleted());
                     assertNotNull(updatedStructureElement.getWhen());
                 }
diff --git a/src/test/java/org/openepics/names/docker/NamesIT.java b/src/test/java/org/openepics/names/docker/NamesIT.java
index 17f40bbf03edafc1395ea6378484d2d39c9e87a9..049ad1f2ab9c30260bf2145305601e1fdcb0905a 100644
--- a/src/test/java/org/openepics/names/docker/NamesIT.java
+++ b/src/test/java/org/openepics/names/docker/NamesIT.java
@@ -201,7 +201,7 @@ class NamesIT {
         ITUtilNames.assertCreate(nameElementCommandCreate, ITUtil.HTTP_UNPROCESSABLE_ENTITY);
 
         // convention name exists
-        // already exists since create subsystem was approved
+        // already exists since subsystem was created
         nameElementCommandCreate.setParentSystemStructure(subsystem010PRL);
         ITUtilNames.assertValidate(nameElementCommandCreate, NameCommand.CREATE, Boolean.FALSE);
         ITUtilNames.assertCreate(nameElementCommandCreate, HttpURLConnection.HTTP_CONFLICT);
@@ -231,7 +231,7 @@ class NamesIT {
         //     description
 
         // convention name exists
-        // already exists since create system was approved
+        // already exists since system was created
         nameElementCommandCreate.setParentSystemStructure(systemRFQ);
         ITUtilNames.assertValidate(nameElementCommandCreate, NameCommand.CREATE, Boolean.FALSE);
         ITUtilNames.assertCreate(nameElementCommandCreate, HttpURLConnection.HTTP_CONFLICT);
@@ -261,7 +261,7 @@ class NamesIT {
         //     description
 
         // convention name exists
-        // already exists since create system group was approved
+        // already exists since system group was created
         nameElementCommandCreate.setParentSystemStructure(systemGroupAcc);
         ITUtilNames.assertValidate(nameElementCommandCreate, NameCommand.CREATE, Boolean.FALSE);
 
@@ -293,7 +293,7 @@ class NamesIT {
         //     description
 
         // convention name exists
-        // already exists since create system was approved
+        // already exists since system was created
         nameElementCommandCreate.setParentSystemStructure(systemRFQ);
         ITUtilNames.assertValidate(nameElementCommandCreate, NameCommand.CREATE, Boolean.FALSE);
         ITUtilNames.assertCreate(nameElementCommandCreate, HttpURLConnection.HTTP_CONFLICT);
@@ -427,7 +427,7 @@ class NamesIT {
         ITUtilNames.assertUpdate(nameElementCommandUpdate, ITUtil.HTTP_UNPROCESSABLE_ENTITY);
 
         // convention name exists
-        // already exists since create subsystem was approved
+        // already exists since subsystem was created
         nameElementCommandUpdate.setIndex(null);
         ITUtilNames.assertValidate(nameElementCommandUpdate, NameCommand.UPDATE, Boolean.FALSE);
         ITUtilNames.assertUpdate(nameElementCommandUpdate, HttpURLConnection.HTTP_CONFLICT);
diff --git a/src/test/java/org/openepics/names/docker/complex/StructuresLevel3IT.java b/src/test/java/org/openepics/names/docker/complex/StructuresLevel3IT.java
index 316eed9424b2806ac630f8d2e6d145fed5c1def6..a5c53d4713fefefe41ecf8a5fac51c003d7f1de7 100644
--- a/src/test/java/org/openepics/names/docker/complex/StructuresLevel3IT.java
+++ b/src/test/java/org/openepics/names/docker/complex/StructuresLevel3IT.java
@@ -211,17 +211,17 @@ class StructuresLevel3IT {
         //     all create
 
         StructureElementCommandCreate[] structureElementCommandsCreate = null;
-        StructureElement[] approvedStructureElements = null;
+        StructureElement[] structureElements = null;
 
         structureElementCommandsCreate = new StructureElementCommandCreate[] {
                 new StructureElementCommandCreate(Type.SUBSYSTEM, systemRFQ, "010PRL", null, "01 Phase Reference Line"),
                 new StructureElementCommandCreate(Type.SUBSYSTEM, systemRFQ, "010",    null, "RFQ-010"),
                 new StructureElementCommandCreate(Type.SUBSYSTEM, systemRFQ, "N1U1",   null, "Power switch board 01. Electrical power cabinets")
         };
-        approvedStructureElements = ITUtilStructures.assertCreate(structureElementCommandsCreate);
-        subsystem010PRL = approvedStructureElements[0].getUuid();
-        subsystem010    = approvedStructureElements[1].getUuid();
-        subsystemN1U1   = approvedStructureElements[2].getUuid();
+        structureElements = ITUtilStructures.assertCreate(structureElementCommandsCreate);
+        subsystem010PRL = structureElements[0].getUuid();
+        subsystem010    = structureElements[1].getUuid();
+        subsystemN1U1   = structureElements[2].getUuid();
 
         assertNotNull(subsystem010PRL);
         assertNotNull(subsystem010);
@@ -234,7 +234,7 @@ class StructuresLevel3IT {
         //     all create
 
         StructureElementCommandCreate[] structureElementCommandsCreate = null;
-        StructureElement[] approvedStructureElements = null;
+        StructureElement[] structureElements = null;
 
         structureElementCommandsCreate = new StructureElementCommandCreate[] {
                 new StructureElementCommandCreate(Type.DEVICETYPE, deviceGroupCryo, "FS",  null, "Flow Switch"),
@@ -270,39 +270,39 @@ class StructuresLevel3IT {
                 new StructureElementCommandCreate(Type.DEVICETYPE, deviceGroupBMD,  "RFA", null, "RF Antenna"),
                 new StructureElementCommandCreate(Type.DEVICETYPE, deviceGroupBMD,  "TT",  null, "Temperature Transmitter")
         };
-        approvedStructureElements = ITUtilStructures.assertCreate(structureElementCommandsCreate);
-        deviceType_Cryo_FS  = approvedStructureElements[0].getUuid();
-        deviceType_Cryo_IOC = approvedStructureElements[1].getUuid();
-        deviceType_Cryo_RFA = approvedStructureElements[2].getUuid();
-        deviceType_Cryo_TT  = approvedStructureElements[3].getUuid();
-        deviceType_EMR_FS   = approvedStructureElements[4].getUuid();
-        deviceType_EMR_IOC  = approvedStructureElements[5].getUuid();
-        deviceType_EMR_RFA  = approvedStructureElements[6].getUuid();
-        deviceType_EMR_TT   = approvedStructureElements[7].getUuid();
-        deviceType_HVAC_FS  = approvedStructureElements[8].getUuid();
-        deviceType_HVAC_IOC = approvedStructureElements[9].getUuid();
-        deviceType_HVAC_RFA = approvedStructureElements[10].getUuid();
-        deviceType_HVAC_TT  = approvedStructureElements[11].getUuid();
-        deviceType_Proc_FS  = approvedStructureElements[12].getUuid();
-        deviceType_Proc_IOC = approvedStructureElements[13].getUuid();
-        deviceType_Proc_RFA = approvedStructureElements[14].getUuid();
-        deviceType_Proc_TT  = approvedStructureElements[15].getUuid();
-        deviceType_SC_FS    = approvedStructureElements[16].getUuid();
-        deviceType_SC_IOC   = approvedStructureElements[17].getUuid();
-        deviceType_SC_RFA   = approvedStructureElements[18].getUuid();
-        deviceType_SC_TT    = approvedStructureElements[19].getUuid();
-        deviceType_Vac_FS   = approvedStructureElements[20].getUuid();
-        deviceType_Vac_IOC  = approvedStructureElements[21].getUuid();
-        deviceType_Vac_RFA  = approvedStructureElements[22].getUuid();
-        deviceType_Vac_TT   = approvedStructureElements[23].getUuid();
-        deviceType_WtrC_FS  = approvedStructureElements[24].getUuid();
-        deviceType_WtrC_IOC = approvedStructureElements[25].getUuid();
-        deviceType_WtrC_RFA = approvedStructureElements[26].getUuid();
-        deviceType_WtrC_TT  = approvedStructureElements[27].getUuid();
-        deviceType_BMD_FS   = approvedStructureElements[28].getUuid();
-        deviceType_BMD_IOC  = approvedStructureElements[29].getUuid();
-        deviceType_BMD_RFA  = approvedStructureElements[30].getUuid();
-        deviceType_BMD_TT   = approvedStructureElements[31].getUuid();
+        structureElements = ITUtilStructures.assertCreate(structureElementCommandsCreate);
+        deviceType_Cryo_FS  = structureElements[0].getUuid();
+        deviceType_Cryo_IOC = structureElements[1].getUuid();
+        deviceType_Cryo_RFA = structureElements[2].getUuid();
+        deviceType_Cryo_TT  = structureElements[3].getUuid();
+        deviceType_EMR_FS   = structureElements[4].getUuid();
+        deviceType_EMR_IOC  = structureElements[5].getUuid();
+        deviceType_EMR_RFA  = structureElements[6].getUuid();
+        deviceType_EMR_TT   = structureElements[7].getUuid();
+        deviceType_HVAC_FS  = structureElements[8].getUuid();
+        deviceType_HVAC_IOC = structureElements[9].getUuid();
+        deviceType_HVAC_RFA = structureElements[10].getUuid();
+        deviceType_HVAC_TT  = structureElements[11].getUuid();
+        deviceType_Proc_FS  = structureElements[12].getUuid();
+        deviceType_Proc_IOC = structureElements[13].getUuid();
+        deviceType_Proc_RFA = structureElements[14].getUuid();
+        deviceType_Proc_TT  = structureElements[15].getUuid();
+        deviceType_SC_FS    = structureElements[16].getUuid();
+        deviceType_SC_IOC   = structureElements[17].getUuid();
+        deviceType_SC_RFA   = structureElements[18].getUuid();
+        deviceType_SC_TT    = structureElements[19].getUuid();
+        deviceType_Vac_FS   = structureElements[20].getUuid();
+        deviceType_Vac_IOC  = structureElements[21].getUuid();
+        deviceType_Vac_RFA  = structureElements[22].getUuid();
+        deviceType_Vac_TT   = structureElements[23].getUuid();
+        deviceType_WtrC_FS  = structureElements[24].getUuid();
+        deviceType_WtrC_IOC = structureElements[25].getUuid();
+        deviceType_WtrC_RFA = structureElements[26].getUuid();
+        deviceType_WtrC_TT  = structureElements[27].getUuid();
+        deviceType_BMD_FS   = structureElements[28].getUuid();
+        deviceType_BMD_IOC  = structureElements[29].getUuid();
+        deviceType_BMD_RFA  = structureElements[30].getUuid();
+        deviceType_BMD_TT   = structureElements[31].getUuid();
 
         assertNotNull(deviceType_Cryo_FS);
         assertNotNull(deviceType_Cryo_IOC);
diff --git a/src/test/java/org/openepics/names/repository/model/AuditNameTest.java b/src/test/java/org/openepics/names/repository/model/AuditNameTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1e9df2ea593e775e451bde44f945f5abb1cf2dc
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/AuditNameTest.java
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2023 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.repository.model;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for AuditName class.
+ *
+ * @author Lars Johansson
+ *
+ * @see Name
+ */
+class AuditNameTest {
+
+    @Test
+    void equals() {
+        AuditName aun1 = null, aun2 = null;
+        Name n1 = null, n2 = null;
+        Date date = new Date();
+
+        n1 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun1 = new AuditName("auditOperation", n1);
+        aun2 = new AuditName("auditOperation", n2);
+
+        assertEquals(aun1, aun2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        AuditName aun1 = null, aun2 = null;
+        Name n1 = null, n2 = null;
+
+        n1 = new Name();
+        n2 = new Name();
+        aun1 = new AuditName("auditOperation", n1);
+        aun2 = new AuditName("auditOperation", n2);
+
+        assertEquals(aun1, aun2);
+    }
+
+    @Test
+    void notEquals() {
+        AuditName aun1 = null, aun2 = null;
+        Name n1 = null, n2 = null;
+        Date date = new Date();
+
+        n1 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun1 = new AuditName("auditOperation", n1);
+        assertNotEquals(aun1, aun2);
+
+        n1 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun1 = new AuditName("auditOperation", n1);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 2L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, 1L, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, 1L, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, 1L,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                "010", "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acd", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACD", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", "description 2",
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.REJECTED, false,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true,
+                date, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                null, "test who", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who 2", null);
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
+        aun2 = new AuditName("auditOperation", n2);
+        assertNotEquals(aun1, aun2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        AuditName aun1 = null;
+        Name n1 = null;
+
+        n1 = new Name();
+        aun1 = new AuditName("auditOperation", n1);
+
+        assertNotEquals(n1, aun1);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        AuditName aun1 = null, aun2 = null;
+        Name n1 = null, n2 = null;
+        Date date = new Date();
+
+        n1 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun1 = new AuditName("auditOperation", n1);
+        aun2 = new AuditName("auditOperation", n2);
+
+        assertNotNull(aun1);
+        assertNotNull(aun2);
+        assertEquals(aun1, aun2);
+        assertEquals(aun1.hashCode(), aun2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        AuditName aun1 = null, aun2 = null;
+        Name n1 = null, n2 = null;
+        Date date = new Date();
+
+        n1 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        n2 = new Name(
+                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun1 = new AuditName("auditOperation", n1);
+        aun2 = new AuditName("auditOperation", n2);
+
+        assertNotNull(aun1);
+        assertNotNull(aun2);
+        assertNotEquals(aun1, aun2);
+        assertNotEquals(aun1.hashCode(), aun2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        AuditName aun1 = null;
+        Name n1 = null;
+        Date date = new Date();
+
+        n1 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun1 = new AuditName("auditOperation", n1);
+
+        String str = aun1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+    @Test
+    void getNonAuditName() {
+        AuditName aun1 = null;
+        Name n1 = null, nan1 = null;
+        Date date = new Date();
+
+        n1 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        aun1 = new AuditName("auditOperation", n1);
+        nan1 = aun1.getNonAuditName();
+
+        assertEquals(n1, nan1);
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/repository/model/AuditStructureTest.java b/src/test/java/org/openepics/names/repository/model/AuditStructureTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..96140da999cfef9a6bb2bc8ac890d12753320348
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/AuditStructureTest.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2023 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.repository.model;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for AuditStructure class.
+ *
+ * @author Lars Johansson
+ *
+ * @see System
+ */
+class AuditStructureTest {
+
+    @Test
+    void equals() {
+        AuditStructure aus1 = null, aus2 = null;
+        System s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus1 = new AuditStructure("auditOperation", s1);
+        aus2 = new AuditStructure("auditOperation", s2);
+
+        assertEquals(aus1, aus2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        AuditStructure aus1 = null, aus2 = null;
+        System s1 = null, s2 = null;
+
+        s1 = new System();
+        s2 = new System();
+        aus1 = new AuditStructure("auditOperation", s1);
+        aus2 = new AuditStructure("auditOperation", s2);
+
+        assertEquals(aus1, aus2);
+    }
+
+    @Test
+    void notEquals() {
+        AuditStructure aus1 = null, aus2 = null;
+        System s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus1 = new AuditStructure("auditOperation", s1);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 2L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA2", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA2", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 42, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description 2",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.REJECTED, false,
+                date, "test who", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true,
+                date, "test who", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                null, "test who", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who 2", "comment");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
+        aus2 = new AuditStructure("auditOperation", s2);
+        assertNotEquals(aus1, aus2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        AuditStructure aus1 = null, aus2 = null;
+        SystemGroup sg = null;
+        System sys = null;
+        Subsystem sub = null;
+        Discipline di = null;
+        DeviceGroup dg = null;
+        DeviceType dt = null;
+
+        sg = new SystemGroup();
+        sys = new System();
+        sub = new Subsystem();
+        di = new Discipline();
+        dg = new DeviceGroup();
+        dt = new DeviceType();
+
+        aus1 = new AuditStructure("auditOperation", sg);
+        aus2 = new AuditStructure("auditOperation", sys);
+        assertNotEquals(aus1, aus2);
+
+        aus2 = new AuditStructure("auditOperation", sub);
+        assertNotEquals(aus1, aus2);
+
+        aus2 = new AuditStructure("auditOperation", di);
+        assertNotEquals(aus1, aus2);
+
+        aus2 = new AuditStructure("auditOperation", dg);
+        assertNotEquals(aus1, aus2);
+
+        aus2 = new AuditStructure("auditOperation", dt);
+        assertNotEquals(aus1, aus2);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        AuditStructure aus1 = null, aus2 = null;
+        System s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus1 = new AuditStructure("auditOperation", s1);
+        aus2 = new AuditStructure("auditOperation", s2);
+
+        assertNotNull(aus1);
+        assertNotNull(aus2);
+        assertEquals(aus1, aus2);
+        assertEquals(aus1.hashCode(), aus2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        AuditStructure aus1 = null, aus2 = null;
+        System s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        s2 = new System(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus1 = new AuditStructure("auditOperation", s1);
+        aus2 = new AuditStructure("auditOperation", s2);
+
+        assertNotNull(aus1);
+        assertNotNull(aus2);
+        assertNotEquals(aus1, aus2);
+        assertNotEquals(aus1.hashCode(), aus2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        AuditStructure aus1 = null;
+        System s1 = null;
+        Date date = new Date();
+
+        s1 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        aus1 = new AuditStructure("auditOperation", s1);
+
+        String str = aus1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/repository/model/DeviceGroupTest.java b/src/test/java/org/openepics/names/repository/model/DeviceGroupTest.java
index 6e54d0aac81227455719777105c14de975bf1db9..e94fee2492683dcfa225dc1f1139ffa200ae810c 100644
--- a/src/test/java/org/openepics/names/repository/model/DeviceGroupTest.java
+++ b/src/test/java/org/openepics/names/repository/model/DeviceGroupTest.java
@@ -45,26 +45,29 @@ class DeviceGroupTest {
         Date date = new Date();
 
         s1 = new DeviceGroup(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new DeviceGroup(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
-
         assertEquals(s1, s2);
+
+        AuditStructure aus1 = new AuditStructure("auditOperation", s1);
+        assertEquals(new DeviceGroup(aus1), s2);
     }
 
     @Test
     void equalsNoArgs() {
         DeviceGroup s1 = null, s2 = null;
 
+        assertEquals(s1, s2);
+
         s1 = new DeviceGroup();
         s2 = new DeviceGroup();
-
         assertEquals(s1, s2);
     }
 
@@ -74,16 +77,87 @@ class DeviceGroupTest {
         Date date = new Date();
 
         s1 = new DeviceGroup(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
         s2 = new DeviceGroup(
-                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 2L,
+                "AA1", null, null, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA2", null, null, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", null, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", null, 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
 
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", null, null, "description 2",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", null, null, "description",
+                Status.REJECTED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", null, null, "description",
+                Status.APPROVED, true,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", null, null, "description",
+                Status.APPROVED, false,
+                null, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", null, null, "description",
+                Status.APPROVED, false,
+                date, "test who 2", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", null, null, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
         assertNotEquals(s1, s2);
     }
 
@@ -104,14 +178,14 @@ class DeviceGroupTest {
         Date date = new Date();
 
         s1 = new DeviceGroup(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new DeviceGroup(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -126,14 +200,14 @@ class DeviceGroupTest {
         Date date = new Date();
 
         s1 = new DeviceGroup(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new DeviceGroup(
-                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -148,9 +222,9 @@ class DeviceGroupTest {
         Date date = new Date();
 
         s1 = new DeviceGroup(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toString();
@@ -167,9 +241,9 @@ class DeviceGroupTest {
         Date date = new Date();
 
         s1 = new DeviceGroup(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", null, null, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/repository/model/DeviceTypeTest.java b/src/test/java/org/openepics/names/repository/model/DeviceTypeTest.java
index e6733428caa2854743803e565f2cb0653455fc29..f95c6e17f928565f543699d1be4592e0be1ab998 100644
--- a/src/test/java/org/openepics/names/repository/model/DeviceTypeTest.java
+++ b/src/test/java/org/openepics/names/repository/model/DeviceTypeTest.java
@@ -45,26 +45,29 @@ class DeviceTypeTest {
         Date date = new Date();
 
         s1 = new DeviceType(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new DeviceType(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
-
         assertEquals(s1, s2);
+
+        AuditStructure aus1 = new AuditStructure("auditOperation", s1);
+        assertEquals(new DeviceType(aus1), s2);
     }
 
     @Test
     void equalsNoArgs() {
         DeviceType s1 = null, s2 = null;
 
+        assertEquals(s1, s2);
+
         s1 = new DeviceType();
         s2 = new DeviceType();
-
         assertEquals(s1, s2);
     }
 
@@ -74,16 +77,87 @@ class DeviceTypeTest {
         Date date = new Date();
 
         s1 = new DeviceType(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
         s2 = new DeviceType(
-                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 2L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA2", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA2", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 42, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
 
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description 2",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.REJECTED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                null, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                 Status.APPROVED, false,
+                date, "test who 2", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new DeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
         assertNotEquals(s1, s2);
     }
 
@@ -104,14 +178,14 @@ class DeviceTypeTest {
         Date date = new Date();
 
         s1 = new DeviceType(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new DeviceType(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -126,14 +200,14 @@ class DeviceTypeTest {
         Date date = new Date();
 
         s1 = new DeviceType(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new DeviceType(
-                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -148,9 +222,9 @@ class DeviceTypeTest {
         Date date = new Date();
 
         s1 = new DeviceType(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toString();
@@ -167,9 +241,9 @@ class DeviceTypeTest {
         Date date = new Date();
 
         s1 = new DeviceType(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/repository/model/DisciplineTest.java b/src/test/java/org/openepics/names/repository/model/DisciplineTest.java
index 4f74ed815a5a0d816a87457e705f8221ec395adc..6009d29edcb44a5c65fa4614ff96bbef55196a1a 100644
--- a/src/test/java/org/openepics/names/repository/model/DisciplineTest.java
+++ b/src/test/java/org/openepics/names/repository/model/DisciplineTest.java
@@ -47,24 +47,27 @@ class DisciplineTest {
         s1 = new Discipline(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new Discipline(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
-
         assertEquals(s1, s2);
+
+        AuditStructure aus1 = new AuditStructure("auditOperation", s1);
+        assertEquals(new Discipline(aus1), s2);
     }
 
     @Test
     void equalsNoArgs() {
         Discipline s1 = null, s2 = null;
 
+        assertEquals(s1, s2);
+
         s1 = new Discipline();
         s2 = new Discipline();
-
         assertEquals(s1, s2);
     }
 
@@ -76,14 +79,78 @@ class DisciplineTest {
         s1 = new Discipline(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
         s2 = new Discipline(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
 
+        s2 = new Discipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA2", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Discipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA2", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Discipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 42, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Discipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description 2",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Discipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.REJECTED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Discipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Discipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                null, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Discipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who 2", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Discipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
         assertNotEquals(s1, s2);
     }
 
@@ -106,12 +173,12 @@ class DisciplineTest {
         s1 = new Discipline(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new Discipline(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -128,12 +195,12 @@ class DisciplineTest {
         s1 = new Discipline(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new Discipline(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -150,7 +217,7 @@ class DisciplineTest {
         s1 = new Discipline(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toString();
@@ -169,7 +236,7 @@ class DisciplineTest {
         s1 = new Discipline(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/repository/model/NameTest.java b/src/test/java/org/openepics/names/repository/model/NameTest.java
index 43f34e2aac5e5e7c34bfedec87257ee766c1cd78..86cfbb96963ce3031a18414b018d7beac40058aa 100644
--- a/src/test/java/org/openepics/names/repository/model/NameTest.java
+++ b/src/test/java/org/openepics/names/repository/model/NameTest.java
@@ -45,14 +45,14 @@ class NameTest {
         Date date = new Date();
 
         n1 = new Name(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
         n2 = new Name(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         assertEquals(n1, n2);
@@ -74,16 +74,108 @@ class NameTest {
         Date date = new Date();
 
         n1 = new Name(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 2L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, 1L, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, 1L, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
         n2 = new Name(
-                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, 1L,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
+        assertNotEquals(n1, n2);
 
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                "010", "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acd", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACD", null,
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", "description",
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.REJECTED, false,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true,
+                date, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                null, "test who", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who 2", null);
+        assertNotEquals(n1, n2);
+
+        n2 = new Name(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
         assertNotEquals(n1, n2);
     }
 
@@ -104,14 +196,14 @@ class NameTest {
         Date date = new Date();
 
         n1 = new Name(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
         n2 = new Name(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         assertNotNull(n1);
@@ -126,14 +218,14 @@ class NameTest {
         Date date = new Date();
 
         n1 = new Name(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
         n2 = new Name(
-                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         assertNotNull(n1);
@@ -148,9 +240,9 @@ class NameTest {
         Date date = new Date();
 
         n1 = new Name(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         String str = n1.toString();
@@ -167,9 +259,9 @@ class NameTest {
         Date date = new Date();
 
         n1 = new Name(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), 1L, null, null, null,
                 null, "Acc", "ACC", null,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         String str = n1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/repository/model/StructureTest.java b/src/test/java/org/openepics/names/repository/model/StructureTest.java
index 68a321317df025350c5f2b022d4f0cbd8663dea6..35d511ec39049a61cbc89e73d4da2cdb89d58abd 100644
--- a/src/test/java/org/openepics/names/repository/model/StructureTest.java
+++ b/src/test/java/org/openepics/names/repository/model/StructureTest.java
@@ -47,12 +47,12 @@ class StructureTest {
         s1 = new Structure(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new Structure(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertEquals(s1, s2);
@@ -76,14 +76,78 @@ class StructureTest {
         s1 = new Structure(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
         s2 = new Structure(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Structure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA2", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Structure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA2", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Structure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 42, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Structure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description 2",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Structure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.REJECTED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Structure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Structure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                null, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Structure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who 2", "comment");
+        assertNotEquals(s1, s2);
 
+        s2 = new Structure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
         assertNotEquals(s1, s2);
     }
 
@@ -106,12 +170,12 @@ class StructureTest {
         s1 = new Structure(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new Structure(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -128,12 +192,12 @@ class StructureTest {
         s1 = new Structure(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new Structure(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -150,7 +214,7 @@ class StructureTest {
         s1 = new Structure(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toString();
@@ -169,7 +233,7 @@ class StructureTest {
         s1 = new Structure(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/repository/model/SubsystemTest.java b/src/test/java/org/openepics/names/repository/model/SubsystemTest.java
index 1b0b32824cabda470090fa1443fa5687096cb73b..98c5509a5343918aa4ced5bb73d84b880075a991 100644
--- a/src/test/java/org/openepics/names/repository/model/SubsystemTest.java
+++ b/src/test/java/org/openepics/names/repository/model/SubsystemTest.java
@@ -45,26 +45,29 @@ class SubsystemTest {
         Date date = new Date();
 
         s1 = new Subsystem(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new Subsystem(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
-
         assertEquals(s1, s2);
+
+        AuditStructure aus1 = new AuditStructure("auditOperation", s1);
+        assertEquals(new Subsystem(aus1), s2);
     }
 
     @Test
     void equalsNoArgs() {
         Subsystem s1 = null, s2 = null;
 
+        assertEquals(s1, s2);
+
         s1 = new Subsystem();
         s2 = new Subsystem();
-
         assertEquals(s1, s2);
     }
 
@@ -74,16 +77,87 @@ class SubsystemTest {
         Date date = new Date();
 
         s1 = new Subsystem(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
         s2 = new Subsystem(
-                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 2L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA2", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA2", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 42, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
 
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description 2",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.REJECTED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                null, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who 2", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new Subsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
         assertNotEquals(s1, s2);
     }
 
@@ -104,14 +178,14 @@ class SubsystemTest {
         Date date = new Date();
 
         s1 = new Subsystem(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new Subsystem(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -126,14 +200,14 @@ class SubsystemTest {
         Date date = new Date();
 
         s1 = new Subsystem(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new Subsystem(
-                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -148,9 +222,9 @@ class SubsystemTest {
         Date date = new Date();
 
         s1 = new Subsystem(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toString();
@@ -167,9 +241,9 @@ class SubsystemTest {
         Date date = new Date();
 
         s1 = new Subsystem(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/repository/model/SystemGroupTest.java b/src/test/java/org/openepics/names/repository/model/SystemGroupTest.java
index 5b321bcc8f8bb6bd29e2783b3d964fe774ec273a..3e74b73a7161f2ee5ac21b09a7d4db838f15a97e 100644
--- a/src/test/java/org/openepics/names/repository/model/SystemGroupTest.java
+++ b/src/test/java/org/openepics/names/repository/model/SystemGroupTest.java
@@ -47,24 +47,27 @@ class SystemGroupTest {
         s1 = new SystemGroup(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new SystemGroup(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
-
         assertEquals(s1, s2);
+
+        AuditStructure aus1 = new AuditStructure("auditOperation", s1);
+        assertEquals(new SystemGroup(aus1), s2);
     }
 
     @Test
     void equalsNoArgs() {
         SystemGroup s1 = null, s2 = null;
 
+        assertEquals(s1, s2);
+
         s1 = new SystemGroup();
         s2 = new SystemGroup();
-
         assertEquals(s1, s2);
     }
 
@@ -76,14 +79,78 @@ class SystemGroupTest {
         s1 = new SystemGroup(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
         s2 = new SystemGroup(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
 
+        s2 = new SystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA2", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new SystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA2", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new SystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 42, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new SystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description 2",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new SystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.REJECTED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new SystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new SystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                null, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new SystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who 2", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new SystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
         assertNotEquals(s1, s2);
     }
 
@@ -106,12 +173,12 @@ class SystemGroupTest {
         s1 = new SystemGroup(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new SystemGroup(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -128,12 +195,12 @@ class SystemGroupTest {
         s1 = new SystemGroup(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new SystemGroup(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -150,7 +217,7 @@ class SystemGroupTest {
         s1 = new SystemGroup(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toString();
@@ -169,7 +236,7 @@ class SystemGroupTest {
         s1 = new SystemGroup(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/repository/model/SystemTest.java b/src/test/java/org/openepics/names/repository/model/SystemTest.java
index d7145b9eaea424767d1e3b61fdcb775d0d770b5e..9acb42c5ec6bf60dcd08287fb1246495e4e29415 100644
--- a/src/test/java/org/openepics/names/repository/model/SystemTest.java
+++ b/src/test/java/org/openepics/names/repository/model/SystemTest.java
@@ -45,26 +45,29 @@ class SystemTest {
         Date date = new Date();
 
         s1 = new System(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new System(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
-
         assertEquals(s1, s2);
+
+        AuditStructure aus1 = new AuditStructure("auditOperation", s1);
+        assertEquals(new System(aus1), s2);
     }
 
     @Test
     void equalsNoArgs() {
         System s1 = null, s2 = null;
 
+        assertEquals(s1, s2);
+
         s1 = new System();
         s2 = new System();
-
         assertEquals(s1, s2);
     }
 
@@ -74,16 +77,87 @@ class SystemTest {
         Date date = new Date();
 
         s1 = new System(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
         s2 = new System(
-                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 2L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA2", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA2", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 42, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
 
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description 2",
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.REJECTED, false,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true,
+                date, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                null, "test who", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who 2", "comment");
+        assertNotEquals(s1, s2);
+
+        s2 = new System(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
         assertNotEquals(s1, s2);
     }
 
@@ -104,14 +178,14 @@ class SystemTest {
         Date date = new Date();
 
         s1 = new System(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new System(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -126,14 +200,14 @@ class SystemTest {
         Date date = new Date();
 
         s1 = new System(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         s2 = new System(
-                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(s1);
@@ -148,9 +222,9 @@ class SystemTest {
         Date date = new Date();
 
         s1 = new System(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toString();
@@ -167,9 +241,9 @@ class SystemTest {
         Date date = new Date();
 
         s1 = new System(
-                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), 1L,
                 "AA1", "AA1", 41, "description",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = s1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/repository/model/wip/DeviceGroupTest.java b/src/test/java/org/openepics/names/repository/model/wip/DeviceGroupTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..05e0677dd603d50435f34ea4ff025fd31930da23
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/wip/DeviceGroupTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023 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.repository.model.wip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for DeviceGroup class.
+ *
+ * @author Lars Johansson
+ *
+ * @see WipDeviceGroup
+ */
+class DeviceGroupTest {
+
+    @Test
+    void equals() {
+        WipDeviceGroup s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        WipDeviceGroup s1 = null, s2 = null;
+
+        s1 = new WipDeviceGroup();
+        s2 = new WipDeviceGroup();
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void notEquals() {
+        WipDeviceGroup s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDeviceGroup(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        WipDeviceGroup s1 = null;
+        WipDeviceType s2 = null;
+
+        s1 = new WipDeviceGroup();
+        s2 = new WipDeviceType();
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        WipDeviceGroup s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertEquals(s1, s2);
+        assertEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        WipDeviceGroup s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDeviceGroup(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertNotEquals(s1, s2);
+        assertNotEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        WipDeviceGroup s1 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+    @Test
+    void toStringSimple() {
+        WipDeviceGroup s1 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", null, null, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toStringSimple();
+
+        assertNotNull(str);
+        assertTrue (str.contains("uuid"));
+        assertFalse(str.contains("description"));
+        assertFalse(str.contains("comment"));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/repository/model/wip/DeviceTypeTest.java b/src/test/java/org/openepics/names/repository/model/wip/DeviceTypeTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f7eee8193e24cdac4d8950f63a7a550e61ec917
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/wip/DeviceTypeTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023 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.repository.model.wip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for DeviceType class.
+ *
+ * @author Lars Johansson
+ *
+ * @see WipDeviceType
+ */
+class DeviceTypeTest {
+
+    @Test
+    void equals() {
+        WipDeviceType s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        WipDeviceType s1 = null, s2 = null;
+
+        s1 = new WipDeviceType();
+        s2 = new WipDeviceType();
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void notEquals() {
+        WipDeviceType s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDeviceType(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        WipDeviceType s1 = null;
+        WipSystemGroup s2 = null;
+
+        s1 = new WipDeviceType();
+        s2 = new WipSystemGroup();
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        WipDeviceType s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertEquals(s1, s2);
+        assertEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        WipDeviceType s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDeviceType(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertNotEquals(s1, s2);
+        assertNotEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        WipDeviceType s1 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+    @Test
+    void toStringSimple() {
+        WipDeviceType s1 = null;
+        Date date = new Date();
+
+        s1 = new WipDeviceType(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toStringSimple();
+
+        assertNotNull(str);
+        assertTrue (str.contains("uuid"));
+        assertFalse(str.contains("description"));
+        assertFalse(str.contains("comment"));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/repository/model/wip/DisciplineTest.java b/src/test/java/org/openepics/names/repository/model/wip/DisciplineTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..a938e6c56c3619a4ee2bd455f8375771cd1e31d2
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/wip/DisciplineTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023 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.repository.model.wip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for Discipline class.
+ *
+ * @author Lars Johansson
+ *
+ * @see WipDiscipline
+ */
+class DisciplineTest {
+
+    @Test
+    void equals() {
+        WipDiscipline s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDiscipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDiscipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        WipDiscipline s1 = null, s2 = null;
+
+        s1 = new WipDiscipline();
+        s2 = new WipDiscipline();
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void notEquals() {
+        WipDiscipline s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDiscipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDiscipline(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        WipDiscipline s1 = null;
+        WipDeviceGroup s2 = null;
+
+        s1 = new WipDiscipline();
+        s2 = new WipDeviceGroup();
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        WipDiscipline s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDiscipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDiscipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertEquals(s1, s2);
+        assertEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        WipDiscipline s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipDiscipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipDiscipline(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertNotEquals(s1, s2);
+        assertNotEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        WipDiscipline s1 = null;
+        Date date = new Date();
+
+        s1 = new WipDiscipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+    @Test
+    void toStringSimple() {
+        WipDiscipline s1 = null;
+        Date date = new Date();
+
+        s1 = new WipDiscipline(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toStringSimple();
+
+        assertNotNull(str);
+        assertTrue (str.contains("uuid"));
+        assertFalse(str.contains("description"));
+        assertFalse(str.contains("comment"));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/repository/model/wip/NameTest.java b/src/test/java/org/openepics/names/repository/model/wip/NameTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..40c9ef39746a0b0926aa8edcfa2249808ea69de8
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/wip/NameTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023 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.repository.model.wip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for Name class.
+ *
+ * @author Lars Johansson
+ *
+ * @see WipName
+ */
+class NameTest {
+
+    @Test
+    void equals() {
+        WipName n1 = null, n2 = null;
+        Date date = new Date();
+
+        n1 = new WipName(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+        n2 = new WipName(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+
+        assertEquals(n1, n2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        WipName n1 = null, n2 = null;
+
+        n1 = new WipName();
+        n2 = new WipName();
+
+        assertEquals(n1, n2);
+    }
+
+    @Test
+    void notEquals() {
+        WipName n1 = null, n2 = null;
+        Date date = new Date();
+
+        n1 = new WipName(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+        n2 = new WipName(
+                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+
+        assertNotEquals(n1, n2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        WipName n1 = null;
+        WipNameStructure n2 = null;
+
+        n1 = new WipName();
+        n2 = new WipNameStructure();
+
+        assertNotEquals(n1, n2);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        WipName n1 = null, n2 = null;
+        Date date = new Date();
+
+        n1 = new WipName(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+        n2 = new WipName(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+
+        assertNotNull(n1);
+        assertNotNull(n2);
+        assertEquals(n1, n2);
+        assertEquals(n1.hashCode(), n2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        WipName n1 = null, n2 = null;
+        Date date = new Date();
+
+        n1 = new WipName(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+        n2 = new WipName(
+                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+
+        assertNotNull(n1);
+        assertNotNull(n2);
+        assertNotEquals(n1, n2);
+        assertNotEquals(n1.hashCode(), n2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        WipName n1 = null;
+        Date date = new Date();
+
+        n1 = new WipName(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+
+        String str = n1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+    @Test
+    void toStringSimple() {
+        WipName n1 = null;
+        Date date = new Date();
+
+        n1 = new WipName(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null, null,
+                null, "Acc", "ACC", null,
+                Status.APPROVED, true, false,
+                date, "test who", null);
+
+        String str = n1.toStringSimple();
+
+        assertNotNull(str);
+        assertTrue (str.contains("uuid"));
+        assertFalse(str.contains("description"));
+        assertFalse(str.contains("comment"));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/repository/model/wip/StructureTest.java b/src/test/java/org/openepics/names/repository/model/wip/StructureTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..d6fcf90ec9ce4beeb28809dd4935c1d8907d760a
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/wip/StructureTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023 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.repository.model.wip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for Structure class.
+ *
+ * @author Lars Johansson
+ *
+ * @see WipStructure
+ */
+class StructureTest {
+
+    @Test
+    void equals() {
+        WipStructure s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipStructure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipStructure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        WipStructure s1 = null, s2 = null;
+
+        s1 = new WipStructure();
+        s2 = new WipStructure();
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void notEquals() {
+        WipStructure s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipStructure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipStructure(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        WipStructure s1 = null;
+        WipNameStructure s2 = null;
+
+        s1 = new WipStructure();
+        s2 = new WipNameStructure();
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        WipStructure s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipStructure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipStructure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertEquals(s1, s2);
+        assertEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        WipStructure s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipStructure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipStructure(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertNotEquals(s1, s2);
+        assertNotEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        WipStructure s1 = null;
+        Date date = new Date();
+
+        s1 = new WipStructure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+    @Test
+    void toStringSimple() {
+        WipStructure s1 = null;
+        Date date = new Date();
+
+        s1 = new WipStructure(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toStringSimple();
+
+        assertNotNull(str);
+        assertTrue (str.contains("uuid"));
+        assertFalse(str.contains("description"));
+        assertFalse(str.contains("comment"));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/repository/model/wip/SubsystemTest.java b/src/test/java/org/openepics/names/repository/model/wip/SubsystemTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..585e6bf6ae1cb54bebe9ebbbb0249d7fe44c6cc5
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/wip/SubsystemTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023 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.repository.model.wip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for Subsystem class.
+ *
+ * @author Lars Johansson
+ *
+ * @see WipSubsystem
+ */
+class SubsystemTest {
+
+    @Test
+    void equals() {
+        WipSubsystem s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSubsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSubsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        WipSubsystem s1 = null, s2 = null;
+
+        s1 = new WipSubsystem();
+        s2 = new WipSubsystem();
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void notEquals() {
+        WipSubsystem s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSubsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSubsystem(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        WipSubsystem s1 = null;
+        WipDiscipline s2 = null;
+
+        s1 = new WipSubsystem();
+        s2 = new WipDiscipline();
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        WipSubsystem s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSubsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSubsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertEquals(s1, s2);
+        assertEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        WipSubsystem s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSubsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSubsystem(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertNotEquals(s1, s2);
+        assertNotEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        WipSubsystem s1 = null;
+        Date date = new Date();
+
+        s1 = new WipSubsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+    @Test
+    void toStringSimple() {
+        WipSubsystem s1 = null;
+        Date date = new Date();
+
+        s1 = new WipSubsystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toStringSimple();
+
+        assertNotNull(str);
+        assertTrue (str.contains("uuid"));
+        assertFalse(str.contains("description"));
+        assertFalse(str.contains("comment"));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/repository/model/wip/SystemGroupTest.java b/src/test/java/org/openepics/names/repository/model/wip/SystemGroupTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bae2400c1348e42bd7e93b3bd0f58c94054a48da
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/wip/SystemGroupTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023 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.repository.model.wip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for SystemGroup class.
+ *
+ * @author Lars Johansson
+ *
+ * @see WipSystemGroup
+ */
+class SystemGroupTest {
+
+    @Test
+    void equals() {
+        WipSystemGroup s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        WipSystemGroup s1 = null, s2 = null;
+
+        s1 = new WipSystemGroup();
+        s2 = new WipSystemGroup();
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void notEquals() {
+        WipSystemGroup s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSystemGroup(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        WipSystemGroup s1 = null;
+        WipSystem s2 = null;
+
+        s1 = new WipSystemGroup();
+        s2 = new WipSystem();
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        WipSystemGroup s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertEquals(s1, s2);
+        assertEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        WipSystemGroup s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSystemGroup(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertNotEquals(s1, s2);
+        assertNotEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        WipSystemGroup s1 = null;
+        Date date = new Date();
+
+        s1 = new WipSystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+    @Test
+    void toStringSimple() {
+        WipSystemGroup s1 = null;
+        Date date = new Date();
+
+        s1 = new WipSystemGroup(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toStringSimple();
+
+        assertNotNull(str);
+        assertTrue (str.contains("uuid"));
+        assertFalse(str.contains("description"));
+        assertFalse(str.contains("comment"));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/repository/model/wip/SystemTest.java b/src/test/java/org/openepics/names/repository/model/wip/SystemTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e8996611409e5112624e6f331c39ca8427e007d4
--- /dev/null
+++ b/src/test/java/org/openepics/names/repository/model/wip/SystemTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023 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.repository.model.wip;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.openepics.names.rest.beans.Status;
+
+/**
+ * Unit tests for System class.
+ *
+ * @author Lars Johansson
+ *
+ * @see WipSystem
+ */
+class SystemTest {
+
+    @Test
+    void equals() {
+        WipSystem s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void equalsNoArgs() {
+        WipSystem s1 = null, s2 = null;
+
+        s1 = new WipSystem();
+        s2 = new WipSystem();
+
+        assertEquals(s1, s2);
+    }
+
+    @Test
+    void notEquals() {
+        WipSystem s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSystem(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void notEqualsNoArgs() {
+        WipSystem s1 = null;
+        WipSubsystem s2 = null;
+
+        s1 = new WipSystem();
+        s2 = new WipSubsystem();
+
+        assertNotEquals(s1, s2);
+    }
+
+    @Test
+    void hashCodeEquals() {
+        WipSystem s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertEquals(s1, s2);
+        assertEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void hashCodeNotEquals() {
+        WipSystem s1 = null, s2 = null;
+        Date date = new Date();
+
+        s1 = new WipSystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+        s2 = new WipSystem(
+                UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        assertNotNull(s1);
+        assertNotNull(s2);
+        assertNotEquals(s1, s2);
+        assertNotEquals(s1.hashCode(), s2.hashCode());
+    }
+
+    @Test
+    void toString_() {
+        WipSystem s1 = null;
+        Date date = new Date();
+
+        s1 = new WipSystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toString();
+
+        assertNotNull(str);
+        assertTrue(str.contains("uuid"));
+        assertTrue(str.contains("description"));
+        assertTrue(str.contains("comment"));
+    }
+
+    @Test
+    void toStringSimple() {
+        WipSystem s1 = null;
+        Date date = new Date();
+
+        s1 = new WipSystem(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", "AA1", 41, "description",
+                Status.APPROVED, true, false,
+                date, "test who", "comment");
+
+        String str = s1.toStringSimple();
+
+        assertNotNull(str);
+        assertTrue (str.contains("uuid"));
+        assertFalse(str.contains("description"));
+        assertFalse(str.contains("comment"));
+    }
+
+}
diff --git a/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandConfirmTest.java b/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandConfirmTest.java
index 79dec121fb952cede44bce791b03c706b2614db5..021c874e833d7a9ba68ab775a3c606bfb9ec19d4 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandConfirmTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandConfirmTest.java
@@ -87,9 +87,14 @@ class NameElementCommandConfirmTest {
 
         ne1 = new NameElementCommandConfirm(
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"));
+        assertNotEquals(ne1, ne2);
+
         ne2 = new NameElementCommandConfirm(
                 UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"));
+        assertNotEquals(ne1, ne2);
 
+        ne2 = new NameElementCommandConfirm(
+                null);
         assertNotEquals(ne1, ne2);
     }
 
diff --git a/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandCreateTest.java b/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandCreateTest.java
index 600e52b5c8d19657d88a274e94eb21aa9c60b8e9..c892c322043b28d8d00d457884021377362a77d3 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandCreateTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandCreateTest.java
@@ -90,10 +90,26 @@ class NameElementCommandCreateTest {
         ne1 = new NameElementCommandCreate(
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), null,
                 null, "System structure only");
+        assertNotEquals(ne1, ne2);
+
         ne2 = new NameElementCommandCreate(
                 UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), null,
                 null, "System structure only");
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElementCommandCreate(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"),
+                null, "System structure only");
+        assertNotEquals(ne1, ne2);
 
+        ne2 = new NameElementCommandCreate(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), null,
+                "010", "System structure only");
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElementCommandCreate(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), null,
+                null, "System structure only 2");
         assertNotEquals(ne1, ne2);
     }
 
diff --git a/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandTest.java b/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandTest.java
index 649bb0fd2a18033dd5edb2b9a9699bfe6d5ec32c..05fbe7e8bede8945be1300701c95b6cef8dcc2a5 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandTest.java
@@ -90,10 +90,31 @@ class NameElementCommandTest {
         ne1 = new NameElementCommand(
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only");
+        assertNotEquals(ne1, ne2);
+
         ne2 = new NameElementCommand(
                 UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only");
+        assertNotEquals(ne1, ne2);
 
+        ne2 = new NameElementCommand(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), null,
+                null, "System structure only");
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElementCommand(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"),
+                null, "System structure only");
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElementCommand(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                "010", "System structure only");
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElementCommand(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only 2");
         assertNotEquals(ne1, ne2);
     }
 
diff --git a/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandUpdateTest.java b/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandUpdateTest.java
index 998853213456827a56eb02ec7c82823765e862f8..995fb892878e51750a65caf80dc8e652741c0534 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandUpdateTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/NameElementCommandUpdateTest.java
@@ -46,11 +46,11 @@ class NameElementCommandUpdateTest {
         NameElementCommandUpdate ne1 = null, ne2 = null;
 
         ne1 = new NameElementCommandUpdate(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null,
-                "System structure only");
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only");
         ne2 = new NameElementCommandUpdate(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null,
-                "System structure only");
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only");
 
         assertEquals(ne1, ne2);
     }
@@ -88,12 +88,33 @@ class NameElementCommandUpdateTest {
         NameElementCommandUpdate ne1 = null, ne2 = null;
 
         ne1 = new NameElementCommandUpdate(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null,
-                "System structure only");
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only");
+        assertNotEquals(ne1, ne2);
+
         ne2 = new NameElementCommandUpdate(
-                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null,
-                "System structure only");
+                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only");
+        assertNotEquals(ne1, ne2);
 
+        ne2 = new NameElementCommandUpdate(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), null,
+                null, "System structure only");
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElementCommandUpdate(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"),
+                null, "System structure only");
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElementCommandUpdate(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                "010", "System structure only");
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElementCommandUpdate(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only 2");
         assertNotEquals(ne1, ne2);
     }
 
@@ -132,11 +153,11 @@ class NameElementCommandUpdateTest {
         NameElementCommandUpdate ne1 = null, ne2 = null;
 
         ne1 = new NameElementCommandUpdate(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null,
-                "System structure only");
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only");
         ne2 = new NameElementCommandUpdate(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null,
-                "System structure only");
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only");
 
         assertNotNull(ne1);
         assertNotNull(ne2);
@@ -149,11 +170,11 @@ class NameElementCommandUpdateTest {
         NameElementCommandUpdate ne1 = null, ne2 = null;
 
         ne1 = new NameElementCommandUpdate(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null,
-                "System structure only");
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only");
         ne2 = new NameElementCommandUpdate(
-                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null,
-                "System structure only");
+                UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only");
 
         assertNotNull(ne1);
         assertNotNull(ne2);
@@ -166,8 +187,8 @@ class NameElementCommandUpdateTest {
         NameElementCommandUpdate ne1 = null;
 
         ne1 = new NameElementCommandUpdate(
-                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null, null,
-                "System structure only");
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only");
 
         String str = ne1.toString();
 
diff --git a/src/test/java/org/openepics/names/rest/beans/element/NameElementTest.java b/src/test/java/org/openepics/names/rest/beans/element/NameElementTest.java
index d5a4b22016696ffbbd4f6b3d48386a0156516af3..0f0b35e24829de7fb54c2c9d5f3785bb1ff20d97 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/NameElementTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/NameElementTest.java
@@ -53,13 +53,13 @@ class NameElementTest {
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
         ne2 = new NameElement(
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         assertEquals(ne1, ne2);
@@ -69,7 +69,7 @@ class NameElementTest {
     void equalsJson() {
         ObjectMapper mapper = new ObjectMapper();
         NameElement ne1 = null, ne2 = null;
-        String json = "{\"uuid\": \"45bdc415-cf5a-4650-b6dd-478540830c2a\", \"parentSystemStructure\": \"eb7e55c2-012b-419d-881a-58a858894e92\", \"parentDeviceStructure\": null, \"systemStructure\": \"Acc\", \"deviceStructure\": null, \"index\": null, \"name\": \"Acc\", \"description\": \"System structure only\", \"status\": \"APPROVED\", \"latest\": true, \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": null}";
+        String json = "{\"uuid\": \"45bdc415-cf5a-4650-b6dd-478540830c2a\", \"parentSystemStructure\": \"eb7e55c2-012b-419d-881a-58a858894e92\", \"parentDeviceStructure\": null, \"systemStructure\": \"Acc\", \"deviceStructure\": null, \"index\": null, \"name\": \"Acc\", \"description\": \"System structure only\", \"status\": \"APPROVED\", \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": null}";
 
         try {
             ne1 = mapper.readValue(json, NameElement.class);
@@ -102,15 +102,112 @@ class NameElementTest {
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
         ne2 = new NameElement(
                 UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), null,
+                null, "System structure only",
+                "Acc", null, "Acc",
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"),
+                null, "System structure only",
+                "Acc", null, "Acc",
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                "010", "System structure only",
+                "Acc", null, "Acc",
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only 2",
+                "Acc", null, "Acc",
+                Status.APPROVED, false,
                 date, "test who", null);
+        assertNotEquals(ne1, ne2);
 
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only",
+                "Acd", null, "Acc",
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only",
+                "Acc", "Di", "Acc",
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only",
+                "Acc", null, "Acd",
+                Status.APPROVED, false,
+                date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only",
+                "Acc", null, "Acc",
+                Status.REJECTED, false,
+                date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only",
+                "Acc", null, "Acc",
+                Status.APPROVED, true,
+                date, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only",
+                "Acc", null, "Acc",
+                Status.APPROVED, false,
+                null, "test who", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only",
+                "Acc", null, "Acc",
+                Status.APPROVED, false,
+                date, "test who 2", null);
+        assertNotEquals(ne1, ne2);
+
+        ne2 = new NameElement(
+                UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
+                null, "System structure only",
+                "Acc", null, "Acc",
+                Status.APPROVED, false,
+                date, "test who", "test");
         assertNotEquals(ne1, ne2);
     }
 
@@ -118,8 +215,8 @@ class NameElementTest {
     void notEqualsJson() {
         ObjectMapper mapper = new ObjectMapper();
         NameElement ne1 = null, ne2 = null;
-        String json  = "{\"uuid\": \"45bdc415-cf5a-4650-b6dd-478540830c2a\", \"parentSystemStructure\": \"eb7e55c2-012b-419d-881a-58a858894e92\", \"parentDeviceStructure\": null, \"systemStructure\": \"Acc\", \"deviceStructure\": null, \"index\": null, \"name\": \"Acc\", \"description\": \"System structure only\", \"status\": \"APPROVED\", \"latest\": true, \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": null}";
-        String json2 = "{\"uuid\": \"55bdc415-cf5a-4650-b6dd-478540830c2a\", \"parentSystemStructure\": \"eb7e55c2-012b-419d-881a-58a858894e92\", \"parentDeviceStructure\": null, \"systemStructure\": \"Acc\", \"deviceStructure\": null, \"index\": null, \"name\": \"Acc\", \"description\": \"System structure only\", \"status\": \"APPROVED\", \"latest\": true, \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": null}";
+        String json  = "{\"uuid\": \"45bdc415-cf5a-4650-b6dd-478540830c2a\", \"parentSystemStructure\": \"eb7e55c2-012b-419d-881a-58a858894e92\", \"parentDeviceStructure\": null, \"systemStructure\": \"Acc\", \"deviceStructure\": null, \"index\": null, \"name\": \"Acc\", \"description\": \"System structure only\", \"status\": \"APPROVED\", \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": null}";
+        String json2 = "{\"uuid\": \"55bdc415-cf5a-4650-b6dd-478540830c2a\", \"parentSystemStructure\": \"eb7e55c2-012b-419d-881a-58a858894e92\", \"parentDeviceStructure\": null, \"systemStructure\": \"Acc\", \"deviceStructure\": null, \"index\": null, \"name\": \"Acc\", \"description\": \"System structure only\", \"status\": \"APPROVED\", \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": null}";
 
         try {
             ne1 = mapper.readValue(json,  NameElement.class);
@@ -153,13 +250,13 @@ class NameElementTest {
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
         ne2 = new NameElement(
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         assertNotNull(ne1);
@@ -177,13 +274,13 @@ class NameElementTest {
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
         ne2 = new NameElement(
                 UUID.fromString("55bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         assertNotNull(ne1);
@@ -201,7 +298,7 @@ class NameElementTest {
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         String str = ne1.toString();
@@ -221,7 +318,7 @@ class NameElementTest {
                 UUID.fromString("45bdc415-cf5a-4650-b6dd-478540830c2a"), UUID.fromString("eb7e55c2-012b-419d-881a-58a858894e92"), null,
                 null, "System structure only",
                 "Acc", null, "Acc",
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", null);
 
         String str = ne1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandConfirmTest.java b/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandConfirmTest.java
index 08e6ea68d798547c1f821cbc590d48edef704195..c621bc96159930e1465bb7d15d135bd341629fdd 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandConfirmTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandConfirmTest.java
@@ -88,9 +88,22 @@ class StructureElementCommandConfirmTest {
 
         se1 = new StructureElementCommandConfirm(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM);
+        assertNotEquals(se1, se2);
+
         se2 = new StructureElementCommandConfirm(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM);
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommandConfirm(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SUBSYSTEM);
+        assertNotEquals(se1, se2);
 
+        se2 = new StructureElementCommandConfirm(
+                null, Type.SYSTEM);
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommandConfirm(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), null);
         assertNotEquals(se1, se2);
     }
 
diff --git a/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandCreateTest.java b/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandCreateTest.java
index fdb45ae72f66c3be6d51e12653216bdfe55a291f..2faa79d1c813fdb75970d67ea39baa7075a2508d 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandCreateTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandCreateTest.java
@@ -91,10 +91,31 @@ class StructureElementCommandCreateTest {
         se1 = new StructureElementCommandCreate(
                 Type.SYSTEM, UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", 41, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommandCreate(
+                Type.SUBSYSTEM, UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", 41, "description");
+        assertNotEquals(se1, se2);
+
         se2 = new StructureElementCommandCreate(
                 Type.SYSTEM, UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
                 "AA1", 41, "description");
+        assertNotEquals(se1, se2);
 
+        se2 = new StructureElementCommandCreate(
+                Type.SYSTEM, UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA2", 41, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommandCreate(
+                Type.SYSTEM, UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", 42, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommandCreate(
+                Type.SYSTEM, UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", 41, "description 2");
         assertNotEquals(se1, se2);
     }
 
diff --git a/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandTest.java b/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandTest.java
index 385f63730c24e6dd70874b0022142b095a0ac270..acbe9eda129fc09c53d4a9e630a0d94b9cba16d9 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandTest.java
@@ -91,10 +91,36 @@ class StructureElementCommandTest {
         se1 = new StructureElementCommand(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description");
+        assertNotEquals(se1, se2);
+
         se2 = new StructureElementCommand(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommand(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SUBSYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommand(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", 41, "description");
+        assertNotEquals(se1, se2);
 
+        se2 = new StructureElementCommand(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA2", 41, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommand(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 42, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommand(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description 2");
         assertNotEquals(se1, se2);
     }
 
diff --git a/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandUpdateTest.java b/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandUpdateTest.java
index 7b093e824f61af523ec5902a81d75cd323d124f3..c22b86ccd7f48ffb6eadd6ddc12414f3e2b01bb7 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandUpdateTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/StructureElementCommandUpdateTest.java
@@ -91,10 +91,36 @@ class StructureElementCommandUpdateTest {
         se1 = new StructureElementCommandUpdate(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description");
+        assertNotEquals(se1, se2);
+
         se2 = new StructureElementCommandUpdate(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommandUpdate(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SUBSYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommandUpdate(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", 41, "description");
+        assertNotEquals(se1, se2);
 
+        se2 = new StructureElementCommandUpdate(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA2", 41, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommandUpdate(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 42, "description");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElementCommandUpdate(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description 2");
         assertNotEquals(se1, se2);
     }
 
diff --git a/src/test/java/org/openepics/names/rest/beans/element/StructureElementTest.java b/src/test/java/org/openepics/names/rest/beans/element/StructureElementTest.java
index 9454bfbd0716a29906617a52620f03759cc595c1..e9510295c78bd5aca9859b4e07fd35e00659a833 100644
--- a/src/test/java/org/openepics/names/rest/beans/element/StructureElementTest.java
+++ b/src/test/java/org/openepics/names/rest/beans/element/StructureElementTest.java
@@ -54,13 +54,13 @@ class StructureElementTest {
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         se2 = new StructureElement(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertEquals(se1, se2);
@@ -70,7 +70,7 @@ class StructureElementTest {
     void equalsJson() {
         ObjectMapper mapper = new ObjectMapper();
         StructureElement se1 = null, se2 = null;
-        String json = "{\"uuid\": \"a14a8565-de10-4026-97e3-ab129ffaba96\", \"type\": \"SYSTEM\", \"parent\": \"05d52f1c-391e-41e3-a48f-dc8f36f8329b\", \"mnemonic\": \"AA1\", \"mnemonicPath\": \"AA1\", \"ordering\": \"41\", \"level\": \"2\", \"description\": \"description\", \"status\": \"APPROVED\", \"latest\": true, \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": \"comment\"};";
+        String json = "{\"uuid\": \"a14a8565-de10-4026-97e3-ab129ffaba96\", \"type\": \"SYSTEM\", \"parent\": \"05d52f1c-391e-41e3-a48f-dc8f36f8329b\", \"mnemonic\": \"AA1\", \"mnemonicPath\": \"AA1\", \"ordering\": \"41\", \"level\": \"2\", \"description\": \"description\", \"status\": \"APPROVED\", \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": \"comment\"};";
 
         try {
             se1 = mapper.readValue(json, StructureElement.class);
@@ -103,15 +103,112 @@ class StructureElementTest {
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
         se2 = new StructureElement(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SUBSYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description",
+                "AA1", 2,
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"),
+                "AA1", 41, "description",
+                "AA1", 2,
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA2", 41, "description",
+                "AA1", 2,
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 42, "description",
+                "AA1", 2,
+                Status.APPROVED, false,
                 date, "test who", "comment");
+        assertNotEquals(se1, se2);
 
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description 2",
+                "AA1", 2,
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description",
+                "AA2", 2,
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description",
+                "AA1", 3,
+                Status.APPROVED, false,
+                date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description",
+                "AA1", 2,
+                Status.REJECTED, false,
+                date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description",
+                "AA1", 2,
+                Status.APPROVED, true,
+                date, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description",
+                "AA1", 2,
+                Status.APPROVED, false,
+                null, "test who", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description",
+                "AA1", 2,
+                Status.APPROVED, false,
+                date, "test who 2", "comment");
+        assertNotEquals(se1, se2);
+
+        se2 = new StructureElement(
+                UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
+                "AA1", 41, "description",
+                "AA1", 2,
+                Status.APPROVED, false,
+                date, "test who", "comment 2");
         assertNotEquals(se1, se2);
     }
 
@@ -119,8 +216,8 @@ class StructureElementTest {
     void notEqualsJson() {
         ObjectMapper mapper = new ObjectMapper();
         StructureElement se1 = null, se2 = null;
-        String json  = "{\"uuid\": \"a14a8565-de10-4026-97e3-ab129ffaba96\", \"type\": \"SYSTEM\", \"parent\": \"05d52f1c-391e-41e3-a48f-dc8f36f8329b\", \"mnemonic\": \"AA1\", \"mnemonicPath\": \"AA1\", \"ordering\": \"41\", \"level\": \"2\", \"description\": \"description\", \"status\": \"APPROVED\", \"latest\": true, \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": \"comment\"};";
-        String json2 = "{\"uuid\": \"b14a8565-de10-4026-97e3-ab129ffaba96\", \"type\": \"SYSTEM\", \"parent\": \"05d52f1c-391e-41e3-a48f-dc8f36f8329b\", \"mnemonic\": \"AA1\", \"mnemonicPath\": \"AA1\", \"ordering\": \"41\", \"level\": \"2\", \"description\": \"description\", \"status\": \"APPROVED\", \"latest\": true, \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": \"comment\"};";
+        String json  = "{\"uuid\": \"a14a8565-de10-4026-97e3-ab129ffaba96\", \"type\": \"SYSTEM\", \"parent\": \"05d52f1c-391e-41e3-a48f-dc8f36f8329b\", \"mnemonic\": \"AA1\", \"mnemonicPath\": \"AA1\", \"ordering\": \"41\", \"level\": \"2\", \"description\": \"description\", \"status\": \"APPROVED\", \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": \"comment\"};";
+        String json2 = "{\"uuid\": \"b14a8565-de10-4026-97e3-ab129ffaba96\", \"type\": \"SYSTEM\", \"parent\": \"05d52f1c-391e-41e3-a48f-dc8f36f8329b\", \"mnemonic\": \"AA1\", \"mnemonicPath\": \"AA1\", \"ordering\": \"41\", \"level\": \"2\", \"description\": \"description\", \"status\": \"APPROVED\", \"deleted\": false, \"when\": null, \"who\": \"test who\", \"comment\": \"comment\"};";
 
         try {
             se1 = mapper.readValue(json,  StructureElement.class);
@@ -154,13 +251,13 @@ class StructureElementTest {
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         se2 = new StructureElement(
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(se1);
@@ -178,13 +275,13 @@ class StructureElementTest {
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
         se2 = new StructureElement(
                 UUID.fromString("b14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         assertNotNull(se1);
@@ -202,7 +299,7 @@ class StructureElementTest {
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = se1.toString();
@@ -222,7 +319,7 @@ class StructureElementTest {
                 UUID.fromString("a14a8565-de10-4026-97e3-ab129ffaba96"), Type.SYSTEM, UUID.fromString("05d52f1c-391e-41e3-a48f-dc8f36f8329b"),
                 "AA1", 41, "description",
                 "AA1", 2,
-                Status.APPROVED, true, false,
+                Status.APPROVED, false,
                 date, "test who", "comment");
 
         String str = se1.toStringSimple();
diff --git a/src/test/java/org/openepics/names/util/NameElementUtilTest.java b/src/test/java/org/openepics/names/util/NameElementUtilTest.java
index 38ce1a5c1860e286db04a8085b7cdc7319fc201a..d4f66dad6aa724edc1833c4f12f19ac1958ef101 100644
--- a/src/test/java/org/openepics/names/util/NameElementUtilTest.java
+++ b/src/test/java/org/openepics/names/util/NameElementUtilTest.java
@@ -27,6 +27,7 @@ import java.util.UUID;
 
 import org.junit.jupiter.api.Test;
 import org.openepics.names.repository.model.Name;
+import org.openepics.names.repository.model.Structure;
 import org.openepics.names.rest.beans.Status;
 import org.openepics.names.rest.beans.element.NameElement;
 import org.openepics.names.rest.beans.element.NameElementCommand;
@@ -48,27 +49,20 @@ class NameElementUtilTest {
      */
     @Test
     void getNameElement() {
-        NameElement nameElement = NameElementUtil.getNameElement(null);
-        assertNull(nameElement);
+        Name name = null;
+        HolderStructures holderStructures = null;
+        Structure structure = null;
 
-        Name name = new Name();
-        nameElement = NameElementUtil.getNameElement(name);
+        NameElement nameElement = NameElementUtil.getNameElement(name, holderStructures);
+        assertNull(nameElement);
+        nameElement = NameElementUtil.getNameElement(name, structure);
+        assertNull(nameElement);
 
-        assertNotNull(nameElement);
-        assertEquals(null, nameElement.getUuid());
-        assertEquals(null, nameElement.getParentSystemStructure());
-        assertEquals(null, nameElement.getParentDeviceStructure());
-        assertEquals(null, nameElement.getSystemStructure());
-        assertEquals(null, nameElement.getDeviceStructure());
-        assertEquals(null, nameElement.getIndex());
-        assertEquals(null, nameElement.getName());
-        assertEquals(null, nameElement.getDescription());
-        assertEquals(Status.APPROVED, nameElement.getStatus());
-        assertEquals(null, nameElement.isLatest());
-        assertEquals(null, nameElement.isDeleted());
-        assertEquals(null, nameElement.getWhen());
-        assertEquals(null, nameElement.getWho());
-        assertEquals(null, nameElement.getComment());
+        name = new Name();
+        nameElement = NameElementUtil.getNameElement(name, holderStructures);
+        assertNull(nameElement);
+        nameElement = NameElementUtil.getNameElement(name, structure);
+        assertNull(nameElement);
     }
 
     /**
@@ -85,7 +79,6 @@ class NameElementUtilTest {
         String deviceStructure = "er";
         String name = "ui";
         Status status = Status.APPROVED;
-        Boolean latest = Boolean.TRUE;
         Boolean deleted = Boolean.FALSE;
         Date when = new Date();
         String who = "as";
@@ -95,7 +88,7 @@ class NameElementUtilTest {
                 uuid, parentSystemStructure, parentDeviceStructure,
                 index, description,
                 systemStructure, deviceStructure, name,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
 
         assertNotNull(nameElement);
@@ -108,7 +101,6 @@ class NameElementUtilTest {
         assertEquals(name, nameElement.getName());
         assertEquals(description, nameElement.getDescription());
         assertEquals(status, nameElement.getStatus());
-        assertEquals(latest, nameElement.isLatest());
         assertEquals(deleted, nameElement.isDeleted());
         assertEquals(when, nameElement.getWhen());
         assertEquals(who, nameElement.getWho());
@@ -285,7 +277,6 @@ class NameElementUtilTest {
         String deviceStructure = "er";
         String name = "ui";
         Status status = Status.APPROVED;
-        Boolean latest = Boolean.TRUE;
         Boolean deleted = Boolean.FALSE;
         Date when = new Date();
         String who = "as";
@@ -295,7 +286,7 @@ class NameElementUtilTest {
                 uuid, parentSystemStructure, parentDeviceStructure,
                 index, description,
                 systemStructure, deviceStructure, name,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
 
         NameElementCommandCreate commandCreate = NameElementUtil.convertElement2CommandCreate(element);
@@ -331,7 +322,6 @@ class NameElementUtilTest {
         String deviceStructure = "er";
         String name = "ui";
         Status status = Status.APPROVED;
-        Boolean latest = Boolean.TRUE;
         Boolean deleted = Boolean.FALSE;
         Date when = new Date();
         String who = "as";
@@ -341,7 +331,7 @@ class NameElementUtilTest {
                 uuid, parentSystemStructure, parentDeviceStructure,
                 index, description,
                 systemStructure, deviceStructure, name,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
 
         NameElementCommandUpdate commandUpdate = NameElementUtil.convertElement2CommandUpdate(element);
@@ -379,7 +369,6 @@ class NameElementUtilTest {
         String deviceStructure = "er";
         String name = "ui";
         Status status = Status.APPROVED;
-        Boolean latest = Boolean.TRUE;
         Boolean deleted = Boolean.FALSE;
         Date when = new Date();
         String who = "as";
@@ -389,7 +378,7 @@ class NameElementUtilTest {
                 uuid, parentSystemStructure, parentDeviceStructure,
                 index, description,
                 systemStructure, deviceStructure, name,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
 
         NameElementCommandConfirm commandConfirm = NameElementUtil.convertElement2CommandConfirm(element);
diff --git a/src/test/java/org/openepics/names/util/NameUtilTest.java b/src/test/java/org/openepics/names/util/NameUtilTest.java
index d690f2eeda38f0ae3841e5bd5a78af0d90f623aa..5b49d09c422269a90c5b92604ff53368415245f2 100644
--- a/src/test/java/org/openepics/names/util/NameUtilTest.java
+++ b/src/test/java/org/openepics/names/util/NameUtilTest.java
@@ -19,14 +19,9 @@
 package org.openepics.names.util;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
 
-import java.util.UUID;
-
-import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.CsvSource;
-import org.openepics.names.repository.model.Name;
 
 /**
  * Unit tests for NamingUtil class.
@@ -37,117 +32,6 @@ import org.openepics.names.repository.model.Name;
  */
 class NameUtilTest {
 
-    /**
-     * Test of get level of system structure for name.
-     */
-    @Test
-    void getLevelSystemStructure() {
-        Name name = new Name();
-        assertEquals(-1, NameUtil.getLevelSystemStructure(name));
-
-        name.setSubsystemUuid(UUID.randomUUID());
-        name.setSystemUuid(null);
-        name.setSystemGroupUuid(null);
-        assertEquals(3, NameUtil.getLevelSystemStructure(name));
-
-        name.setSubsystemUuid(null);
-        name.setSystemUuid(UUID.randomUUID());
-        name.setSystemGroupUuid(null);
-        assertEquals(2, NameUtil.getLevelSystemStructure(name));
-
-        name.setSubsystemUuid(UUID.randomUUID());
-        name.setSystemUuid(UUID.randomUUID());
-        name.setSystemGroupUuid(null);
-        assertEquals(-1, NameUtil.getLevelSystemStructure(name));
-
-        name.setSubsystemUuid(null);
-        name.setSystemUuid(null);
-        name.setSystemGroupUuid(UUID.randomUUID());
-        assertEquals(1, NameUtil.getLevelSystemStructure(name));
-
-        name.setSubsystemUuid(UUID.randomUUID());
-        name.setSystemUuid(null);
-        name.setSystemGroupUuid(UUID.randomUUID());
-        assertEquals(-1, NameUtil.getLevelSystemStructure(name));
-
-        name.setSubsystemUuid(null);
-        name.setSystemUuid(UUID.randomUUID());
-        name.setSystemGroupUuid(UUID.randomUUID());
-        assertEquals(-1, NameUtil.getLevelSystemStructure(name));
-
-        name.setSubsystemUuid(UUID.randomUUID());
-        name.setSystemUuid(UUID.randomUUID());
-        name.setSystemGroupUuid(UUID.randomUUID());
-        assertEquals(-1, NameUtil.getLevelSystemStructure(name));
-    }
-
-    /**
-     * Test of get level of device structure for name.
-     */
-    @Test
-    void getLevelDeviceStructure() {
-        Name name = new Name();
-        assertEquals(-1, NameUtil.getLevelDeviceStructure(name));
-
-        name.setDeviceTypeUuid(UUID.randomUUID());
-        assertEquals(3, NameUtil.getLevelDeviceStructure(name));
-    }
-
-    /**
-     * Test of get level of device structure for name.
-     */
-    @Test
-    void getParentSystemStructure() {
-        assertNull(NameUtil.getParentSystemStructure(null));
-
-        Name name = new Name();
-        assertNull(NameUtil.getParentSystemStructure(name));
-
-        name.setSystemGroupUuid(null);
-        name.setSystemUuid(null);
-        name.setSubsystemUuid(null);
-        assertNull(NameUtil.getParentSystemStructure(name));
-
-        UUID uuid1 = UUID.randomUUID();
-        name.setSystemGroupUuid(uuid1);
-        name.setSystemUuid(null);
-        name.setSubsystemUuid(null);
-        assertEquals(uuid1, NameUtil.getParentSystemStructure(name));
-
-        name.setSystemGroupUuid(null);
-        name.setSystemUuid(uuid1);
-        name.setSubsystemUuid(null);
-        assertEquals(uuid1, NameUtil.getParentSystemStructure(name));
-
-        name.setSystemGroupUuid(null);
-        name.setSystemUuid(null);
-        name.setSubsystemUuid(uuid1);
-        assertEquals(uuid1, NameUtil.getParentSystemStructure(name));
-
-        // cases below should not happen but test anyway
-        UUID uuid2 = UUID.randomUUID();
-        UUID uuid3 = UUID.randomUUID();
-        name.setSystemGroupUuid(uuid1);
-        name.setSystemUuid(uuid2);
-        name.setSubsystemUuid(uuid3);
-        assertEquals(uuid3, NameUtil.getParentSystemStructure(name));
-
-        name.setSystemGroupUuid(uuid1);
-        name.setSystemUuid(uuid2);
-        name.setSubsystemUuid(null);
-        assertEquals(uuid2, NameUtil.getParentSystemStructure(name));
-
-        name.setSystemGroupUuid(null);
-        name.setSystemUuid(uuid2);
-        name.setSubsystemUuid(uuid3);
-        assertEquals(uuid3, NameUtil.getParentSystemStructure(name));
-
-        name.setSystemGroupUuid(uuid1);
-        name.setSystemUuid(null);
-        name.setSubsystemUuid(uuid3);
-        assertEquals(uuid3, NameUtil.getParentSystemStructure(name));
-    }
-
     /**
      * Test of get convention name for system and device structure mnemonic paths and index.
      */
@@ -165,4 +49,5 @@ class NameUtilTest {
     void getName(String systemStructure, String deviceStructure, String index, String expected) {
         assertEquals(expected, NameUtil.getName(systemStructure, deviceStructure, index));
     }
+
 }
diff --git a/src/test/java/org/openepics/names/util/StructureElementUtilTest.java b/src/test/java/org/openepics/names/util/StructureElementUtilTest.java
index eda0b66ae900d0c810c5e2001b358d629c5b2aad..361770748cd5dd298820acd91ce8f9c2927d2cd3 100644
--- a/src/test/java/org/openepics/names/util/StructureElementUtilTest.java
+++ b/src/test/java/org/openepics/names/util/StructureElementUtilTest.java
@@ -58,7 +58,6 @@ class StructureElementUtilTest {
         String mnemonicPath = "zx";
         Integer level = 3;
         Status status = Status.PENDING;
-        Boolean latest = Boolean.FALSE;
         Boolean deleted = Boolean.FALSE;
         Date when = new Date();
         String who = "bn";
@@ -68,7 +67,7 @@ class StructureElementUtilTest {
                 uuid, type, parent,
                 mnemonic, ordering, description,
                 mnemonicPath, level,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
 
         assertNotNull(structureElement);
@@ -81,7 +80,6 @@ class StructureElementUtilTest {
         assertEquals(level, structureElement.getLevel());
         assertEquals(description, structureElement.getDescription());
         assertEquals(status, structureElement.getStatus());
-        assertEquals(latest, structureElement.isLatest());
         assertEquals(deleted, structureElement.isDeleted());
         assertEquals(when, structureElement.getWhen());
         assertEquals(who, structureElement.getWho());
@@ -302,7 +300,6 @@ class StructureElementUtilTest {
         String mnemonicPath = "zx";
         Integer level = 3;
         Status status = Status.PENDING;
-        Boolean latest = Boolean.FALSE;
         Boolean deleted = Boolean.FALSE;
         Date when = new Date();
         String who = "bn";
@@ -312,7 +309,7 @@ class StructureElementUtilTest {
                 uuid, type, parent,
                 mnemonic, ordering, description,
                 mnemonicPath, level,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
 
         StructureElementCommandCreate commandCreate = StructureElementUtil.convertElement2CommandCreate(element);
@@ -350,7 +347,6 @@ class StructureElementUtilTest {
         String mnemonicPath = "zx";
         Integer level = 3;
         Status status = Status.PENDING;
-        Boolean latest = Boolean.FALSE;
         Boolean deleted = Boolean.FALSE;
         Date when = new Date();
         String who = "bn";
@@ -360,7 +356,7 @@ class StructureElementUtilTest {
                 uuid, type, parent,
                 mnemonic, ordering, description,
                 mnemonicPath, level,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
 
         StructureElementCommandUpdate commandUpdate = StructureElementUtil.convertElement2CommandUpdate(element);
@@ -400,7 +396,6 @@ class StructureElementUtilTest {
         String mnemonicPath = "zx";
         Integer level = 3;
         Status status = Status.PENDING;
-        Boolean latest = Boolean.FALSE;
         Boolean deleted = Boolean.FALSE;
         Date when = new Date();
         String who = "bn";
@@ -410,7 +405,7 @@ class StructureElementUtilTest {
                 uuid, type, parent,
                 mnemonic, ordering, description,
                 mnemonicPath, level,
-                status, latest, deleted,
+                status, deleted,
                 when, who, comment);
 
         StructureElementCommandConfirm commandConfirm = StructureElementUtil.convertElement2CommandConfirm(element);
diff --git a/src/test/java/org/openepics/names/util/UtilitiesTest.java b/src/test/java/org/openepics/names/util/UtilitiesTest.java
index 9bea51634af995fa2f697f6e851ad08124b1bb59..8f7ba5d839765291514299f9b8c7e9e458eed3ae 100644
--- a/src/test/java/org/openepics/names/util/UtilitiesTest.java
+++ b/src/test/java/org/openepics/names/util/UtilitiesTest.java
@@ -112,7 +112,7 @@ class UtilitiesTest {
                 null, null, null,
                 null, null, null,
                 null, null,
-                null, null, null,
+                null, null,
                 null, null, null);
         assertFalse(Utilities.addToCollection(list,  structureElement));
 
@@ -124,7 +124,7 @@ class UtilitiesTest {
                 null, null, null,
                 null, null, null,
                 null, null,
-                null, null, null,
+                null, null,
                 null, null, null);
         assertTrue(Utilities.addToCollection(list,  structureElement));
         assertEquals(1, list.size());
diff --git a/src/test/java/org/openepics/names/util/ValidateUtilTest.java b/src/test/java/org/openepics/names/util/ValidateUtilTest.java
index fe3de52fc6965d929061c7c5dfdcfd8e3db19613..22eaebe3673353fe684b0fc17523ff55f60f6674 100644
--- a/src/test/java/org/openepics/names/util/ValidateUtilTest.java
+++ b/src/test/java/org/openepics/names/util/ValidateUtilTest.java
@@ -669,7 +669,8 @@ class ValidateUtilTest {
      */
     @Test
     void validateDataCreateNameElement() {
-        ValidateNameElementUtil.validateNameElementDataCreate(null, null, null, null, null);
+        ValidateNameElementUtil.validateNameElementDataCreate(null, null,
+                null, null, null);
     }
 
     /**
@@ -677,7 +678,8 @@ class ValidateUtilTest {
      */
     @Test
     void validateDataCreateName() {
-        ValidateNameElementUtil.validateNameDataCreate(null, null, null, null);
+        ValidateNameElementUtil.validateNameDataCreate(null, null,
+                null, null);
     }
     /**
      * Test of validate input update name element.
@@ -692,7 +694,8 @@ class ValidateUtilTest {
      */
     @Test
     void validateDataUpdateNameElement() {
-        ValidateNameElementUtil.validateNameElementDataUpdate(null, null, null, null, null);
+        ValidateNameElementUtil.validateNameElementDataUpdate(null, null,
+                null, null, null);
     }
 
     // ----------------------------------------------------------------------------------------------------
@@ -748,7 +751,8 @@ class ValidateUtilTest {
      */
     @Test
     void validateDataCreateStructureElement() {
-        ValidateStructureElementUtil.validateStructureElementDataCreate(null, null, null, null);
+        ValidateStructureElementUtil.validateStructureElementDataCreate(null, null,
+                null, null);
     }
 
     /**
@@ -756,7 +760,8 @@ class ValidateUtilTest {
      */
     @Test
     void validateDataCreateStructuret() {
-        ValidateStructureElementUtil.validateStructureDataCreate(null, null, null, null, null);
+        ValidateStructureElementUtil.validateStructureDataCreate(null, null, null,
+                null, null);
     }
 
     /**
@@ -772,7 +777,8 @@ class ValidateUtilTest {
      */
     @Test
     void validateDataUpdateStructureElement() {
-        ValidateStructureElementUtil.validateStructureElementDataUpdate(null, null, null, null);
+        ValidateStructureElementUtil.validateStructureElementDataUpdate(null, null,
+                null, null);
     }
 
 }
diff --git a/src/test/resources/data/templates/NameElementCommand_create_name_NameElement.xlsx b/src/test/resources/data/templates/NameElementCommand_create_name_NameElement.xlsx
index 3c6da31db53208e5521b92522af74f90f05b61d4..b564da6954897338e2c44ab963093de613298c14 100644
Binary files a/src/test/resources/data/templates/NameElementCommand_create_name_NameElement.xlsx and b/src/test/resources/data/templates/NameElementCommand_create_name_NameElement.xlsx differ
diff --git a/src/test/resources/data/templates/StructureElementCommand_create_system_StructureElement.xlsx b/src/test/resources/data/templates/StructureElementCommand_create_system_StructureElement.xlsx
index f0753712fc1fc340af9136b851f0eaff5294baf6..d2dc9802b5cc47ed0d81973e4eb8563b80d6adb7 100644
Binary files a/src/test/resources/data/templates/StructureElementCommand_create_system_StructureElement.xlsx and b/src/test/resources/data/templates/StructureElementCommand_create_system_StructureElement.xlsx differ