diff --git a/src/main/java/org/openepics/names/old/model/Device.java b/src/main/java/org/openepics/names/old/model/Device.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa2565afb16d7694d9c24c7802d23d01958ee73f
--- /dev/null
+++ b/src/main/java/org/openepics/names/old/model/Device.java
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2014 European Spallation Source ERIC.
+ * Copyright (c) 2014 Cosylab d.d.
+ *
+ * This file is part of Naming Service.
+ * Naming Service 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 any newer 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, see https://www.gnu.org/licenses/gpl-2.0.txt
+ */
+
+package org.openepics.names.old.model;
+
+import com.google.common.base.Preconditions;
+
+import javax.persistence.Entity;
+
+import org.openepics.names.repository.model.Persistable;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * An entity representing a device.
+ *
+ * @author Marko Kolar
+ */
+@Entity
+public class Device extends Persistable {
+
+    private static final long serialVersionUID = 8489649071981076533L;
+    private String uuid;
+
+    protected Device() {}
+
+    /**
+     * Constructs a new device entity based on a UUID identifier.
+     *
+     * @param uuid the universally unique identifier
+     */
+    public Device(UUID uuid) {
+        Preconditions.checkNotNull(uuid);
+        this.uuid = uuid.toString();
+    }
+
+    /**
+     * @return The universally unique identifier.
+     */
+    public UUID getUuid() { return UUID.fromString(uuid); }
+
+    @Override public boolean equals(Object other) {
+        return other instanceof Device && ((Device) other).getUuid().equals(getUuid());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getUuid());
+    }
+}
diff --git a/src/main/java/org/openepics/names/old/model/DeviceRevision.java b/src/main/java/org/openepics/names/old/model/DeviceRevision.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7efa5a8ab96d2c1755905aebe3abbb3d250ef7f
--- /dev/null
+++ b/src/main/java/org/openepics/names/old/model/DeviceRevision.java
@@ -0,0 +1,232 @@
+/*-
+ * Copyright (c) 2014 European Spallation Source ERIC.
+ * Copyright (c) 2014 Cosylab d.d.
+ *
+ * This file is part of Naming Service.
+ * Naming Service 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 any newer 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, see https://www.gnu.org/licenses/gpl-2.0.txt
+ */
+
+package org.openepics.names.old.model;
+
+import com.google.common.base.Preconditions;
+
+import javax.annotation.Nullable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import org.openepics.names.repository.model.Persistable;
+
+import java.util.Date;
+
+/**
+ * A revision of a Device entity representing its state at some point in time.
+ *
+ * @author Marko Kolar
+ */
+@Entity
+@Table(name = "devicerevision")
+public class DeviceRevision extends Persistable {
+
+    private static final long serialVersionUID = -7697708696131775826L;
+
+    @JoinColumn(name = "device_id")
+    private @ManyToOne Device device;
+
+    @JoinColumn(name = "requestedby_id")
+    private @ManyToOne UserAccount requestedBy;
+
+    @Column(name = "requestdate")
+    private Date requestDate;
+
+    private boolean deleted;
+
+    @JoinColumn(name = "section_id")
+    private @ManyToOne NamePart section;
+
+    @JoinColumn(name = "devicetype_id")
+    private @ManyToOne NamePart deviceType;
+
+    @Column(name = "instanceindex")
+    private @Nullable String instanceIndex;
+
+    @Column(name = "conventionname")
+    private String conventionName;
+
+    @Column(name = "conventionnameeqclass")
+    private String conventionNameEqClass;
+
+    @Column(name = "additionalinfo")
+    private @Nullable String additionalInfo;
+
+    @Column(name = "processorcomment")
+    private @Nullable String processorComment;
+
+    protected DeviceRevision() {}
+
+    /**
+     * Constructs a new device revision entity (data object with relations).
+     *
+     * @param device the device the revision pertains to
+     * @param requestDate the time when the revision was proposed
+     * @param requestedBy the user that proposed the revision. Null if the revision was generated by an automated
+     * process.
+     * @param deleted a flag signifying that the revision represents deletion of the device
+     * @param section the section containing the device
+     * @param deviceType the type of the device
+     * @param instanceIndex an additional identifier that, in combination with other attributes, determine the unique
+     * convention name of the device. Null if omitted.
+     * @param conventionName the full name of the device in accordance with the naming convention
+     * @param conventionNameEqClass the representative of the equivalence class the convention name belongs to. This is
+     * used to ensure uniqueness of convention names when treating similar looking names (for example, containing 0 vs.
+     * O, 1 vs. l) as equal.
+     * @param additionalInfo Additional information (description, comment etc) about the device.
+     */
+    public DeviceRevision(
+            Device device, Date requestDate, @Nullable UserAccount requestedBy, boolean deleted,
+            NamePart section, NamePart deviceType, @Nullable String instanceIndex, String conventionName,
+            String conventionNameEqClass, @Nullable String additionalInfo) {
+
+        this(device, requestDate, requestedBy, deleted, section, deviceType, instanceIndex, conventionName,
+                conventionNameEqClass, additionalInfo, null);
+    }
+
+    /**
+     * Constructs a new device revision entity (data object with relations).
+     *
+     * @param device the device the revision pertains to
+     * @param requestDate the time when the revision was proposed
+     * @param requestedBy the user that proposed the revision. Null if the revision was generated by an automated
+     * process.
+     * @param deleted a flag signifying that the revision represents deletion of the device
+     * @param section the section containing the device
+     * @param deviceType the type of the device
+     * @param instanceIndex an additional identifier that, in combination with other attributes, determine the unique
+     * convention name of the device. Null if omitted.
+     * @param conventionName the full name of the device in accordance with the naming convention
+     * @param conventionNameEqClass the representative of the equivalence class the convention name belongs to. This is
+     * used to ensure uniqueness of convention names when treating similar looking names (for example, containing 0 vs.
+     * O, 1 vs. l) as equal.
+     * @param additionalInfo additional information (description, comment etc) about the device
+     * @param commitMessage commit message
+     */
+    public DeviceRevision(
+            Device device, Date requestDate, @Nullable UserAccount requestedBy, boolean deleted,
+            NamePart section, NamePart deviceType, @Nullable String instanceIndex, String conventionName,
+            String conventionNameEqClass, @Nullable String additionalInfo, @Nullable String commitMessage) {
+
+        Preconditions.checkNotNull(device);
+        Preconditions.checkNotNull(requestDate);
+        Preconditions.checkNotNull(section);
+        // not check deviceType as device may have section but no deviceType
+        Preconditions.checkArgument(instanceIndex == null || !instanceIndex.isEmpty());
+        Preconditions.checkArgument(conventionName != null && !conventionName.isEmpty());
+        Preconditions.checkArgument(conventionNameEqClass != null);
+        Preconditions.checkArgument(additionalInfo == null || !additionalInfo.isEmpty());
+        this.device = device;
+        this.requestedBy = requestedBy;
+        this.requestDate = new Date(requestDate.getTime());
+        this.deleted = deleted;
+        this.section = section;
+        this.deviceType = deviceType;
+        this.instanceIndex = instanceIndex;
+        this.conventionName = conventionName;
+        this.conventionNameEqClass = conventionNameEqClass;
+        this.additionalInfo=additionalInfo;
+        this.processorComment=commitMessage;
+    }
+
+    /**
+     * @return The device the revision pertains to.
+     */
+    public Device getDevice() { return device; }
+
+    /**
+     * @return The time when the revision was proposed.
+     */
+    public Date getRequestDate() {
+        return requestDate != null ? new Date(requestDate.getTime()) : null;
+    }
+
+    /**
+     * @return The user that proposed the revision. Null if the revision was generated by an automated process.
+     */
+    public @Nullable UserAccount getRequestedBy() { return requestedBy; }
+
+    /**
+     * @return A flag signifying that the revision represents deletion of the device.
+     */
+    public boolean isDeleted() { return deleted; }
+
+    /**
+     * @return The section containing the device.
+     */
+    public NamePart getSection() { return section; }
+
+    /**
+     * @return The type of the device.
+     */
+    public NamePart getDeviceType() { return deviceType; }
+
+    /**
+     * @return  An additional identifier that, in combination with other attributes,
+     *          determine the unique convention name of the device. Null if omitted.
+     */
+    public @Nullable String getInstanceIndex() { return instanceIndex; }
+
+    /**
+     * @return The full name of the device in accordance with the naming convention.
+     */
+    public String getConventionName() { return conventionName; }
+
+    /**
+     * @return  The representative of the equivalence class the convention name belongs to.
+     *          This is used to ensure uniqueness of convention names when treating similar
+     *          looking names (for example, containing 0 vs. O, 1 vs. l) as equal.
+     */
+    public String getConventionNameEqClass() { return conventionNameEqClass; }
+
+    /**
+     * Sets the convention equivalent class
+     * @param conventionNameEqClass the convention equivalent class to be set.
+     */
+    public void setConventionNameEqClass(String conventionNameEqClass){
+       this.conventionNameEqClass= conventionNameEqClass;
+    }
+
+    /**
+     * @return Additional information (description, comment etc) about the device.
+     */
+    public @Nullable String getAdditionalInfo(){ return additionalInfo;}
+
+    @Nullable
+    public String getProcessorComment() {
+        return processorComment;
+    }
+
+    public void setProcessorComment(@Nullable String processorComment) {
+        this.processorComment = processorComment;
+    }
+
+    public boolean supersede(DeviceRevision other) {
+        // TODO: fix this...(when new revision are be created instead of updating old ones)
+        //        return other == null
+        //                    || getId() > other.getId()
+        //                    || getId() == other.getId() && other.getStatus().isPending() && !getStatus().isPending();
+        return other == null
+                || getId() > other.getId();
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/old/model/NamePart.java b/src/main/java/org/openepics/names/old/model/NamePart.java
new file mode 100644
index 0000000000000000000000000000000000000000..b80c650b451a86ba393e8f65ffff26033111511f
--- /dev/null
+++ b/src/main/java/org/openepics/names/old/model/NamePart.java
@@ -0,0 +1,88 @@
+/*-
+ * Copyright (c) 2014 European Spallation Source ERIC.
+ * Copyright (c) 2014 Cosylab d.d.
+ *
+ * This file is part of Naming Service.
+ * Naming Service 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 any newer 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, see https://www.gnu.org/licenses/gpl-2.0.txt
+ */
+
+package org.openepics.names.old.model;
+
+import com.google.common.base.Preconditions;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Table;
+
+import org.openepics.names.repository.model.Persistable;
+
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * An entity representing either a named section of the System Structure or a named device type of the Device Structure,
+ * depending on the specified namePartType.
+ *
+ * @author Marko Kolar
+ */
+@Entity
+@Table(name = "namepart")
+public class NamePart extends Persistable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1674808840579429369L;
+
+    private String uuid;
+
+    @Column(name = "nameparttype")
+    @Enumerated(EnumType.STRING)
+    private NamePartType namePartType;
+
+    protected NamePart() {}
+
+    /**
+     * Constructs a new name part entity based on a UUID identifier and name part type.
+     *
+     * @param uuid the universally unique identifier
+     * @param namePartType the type of the NamePart
+     */
+    public NamePart(UUID uuid, NamePartType namePartType) {
+        Preconditions.checkNotNull(uuid);
+        Preconditions.checkNotNull(namePartType);
+        this.uuid = uuid.toString();
+        this.namePartType = namePartType;
+    }
+
+    /**
+     * @return The universally unique identifier.
+     */
+    public UUID getUuid() { return UUID.fromString(uuid); }
+
+    /**
+     * @return The type of the NamePart.
+     */
+    public NamePartType getNamePartType() { return namePartType; }
+
+    @Override public boolean equals(Object other) {
+        return other instanceof NamePart && ((NamePart) other).getUuid().equals(getUuid());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getUuid());
+    }
+}
diff --git a/src/main/java/org/openepics/names/old/model/NamePartRevision.java b/src/main/java/org/openepics/names/old/model/NamePartRevision.java
new file mode 100644
index 0000000000000000000000000000000000000000..eea142c9ef11e19e859d99c1108556ce8876c800
--- /dev/null
+++ b/src/main/java/org/openepics/names/old/model/NamePartRevision.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2014 European Spallation Source ERIC.
+ * Copyright (c) 2014 Cosylab d.d.
+ *
+ * This software is Copyright by the Board of Trustees of Michigan
+ * State University (c) Copyright 2012.
+ *
+ * You may use this software under the terms of the GNU public license
+ *  (GPL). The terms of this license are described at:
+ *       http://www.gnu.org/licenses/gpl.txt
+ *
+ * Contact Information:
+ *   Facilitty for Rare Isotope Beam
+ *   Michigan State University
+ *   East Lansing, MI 48824-1321
+ *   http://frib.msu.edu
+ */
+
+package org.openepics.names.old.model;
+
+import com.google.common.base.Preconditions;
+
+import javax.annotation.Nullable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import org.openepics.names.repository.model.Persistable;
+
+import java.util.Date;
+
+/**
+ * A revision of a NamePart entity representing its state at some point in time.
+ *
+ * @author Vasu V
+ * @author Marko Kolar
+ * @author Karin Rathsman
+ */
+@Entity
+@Table(name = "namepartrevision")
+public class NamePartRevision extends Persistable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -8783968098755208875L;
+
+    @JoinColumn(name = "namepart_id")
+    private @ManyToOne NamePart namePart;
+
+    @Column(name = "requestdate")
+    private Date requestDate;
+
+    @JoinColumn(name = "requestedby_id")
+    private @ManyToOne @Nullable UserAccount requestedBy;
+
+    @Column(name = "requestercomment")
+    private @Nullable String requesterComment;
+
+    private boolean deleted;
+
+    @JoinColumn(name = "parent_id")
+    private @ManyToOne @Nullable NamePart parent;
+
+    private String name;
+
+    private @Nullable String mnemonic;
+
+    private @Nullable String description=null;
+
+    @Column(name = "mnemoniceqclass")
+    private @Nullable String mnemonicEqClass;
+
+    @Enumerated(EnumType.STRING)
+    private NamePartRevisionStatus status;
+
+    @JoinColumn(name = "processedby_id")
+    private @ManyToOne @Nullable UserAccount processedBy = null;
+
+    @Column(name = "processdate")
+    private @Nullable Date processDate = null;
+
+    @Column(name = "processorcomment")
+    private @Nullable String processorComment = null;
+
+    protected NamePartRevision() {}
+
+    /**
+     * Constructs a new name part revision entity (data object with relations).
+     *
+     * @param namePart          the name part the revision pertains to
+     * @param requestDate       the time when the revision was proposed
+     * @param requestedBy       the user that proposed the revision.
+     *                          Null if the revision was generated by an automated process.
+     * @param requesterComment  the comment the user gave when proposing the revision. Null if no comment was given.
+     * @param deleted           a flag signifying that the revision represents deletion of the name part
+     * @param parent            the parent of this name part in the hierarchy. Null if at the top of the hierarchy.
+     * @param name              is the full name of the part. Does not need to follow a convention.
+     * @param mnemonic          is the short, mnemonic name of the part in accordance with the naming convention
+     * @param description       is the (lengthy) description or comment of the part.
+     * @param mnemonicEqClass   the representative of the equivalence class the mnemonic belongs to.
+     *                          This is used to ensure uniqueness of mnemonics on certain levels when treating
+     *                          similar looking names (for example, containing 0 vs. O, 1 vs. l) as equal.
+     */
+    public NamePartRevision(
+            NamePart namePart, Date requestDate, @Nullable UserAccount requestedBy, @Nullable String requesterComment,
+            boolean deleted, @Nullable NamePart parent, String name, String mnemonic,
+            @Nullable String description, String mnemonicEqClass) {
+
+        Preconditions.checkNotNull(namePart);
+        Preconditions.checkNotNull(requestDate);
+        Preconditions.checkArgument(requesterComment == null || !requesterComment.isEmpty());
+        Preconditions.checkArgument(name != null && !name.isEmpty());
+        this.namePart = namePart;
+        this.requestDate = new Date(requestDate.getTime());
+        this.requestedBy = requestedBy;
+        this.requesterComment = requesterComment;
+        this.deleted = deleted;
+        this.parent = parent;
+        this.name = name;
+        this.mnemonic = mnemonic;
+        this.description = description;
+        this.mnemonicEqClass = mnemonicEqClass;
+        this.status = NamePartRevisionStatus.PENDING;
+    }
+
+    /**
+     * @return The name part the revision pertains to.
+     */
+    public NamePart getNamePart() { return namePart; }
+
+    /**
+     * Sets the status
+     * @param status the status to be set
+     */
+    public void setStatus(NamePartRevisionStatus status){
+        this.status = status;
+    }
+
+    /**
+     *  @return The time when the revision was proposed.
+     */
+    public Date getRequestDate() {
+        return requestDate != null ? new Date(requestDate.getTime()) : null;
+    }
+
+    /**
+     *  @return The user that proposed the revision. Null if the revision was generated by an automated process.
+     */
+    public @Nullable UserAccount getRequestedBy() { return requestedBy; }
+
+    /**
+     *  @return The comment the user gave when proposing the revision. Null if no comment was given.
+     */
+    public @Nullable String getRequesterComment() { return requesterComment; }
+
+    /**
+     *  @return A flag signifying that the revision represents deletion of the name part.
+     */
+    public boolean isDeleted() { return deleted; }
+
+    /**
+     *  @return The parent of this name part in the hierarchy. Null if at the top of the hierarchy.
+     */
+    public @Nullable NamePart getParent() { return parent; }
+
+    /**
+     *  @return Full name of the part. Does not need to follow a convention.
+     */
+    public String getName() { return name; }
+
+    /**
+     *  @return The short, mnemonic name of the part in accordance with the naming convention.
+     */
+    public @Nullable String getMnemonic() { return mnemonic; }
+
+    /**
+     *  @return The description or other relevant information of the namepart. Optional.
+     */
+    public @Nullable String getDescription(){ return description; }
+
+    /**
+     *  @return     The representative of the equivalence class the mnemonic belongs to.
+     *              This is used to ensure uniqueness of mnemonics on certain level when treating
+     *              similar looking names (for example, containing 0 vs. O, 1 vs. l) as equal.
+     */
+    public @Nullable String getMnemonicEqClass() { return mnemonicEqClass; }
+
+    //TODO Remove after first deploy!!!
+    public void setMnemonicEqClass(String mnemonicEqClass) { this.mnemonicEqClass = mnemonicEqClass; }
+
+    /**
+     *  @return The status of the name part in the request / approve workflow.
+     */
+    public NamePartRevisionStatus getStatus() { return status; }
+
+    /**
+     *  @return The time the revision was processed in the request / approve workflow. Null if still pending.
+     */
+    public @Nullable Date getProcessDate() {
+        return processDate != null ? new Date(processDate.getTime()) : null;
+    }
+
+    /**
+     * Sets the process date
+     * @param date the date to be set
+     */
+    public void setProcessDate(Date date) {
+        this.processDate = date != null ? new Date(date.getTime()) : null;
+    }
+
+    /**
+     *  @return     The user who processed the revision in the request / approve workflow.
+     *              Null if still pending or if the revision  @return was processed by an automated process.
+     */
+    public @Nullable UserAccount getProcessedBy() { return processedBy; }
+
+    /**
+     * Sets the process user
+     * @param user the process user
+     */
+    public void setProcessedBy(UserAccount user){
+        this.processedBy = user;
+    }
+
+    /**
+     *  @return     The comment the user gave when processing the revision in the request / approve workflow.
+     *              Null if still pending  @return or if no comment was given.
+     */
+    public @Nullable String getProcessorComment() { return processorComment; }
+
+    /**
+     * Sets the processorComment
+     * @param message the message
+     */
+    public void setProcessorComment(String message){
+        this.processorComment = message;
+    }
+
+    /**
+     * Updates the revision's status in the request / approve workflow as either approved, rejected or canceled.
+     * This completes the workflow and no further status changes are possible after that.
+     *
+     * @param status    the new status of the name part
+     * @param date      the time the revision was processed
+     * @param by        the user who processed the revision. Null if the revision was processed by an automated process.
+     * @param comment   the comment the administrator user gave when processing the revision.
+     *                  Null if no comment was given.
+     *
+     * @deprecated since version 3.3.2
+     */
+    @Deprecated
+    public void updateAsProcessed(
+            NamePartRevisionStatus status, Date date, @Nullable UserAccount by, @Nullable String comment) {
+
+        Preconditions.checkState(this.status == NamePartRevisionStatus.PENDING);
+        Preconditions.checkArgument(status != NamePartRevisionStatus.PENDING);
+        Preconditions.checkNotNull(date);
+        Preconditions.checkArgument(comment == null || !comment.isEmpty());
+        this.status = status;
+        this.processDate = new Date(date.getTime());
+        this.processedBy = by;
+        this.processorComment = comment;
+    }
+
+    /**
+     * rollback processed status to pending.
+     *
+     * @deprecated since version 3.3.2
+     */
+    @Deprecated
+    public void rollBackProcessed() {
+        Preconditions.checkState(!this.status.equals(NamePartRevisionStatus.PENDING),"Status cannot be Pending");
+        this.status=NamePartRevisionStatus.PENDING;
+        this.processDate = null;
+        this.processedBy = null;
+        this.processorComment = null;
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/old/model/NamePartType.java b/src/main/java/org/openepics/names/old/model/NamePartType.java
new file mode 100644
index 0000000000000000000000000000000000000000..78a585f08be446abcb8b35732a90770c26d6817a
--- /dev/null
+++ b/src/main/java/org/openepics/names/old/model/NamePartType.java
@@ -0,0 +1,32 @@
+/*-
+ * Copyright (c) 2014 European Spallation Source ERIC.
+ * Copyright (c) 2014 Cosylab d.d.
+ *
+ * This file is part of Naming Service.
+ * Naming Service 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 any newer 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, see https://www.gnu.org/licenses/gpl-2.0.txt
+ */
+
+package org.openepics.names.old.model;
+
+/**
+ * Type of a NamePart specifying whether it belongs to the System Structure or the Device Structure.
+ *
+ * @author Marko Kolar
+ */
+public enum NamePartType {
+    /** A (sub)section of the Logical System Structure. */
+    SECTION,
+
+    /** A device (sub)type of the Device Category Structure. */
+    DEVICE_TYPE
+}
diff --git a/src/main/java/org/openepics/names/old/model/Role.java b/src/main/java/org/openepics/names/old/model/Role.java
new file mode 100644
index 0000000000000000000000000000000000000000..36c1281f34b7ee6c45210afe7a2a55a7ae423aaa
--- /dev/null
+++ b/src/main/java/org/openepics/names/old/model/Role.java
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2014 European Spallation Source ERIC.
+ * Copyright (c) 2014 Cosylab d.d.
+ *
+ * This file is part of Naming Service.
+ * Naming Service 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 any newer 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, see https://www.gnu.org/licenses/gpl-2.0.txt
+ */
+
+package org.openepics.names.old.model;
+
+/**
+ * UserAccount's role that determines the user's access control permissions. Used by the SessionServiceTest (not RBAC)
+ *
+ * @author Marko Kolar
+ */
+public enum Role {
+    /**
+     * Editor role giving permissions to propose changes to the Logical System and Device Category structures
+     * and to add, modify or delete Devices.
+     */
+    EDITOR,
+
+    /**
+     * Super user role giving permission to approve or reject proposed changes to System and Device structures,
+     * in addition to normal Editor permissions.
+     */
+    SUPERUSER
+}
diff --git a/src/main/java/org/openepics/names/old/model/UserAccount.java b/src/main/java/org/openepics/names/old/model/UserAccount.java
new file mode 100644
index 0000000000000000000000000000000000000000..739f460b760396cabbfdf44ebe160923b45210f5
--- /dev/null
+++ b/src/main/java/org/openepics/names/old/model/UserAccount.java
@@ -0,0 +1,87 @@
+/*-
+ * Copyright (c) 2014 European Spallation Source ERIC.
+ * Copyright (c) 2014 Cosylab d.d.
+ *
+ * This file is part of Naming Service.
+ * Naming Service 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 any newer 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, see https://www.gnu.org/licenses/gpl-2.0.txt
+ */
+
+package org.openepics.names.old.model;
+
+import com.google.common.base.Preconditions;
+
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Table;
+
+import org.openepics.names.repository.model.Persistable;
+
+import java.util.Objects;
+
+/**
+ * An entity representing a user account used to sing in to the application.
+ *
+ * @author Vasu V
+ * @author Marko Kolar
+ */
+@Entity
+@Table(name = "useraccount")
+public class UserAccount extends Persistable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = -6026728360254460697L;
+
+    private String username;
+
+    @Enumerated(EnumType.STRING) private Role role;
+
+    protected UserAccount() {}
+
+    /**
+     * Constructs a new user account object given username and role.
+     *
+     * @param username the name identifying the user
+     * @param role the role that determines the user's access control permissions
+     */
+    public UserAccount(String username, Role role) {
+        Preconditions.checkArgument(username != null && !username.isEmpty());
+        Preconditions.checkNotNull(role);
+        this.username = username;
+        this.role = role;
+    }
+
+    /**
+     *  @return The name identifying the user
+     */
+    public String getUsername() { return username; }
+
+    /**
+     *  @return The role that determines the user's access control permissions
+     */
+    public Role getRole() { return role; }
+
+    @Override public int hashCode() {
+        return Objects.hashCode(username);
+    }
+
+    @Override public boolean equals(Object other) {
+        return other instanceof UserAccount && ((UserAccount) other).getUsername().equals(getUsername());
+    }
+
+    @Override public String toString(){
+        return getUsername();
+    }
+}
diff --git a/src/main/java/org/openepics/names/old/nameviews/NameViewProvider.java b/src/main/java/org/openepics/names/old/nameviews/NameViewProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..da8a0b170a51e20ee8178c9497d9a56a5d40af49
--- /dev/null
+++ b/src/main/java/org/openepics/names/old/nameviews/NameViewProvider.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2016 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.old.nameviews;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.openepics.names.old.model.DeviceRevision;
+
+/**
+ * Implementation of part of NameViewProvider.
+ * Been that generates the nameView tree and updates name views.
+ *
+ * @author karinrathsman
+ * @author Lars Johansson
+ *
+ */
+public class NameViewProvider implements Serializable {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 6916728601880286405L;
+
+    private NameRevisions nameRevisions;
+
+    public NameViewProvider() {
+        nameRevisions = new NameRevisions();
+    }
+
+    public void update(List<DeviceRevision> newRevisions) {
+        for (DeviceRevision revision : newRevisions) {
+            nameRevisions.update(revision);
+        }
+    }
+
+    public String equivalenceClassRepresentative(String name) {
+        return name != null
+                ? name.toUpperCase()
+                        .replaceAll("(?<=[A-Za-z])0+", "")
+                        .replace('I', '1').replace('L', '1').replace('O', '0')
+                        .replaceAll("(?<!\\d)0+(?=\\d)", "")
+                : null;
+    }
+
+    /**
+     * @return the restfulNameRevisionMap that maps a given device name with the
+     * latest revision with that name.
+     */
+    public NameRevisions getNameRevisions() {
+        return nameRevisions;
+    }
+
+    /**
+     * This class handles map of key-value with equivalence class representative of convention name as key
+     * and name revision as value. It is used to build structure of name data.
+     *
+     * <p>
+     * Equivalence class representative of convention name is used as key as it ensure uniqueness of names
+     * when treating similar looking names. Name revision represents database entry.
+     */
+    public class NameRevisions {
+
+        private Map<String, DeviceRevision> deviceRevisionMap;
+
+        /**
+         * Constructs new map for equivalence class representative of convention name and name revision objects.
+         */
+        public NameRevisions() {
+            deviceRevisionMap = new HashMap<>();
+        }
+
+        private String key(String name) {
+            return equivalenceClassRepresentative(name);
+        }
+
+        /**
+         * Retrieves content from nameRevisionMap for given parameter as <tt>uuid</tt> or <tt>name</tt>.
+         * Among usage is REST API and its methods.
+         *
+         * @param string uuid or name
+         * @return name revision
+         */
+        public DeviceRevision get(String string) {
+            // note
+            //     equivalenceClassRepresentative of name as key in deviceRevisionMap
+            //
+            //     method not to call key method with input string directly since that would mean
+            //     calling equivalenceClassRepresentative twice, which would potentially strip
+            //     information from input string, e.g. CRY0 would become CRY
+            //
+            //     method works with
+            //     - name
+            //     - equivalenceClassRepresentative of name
+            //     - uuid
+            //
+            //     1. consider input equivalenceClassRepresentative
+            //     2. consider input name (make equivalenceClassRepresentative)
+            //     3. consider input uuid
+
+            String key = string;
+            if (deviceRevisionMap.containsKey(key)) {
+                return deviceRevisionMap.get(key);
+            } else if (deviceRevisionMap.containsKey(key(key))) {
+                return deviceRevisionMap.get(key(key));
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Updates the deviceRevisionMap if the specified revision supersedes the
+         * existing revision with the same name
+         *
+         * @param revision
+         */
+        protected void update(DeviceRevision revision) {
+            String key = key(revision.getConventionName());
+            DeviceRevision otherRevision = deviceRevisionMap.get(key);
+            if (revision.supersede(otherRevision)) {
+                deviceRevisionMap.put(key, revision);
+            }
+        }
+
+        /**
+         * Return key set for device revision map.
+         *
+         * @return key set for device revision map
+         *
+         * @see NameRevisions
+         */
+        public Set<String> keySet() {
+            return deviceRevisionMap.keySet();
+        }
+
+        /**
+         * Return entry set for device revision map.
+         *
+         * @return entry set for device revision map
+         *
+         * @see NameRevisions
+         */
+        public Set<Map.Entry<String, DeviceRevision>> entrySet() {
+            return deviceRevisionMap.entrySet();
+        }
+
+        /**
+         * Return if device revision map contains given key.
+         *
+         * @param name key for device revision map
+         * @return if device revision map contains given key
+         *
+         * @see NameRevisions
+         */
+        public boolean contains(String name) {
+            return deviceRevisionMap.containsKey(key(name));
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/openepics/names/repository/old/IDeviceRevisionRepository.java b/src/main/java/org/openepics/names/repository/old/IDeviceRevisionRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..c31c35e78b42b83ffa11a7e3bc3be41450f05a67
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/old/IDeviceRevisionRepository.java
@@ -0,0 +1,32 @@
+/*
+ * 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.old;
+
+import org.openepics.names.old.model.DeviceRevision;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find device revision information from JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface IDeviceRevisionRepository extends JpaRepository<DeviceRevision, Long> {
+}
diff --git a/src/main/java/org/openepics/names/repository/old/INamePartRevisionRepository.java b/src/main/java/org/openepics/names/repository/old/INamePartRevisionRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..c26b7d1798bca9549e8daff42acbe4d3718f5b1f
--- /dev/null
+++ b/src/main/java/org/openepics/names/repository/old/INamePartRevisionRepository.java
@@ -0,0 +1,32 @@
+/*
+ * 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.old;
+
+import org.openepics.names.old.model.NamePartRevision;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Find name part revision information from JPA.
+ *
+ * @author Lars Johansson
+ */
+@Repository
+public interface INamePartRevisionRepository extends JpaRepository<NamePartRevision, Long> {
+}
diff --git a/src/main/java/org/openepics/names/rest/controller/VerificationController.java b/src/main/java/org/openepics/names/rest/controller/VerificationController.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e0f6913564ca446fcea4930888736b5c5cd8aaf
--- /dev/null
+++ b/src/main/java/org/openepics/names/rest/controller/VerificationController.java
@@ -0,0 +1,1045 @@
+/*
+ * 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.rest.controller;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.UUID;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.commons.lang3.StringUtils;
+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.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.old.IDeviceRevisionRepository;
+import org.openepics.names.repository.old.INamePartRevisionRepository;
+import org.openepics.names.util.HolderIRepositories;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * This part of REST API provides verification of data migration for Naming application.
+ *
+ * <p>Prerequisite(s)
+ * <ul>
+ * <li>both old and migrated database available</li>
+ * </ul>
+ *
+ * <p>
+ * Ideally, some knowledge of database tables and object structures acquired to dig into this class.
+ * It can be done in any case and there is documentation available.
+ * It is recommended to have database tables and object structures available.
+ *
+ * @author Lars Johansson
+ */
+@RestController
+@RequestMapping("/verification")
+@EnableAutoConfiguration
+public class VerificationController {
+
+    // note
+    //     global exception handler available
+
+    /*
+       Methods
+           read      GET /verification/migration_devicerevision   - readMigrationDeviceRevision()
+           read      GET /verification/migration_namepartrevision - readMigrationNamePartRevision
+           read      GET /verification/data_reachable             - readDataReachable()
+           read      GET /verification/restapi_oldvsnew           - readRestApiOldVsNew()
+     */
+
+    private static final Logger LOGGER = Logger.getLogger(VerificationController.class.getName());
+
+    private static final String NEW_LINE_BR = "<br/>";
+    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+    private HolderIRepositories holderIRepositories;
+
+    @Autowired
+    IDeviceRevisionRepository deviceRevisionRepository;
+    @Autowired
+    INamePartRevisionRepository namePartRevisionRepository;
+
+    @Autowired
+    public VerificationController(
+            INameRepository nameRepository,
+            ISystemGroupRepository systemGroupRepository,
+            ISystemRepository systemRepository,
+            ISubsystemRepository subsystemRepository,
+            IDisciplineRepository disciplineRepository,
+            IDeviceGroupRepository deviceGroupRepository,
+            IDeviceTypeRepository deviceTypeRepository) {
+
+        holderIRepositories = new HolderIRepositories(
+                nameRepository,
+                systemGroupRepository,
+                systemRepository,
+                subsystemRepository,
+                disciplineRepository,
+                deviceGroupRepository,
+                deviceTypeRepository);
+    }
+
+    /**
+     * Perform verification of data migration with focus on device revision.
+     * Ok if all entries ok and no entry nok.
+     *
+     * @return report of data migration
+     */
+    @GetMapping ("/migration_devicerevision")
+    public String readMigrationDeviceRevision() {
+        // verification of
+        //     name vs. devicerevision, device
+        //     with help of namepartrevision, namepart
+
+        // note
+        //     check entry by entry
+        //     ----------
+        //     to check  1st, 2nd, 3rd parent to determine if systemgroup, system or subsystem
+        //     otherwise not clear how to make sure if it is supposed to be systemgroup and not system, subsystem and vice versa
+        //     ----------
+        //     date may be in different format for different objects, to be formatted before being compared
+        //     ----------
+        //     name.id                                = devicerevision.id
+        //     name.version                           = devicerevision.version
+        //     name.uuid                              = devicerevision.device_id             (device.id      --> device.uuid)
+        //     name.namepartrevision_systemgroup_uuid = devicerevision.section_id            (namepart.id    --> namepart.uuid
+        //     name.namepartrevision_system_uuid      = devicerevision.section_id            (namepart.id    --> namepart.uuid
+        //     name.namepartrevision_subsystem_uuid   = devicerevision.section_id            (namepart.id    --> namepart.uuid
+        //     name.namepartrevision_devicetype_uuid  = devicerevision.devicetype_id         (namepart.id    --> namepart.uuid
+        //     name.instance_index                    = devicerevision.instanceindex
+        //     name.convention_name                   = devicerevision.conventionname
+        //     name.convention_name_equivalence       = devicerevision.conventionnameeqclass
+        //     name.description                       = devicerevision.additionalinfo
+        //     name.status                            = null
+        //     name.latest                            = true if id = get max id for uuid     (not consider status)
+        //     name.deleted                           = devicerevision.deleted
+        //     name.requested                         = devicerevision.requestdate
+        //     name.requested_by                      = devicerevision.requestedby_id        (useraccount.id --> useraccount.username)
+        //     name.requested_comment                 = null
+        //     name.processed                         = null
+        //     name.processed_by                      = null
+        //     name.processed_comment                 = devicerevision.processorcomment
+
+        StringBuilder reportHtml = new StringBuilder();
+
+        // find data
+        //     for verification
+        //         names
+        //     to support
+        //         device names
+        //         name part revisions
+
+        List<Name>             names             = holderIRepositories.getNameRepository().findAll();
+        List<DeviceRevision>   deviceNames       = deviceRevisionRepository.findAll();
+        List<NamePartRevision> namePartRevisions = namePartRevisionRepository.findAll();
+
+        prepareLogReport("readMigrationDeviceRevision, find data,     names.size:                       " + names.size(), reportHtml);
+        prepareLogReport("readMigrationDeviceRevision, find data,     deviceNames.size:                 " + deviceNames.size(), reportHtml);
+        prepareLogReport("readMigrationDeviceRevision, find data,     namePartRevisions.size:           " + namePartRevisions.size(), reportHtml);
+
+        // utility
+        //     interpret lists into hashmaps for faster retrieval in for loop below
+        //     used to help check name entries
+        //     ----------
+        //     mapIdDeviceRevision     - find corresponding (old) device revision for given id
+        //     mapUuidMaxIdName        - find out latest name id for given uuid
+        //     mapUuidNamePartRevision - find out name part revision for given uuid
+
+        HashMap<Long, DeviceRevision> mapIdDeviceRevision = new HashMap<>((int)(deviceNames.size()/0.75 + 2));
+        for (DeviceRevision deviceRevision : deviceNames) {
+            mapIdDeviceRevision.put(deviceRevision.getId(), deviceRevision);
+        }
+        HashMap<UUID, Long> mapUuidMaxIdName = new HashMap<>();
+        for (Name name : names) {
+            if (mapUuidMaxIdName.get(name.getUuid()) == null
+                    ||  name.getId() > mapUuidMaxIdName.get(name.getUuid())) {
+                mapUuidMaxIdName.put(name.getUuid(), name.getId());
+            }
+        }
+        HashMap<UUID, NamePartRevision> mapUuidNamePartRevision = new HashMap<>((int)(namePartRevisions.size()/0.75 + 2));
+        for (NamePartRevision namePartRevision : namePartRevisions) {
+            mapUuidNamePartRevision.put(namePartRevision.getNamePart().getUuid(), namePartRevision);
+        }
+
+        prepareLogReport("readMigrationDeviceRevision, utility,       mapIdDeviceRevision.size:         " + mapIdDeviceRevision.size(), reportHtml);
+        prepareLogReport("readMigrationDeviceRevision, utility,       mapUuidMaxIdName.size:            " + mapUuidMaxIdName.size(), reportHtml);
+        prepareLogReport("readMigrationDeviceRevision, utility,       mapUuidNamePartRevision.size:     " + mapUuidNamePartRevision.size(), reportHtml);
+
+        // keep track of id
+        //     ok
+        //     nok
+        SortedSet<Long> id_ok_deviceRevisionDevice  = new TreeSet<>();
+        SortedSet<Long> id_nok_deviceRevisionDevice = new TreeSet<>();
+
+        prepareLogReport("readMigrationDeviceRevision, check, before, id_ok_deviceRevisionDevice.size:  " + id_ok_deviceRevisionDevice.size(), reportHtml);
+        prepareLogReport("readMigrationDeviceRevision, check, before, id_nok_deviceRevisionDevice.size: " + id_nok_deviceRevisionDevice.size(), reportHtml);
+
+        // name
+        // check entry by entry
+        //     each attribute as expected
+        boolean check = false;
+        DeviceRevision deviceRevision = null;
+        for (Name name : names) {
+            check = true;
+            deviceRevision = mapIdDeviceRevision.get(name.getId());
+
+            check = deviceRevision != null;
+
+            check = check && name.getId().equals(deviceRevision.getId());
+            check = check && name.getVersion().equals(deviceRevision.getVersion());
+            check = check && name.getUuid().equals(deviceRevision.getDevice().getUuid());
+
+            // to check  1st, 2nd, 3rd parent to determine if systemgroup, system or subsystem
+            // otherwise not clear how to make sure if it is supposed to be systemgroup and not system, subsystem and vice versa
+            NamePartRevision parent1 = deviceRevision.getSection() != null
+                    ? mapUuidNamePartRevision.get(deviceRevision.getSection().getUuid())
+                    : null;
+            NamePartRevision parent2 = parent1 != null && parent1.getParent() != null
+                    ? mapUuidNamePartRevision.get(parent1.getParent().getUuid())
+                    : null;
+            NamePartRevision parent3 = parent2 != null && parent2.getParent() != null
+                    ? mapUuidNamePartRevision.get(parent2.getParent().getUuid())
+                    : null;
+            // parent 1    but not parent 2, 3 - system group
+            // parent 1, 2 but not parent 3    - system
+            // parent 1, 2, 3                  - subsystem
+            // else nok
+            UUID systemGroupUuid = name.getSystemgroupUuid();
+            UUID systemUuid = name.getSystemUuid();
+            UUID subsystemUuid = name.getSubsystemUuid();
+            UUID sectionUuid = deviceRevision.getSection().getUuid();
+            if (parent1 != null && parent2 == null && parent3 == null) {
+                check = check && sectionUuid.equals(systemGroupUuid) && systemUuid == null && subsystemUuid == null;
+            } else if (parent1 != null && parent2 != null && parent3 == null) {
+                check = check && sectionUuid.equals(systemUuid) && systemGroupUuid == null && subsystemUuid == null;
+            } else if (parent1 != null && parent2 != null && parent3 != null) {
+                check = check && sectionUuid.equals(subsystemUuid) && systemGroupUuid == null && systemUuid == null;
+            } else {
+                check = false;
+            }
+
+            check = check && ((name.getDevicetypeUuid() == null && deviceRevision.getDeviceType() == null)
+                                || (name.getDevicetypeUuid().equals(deviceRevision.getDeviceType().getUuid())));
+            check = check && StringUtils.equals(name.getInstanceIndex(), deviceRevision.getInstanceIndex());
+            check = check && StringUtils.equals(name.getConventionName(), deviceRevision.getConventionName());
+            check = check && StringUtils.equals(name.getConventionNameEquivalence(), deviceRevision.getConventionNameEqClass());
+            check = check && StringUtils.equals(name.getDescription(), deviceRevision.getAdditionalInfo());
+            check = check && name.getStatus() == null;
+
+            // latest
+            //     true if id = get max id for uuid
+            check = check && name.isLatest() == name.getId().equals(mapUuidMaxIdName.get(name.getUuid()));
+            check = check && name.isDeleted() == deviceRevision.isDeleted();
+
+            // date may be in different format for different objects, to be formatted before being compared
+            check = check && ((name.getRequested() == null && deviceRevision.getRequestDate() == null)
+                                || StringUtils.equals(SDF.format(name.getRequested()), SDF.format(deviceRevision.getRequestDate())));
+            check = check && StringUtils.equals(name.getRequestedBy(), deviceRevision.getRequestedBy().getUsername());
+            check = check && name.getRequestedComment() == null;
+            check = check && name.getProcessed() == null;
+            check = check && name.getProcessedBy() == null;
+            check = check && StringUtils.equals(name.getProcessedComment(), deviceRevision.getProcessorComment());
+
+            // add to count
+            if (check) {
+                id_ok_deviceRevisionDevice.add(name.getId());
+            } else {
+                id_nok_deviceRevisionDevice.add(name.getId());
+            }
+        }
+
+        // ok if
+        //     all entries ok
+        //     no entry nok
+        boolean ok = id_ok_deviceRevisionDevice.size() == names.size()
+                && id_nok_deviceRevisionDevice.size() == 0;
+
+        prepareLogReport("readMigrationDeviceRevision, check, after,  id_ok_deviceRevisionDevice.size:  " + id_ok_deviceRevisionDevice.size(), reportHtml);
+        prepareLogReport("readMigrationDeviceRevision, check, after,  id_nok_deviceRevisionDevice.size: " + id_nok_deviceRevisionDevice.size(), reportHtml);
+        prepareLogReport("readMigrationDeviceRevision, ok: " + ok, reportHtml);
+
+        return reportHtml.toString();
+    }
+
+    /**
+     * Perform verification of data migration with focus on name part revision.
+     * Ok if all entries ok and no entry nok.
+     *
+     * @return report of data migration
+     */
+    @GetMapping ("/migration_namepartrevision")
+    public String readMigrationNamePartRevision() {
+        // verification of
+        //     systemgroup
+        //     system
+        //     subsystem
+        //     discipline
+        //     devicegroup
+        //     devicetype
+        //         vs.
+        //     namepartrevision
+        //     with help of namepartrevision, namepart
+
+        // note
+        //     check entry by entry
+        //     ----------
+        //     to check parent uuid
+        //     ----------
+        //     date may be in different format for different objects, to be formatted before being compared
+        //     ----------
+        //     e.g.
+        //     system.id                  = namepartrevision.id
+        //     system.version             = namepartrevision.version
+        //     system.uuid                = namepartrevision.namepart_id      (namepart.id    --> namepart.uuid)
+        //     ( system.parent_uuid       = namepartrevision.parent_id        (namepart.id    --> namepart.uuid) )
+        //     system.name                = namepartrevision.name
+        //     system.mnemonic            = namepartrevision.mnemonic
+        //     system.mnemonicequivalence = namepartrevision.mnemoniceqclass
+        //     system.description         = namepartrevision.description
+        //     system.status              = namepartrevision.status
+        //     system.latest              = true if id = get max id for uuid  (consider status, but not PENDING)
+        //     system.deleted             = namepartrevision.deleted
+        //     system.requested           = namepartrevision.requestdate
+        //     system.requested_by        = namepartrevision.requestedby_id   (useraccount.id --> useraccount.username)
+        //     system.requested_comment   = namepartrevision.requestercomment
+        //     system.processed           = namepartrevision.processdate
+        //     system.processed_by        = namepartrevision.processedby_id   (useraccount.id --> useraccount.username)
+        //     system.processed_comment   = namepartrevision.processorcomment
+
+        StringBuilder reportHtml = new StringBuilder();
+
+        // find data
+        //     for verification
+        //         system groups
+        //         systems
+        //         subsystems
+        //         disciplines
+        //         device groups
+        //         device types
+        //     to support
+        //         name part revisions
+
+        List<SystemGroup>      systemGroups      = holderIRepositories.getSystemGroupRepository().findAll();
+        List<System>           systems           = holderIRepositories.getSystemRepository().findAll();
+        List<Subsystem>        subsystems        = holderIRepositories.getSubsystemRepository().findAll();
+        List<Discipline>       disciplines       = holderIRepositories.getDisciplineRepository().findAll();
+        List<DeviceGroup>      deviceGroups      = holderIRepositories.getDeviceGroupRepository().findAll();
+        List<DeviceType>       deviceTypes       = holderIRepositories.getDeviceTypeRepository().findAll();
+        List<NamePartRevision> namePartRevisions = namePartRevisionRepository.findAll();
+
+        prepareLogReport("readMigrationNamePartRevision, find data,                systemGroups.size:            " + systemGroups.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, find data,                systems.size:                 " + systems.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, find data,                subsystems.size:              " + subsystems.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, find data,                disciplines.size:             " + disciplines.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, find data,                deviceGroups.size:            " + deviceGroups.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, find data,                deviceTypes.size:             " + deviceTypes.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, find data,                namePartRevisions.size:       " + namePartRevisions.size(), reportHtml);
+
+        // utility
+        //     interpret lists into hashmaps for faster retrieval in for loop below
+        //     used to help check name entries
+        //     ----------
+        //     mapIdNamePartRevision   - find corresponding (old) name part revision for given id
+        //     mapUuidMaxIdSystemGroup - find out latest system group id for given uuid
+        //     mapUuidMaxIdSystem      - find out latest system id for given uuid
+        //     mapUuidMaxIdSubsystem   - find out latest subsystem id for given uuid
+        //     mapUuidMaxIdDiscipline  - find out latest discipline id for given uuid
+        //     mapUuidMaxIdDeviceGroup - find out latest device group id for given uuid
+        //     mapUuidMaxIdDeviceType  - find out latest device type id for given uuid
+
+        HashMap<Long, NamePartRevision> mapIdNamePartRevision = new HashMap<>((int)(namePartRevisions.size()/0.75 + 2));
+        for (NamePartRevision namePartRevision : namePartRevisions) {
+            mapIdNamePartRevision.put(namePartRevision.getId(), namePartRevision);
+        }
+        HashMap<UUID, Long> mapUuidMaxIdSystemGroup = new HashMap<>();
+        for (SystemGroup systemGroup : systemGroups) {
+            if (		(mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()) == null
+                        ||  systemGroup.getId() > mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()))
+                    && NamePartRevisionStatus.APPROVED.name().equals(systemGroup.getStatus().name())) {
+                mapUuidMaxIdSystemGroup.put(systemGroup.getUuid(), systemGroup.getId());
+            }
+        }
+        HashMap<UUID, Long> mapUuidMaxIdSystem = new HashMap<>();
+        for (System system : systems) {
+            if ((		mapUuidMaxIdSystem.get(system.getUuid()) == null
+                        ||  system.getId() > mapUuidMaxIdSystem.get(system.getUuid()))
+                    && NamePartRevisionStatus.APPROVED.name().equals(system.getStatus().name())) {
+                mapUuidMaxIdSystem.put(system.getUuid(), system.getId());
+            }
+        }
+        HashMap<UUID, Long> mapUuidMaxIdSubsystem = new HashMap<>();
+        for (Subsystem subsystem : subsystems) {
+            if (		(mapUuidMaxIdSubsystem.get(subsystem.getUuid()) == null
+                        ||  subsystem.getId() > mapUuidMaxIdSubsystem.get(subsystem.getUuid()))
+                    && NamePartRevisionStatus.APPROVED.name().equals(subsystem.getStatus().name())) {
+                mapUuidMaxIdSubsystem.put(subsystem.getUuid(), subsystem.getId());
+            }
+        }
+        HashMap<UUID, Long> mapUuidMaxIdDiscipline = new HashMap<>();
+        for (Discipline discipline : disciplines) {
+            if ((mapUuidMaxIdDiscipline.get(discipline.getUuid()) == null
+                    ||  discipline.getId() > mapUuidMaxIdDiscipline.get(discipline.getUuid()))
+                    && NamePartRevisionStatus.APPROVED.name().equals(discipline.getStatus().name())) {
+                mapUuidMaxIdDiscipline.put(discipline.getUuid(), discipline.getId());
+            }
+        }
+        HashMap<UUID, Long> mapUuidMaxIdDeviceGroup = new HashMap<>();
+        for (DeviceGroup deviceGroup : deviceGroups) {
+            if ((mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()) == null
+                    ||  deviceGroup.getId() > mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()))
+                    && NamePartRevisionStatus.APPROVED.name().equals(deviceGroup.getStatus().name())) {
+                mapUuidMaxIdDeviceGroup.put(deviceGroup.getUuid(), deviceGroup.getId());
+            }
+        }
+        HashMap<UUID, Long> mapUuidMaxIdDeviceType = new HashMap<>();
+        for (DeviceType deviceType : deviceTypes) {
+            if ((mapUuidMaxIdDeviceType.get(deviceType.getUuid()) == null
+                    ||  deviceType.getId() > mapUuidMaxIdDeviceType.get(deviceType.getUuid()))
+                    && NamePartRevisionStatus.APPROVED.name().equals(deviceType.getStatus().name())) {
+                mapUuidMaxIdDeviceType.put(deviceType.getUuid(), deviceType.getId());
+            }
+        }
+
+        prepareLogReport("readMigrationNamePartRevision, utility,                  mapIdNamePartRevision.size:   " + mapIdNamePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, utility,                  mapUuidMaxIdSystemGroup.size: " + mapUuidMaxIdSystemGroup.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, utility,                  mapUuidMaxIdSystem.size:      " + mapUuidMaxIdSystem.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, utility,                  mapUuidMaxIdSubsystem.size:   " + mapUuidMaxIdSubsystem.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, utility,                  mapUuidMaxIdDiscipline.size:  " + mapUuidMaxIdDiscipline.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, utility,                  mapUuidMaxIdDeviceGroup.size: " + mapUuidMaxIdDeviceGroup.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, utility,                  mapUuidMaxIdDeviceType.size:  " + mapUuidMaxIdDeviceType.size(), reportHtml);
+
+        // keep track of id
+        //     ok
+        //     nok
+        SortedSet<Long> id_ok_namePartRevision  = new TreeSet<>();
+        SortedSet<Long> id_nok_namePartRevision = new TreeSet<>();
+
+        prepareLogReport("readMigrationNamePartRevision, check, before,            id_ok_namePartRevision.size:  " + id_ok_namePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, check, before,            id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
+
+        // system group
+        // check entry by entry
+        //         each attribute as expected
+        boolean check = false;
+        NamePartRevision namePartRevision = null;
+        for (SystemGroup systemGroup : systemGroups) {
+            check = true;
+            namePartRevision = mapIdNamePartRevision.get(systemGroup.getId());
+
+            check = namePartRevision != null;
+
+            check = check && systemGroup.getId().equals(namePartRevision.getId());
+            check = check && systemGroup.getVersion().equals(namePartRevision.getVersion());
+            check = check && systemGroup.getUuid().equals(namePartRevision.getNamePart().getUuid());
+
+            // no parent uuid for system group
+            check = check && StringUtils.equals(systemGroup.getName(), namePartRevision.getName());
+            check = check && StringUtils.equals(systemGroup.getMnemonic(), namePartRevision.getMnemonic());
+            check = check && StringUtils.equals(systemGroup.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
+            check = check && StringUtils.equals(systemGroup.getDescription(), namePartRevision.getDescription());
+            check = check && ((systemGroup.getStatus() == null && namePartRevision.getStatus() == null)
+                                || (systemGroup.getStatus().name().equals(namePartRevision.getStatus().name())));
+
+            // latest
+            //     true if id = get max id for uuid
+            //     special rules for pending, not consider pending
+            check = check && systemGroup.isLatest() == systemGroup.getId().equals(mapUuidMaxIdSystemGroup.get(systemGroup.getUuid()));
+            check = check && systemGroup.isDeleted() == namePartRevision.isDeleted();
+
+            // date may be in different format for different objects, to be formatted before being compared
+            check = check && ((systemGroup.getRequested() == null && namePartRevision.getRequestDate() == null)
+                                || StringUtils.equals(SDF.format(systemGroup.getRequested()), SDF.format(namePartRevision.getRequestDate())));
+            check = check && (systemGroup.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
+                                || 	StringUtils.equals(systemGroup.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
+            check = check && StringUtils.equals(systemGroup.getRequestedComment(), namePartRevision.getRequesterComment());
+            check = check && ((systemGroup.getProcessed() == null && namePartRevision.getProcessDate() == null)
+                                || StringUtils.equals(SDF.format(systemGroup.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
+            check = check && (systemGroup.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
+                                || 	StringUtils.equals(systemGroup.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
+            check = check && StringUtils.equals(systemGroup.getProcessedComment(), namePartRevision.getProcessorComment());
+
+            // add to count
+            if (check) {
+                id_ok_namePartRevision.add(systemGroup.getId());
+            } else {
+                id_nok_namePartRevision.add(systemGroup.getId());
+            }
+        }
+        prepareLogReport("readMigrationNamePartRevision, check, after systemgroup, id_ok_namePartRevision.size:  " + id_ok_namePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, check, after systemgroup, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
+
+        // system
+        // check entry by entry
+        //         each attribute as expected
+        for (System system : systems) {
+            check = true;
+            namePartRevision = mapIdNamePartRevision.get(system.getId());
+
+            check = namePartRevision != null;
+
+            check = check && system.getId().equals(namePartRevision.getId());
+            check = check && system.getVersion().equals(namePartRevision.getVersion());
+            check = check && system.getUuid().equals(namePartRevision.getNamePart().getUuid());
+
+            // parent uuid
+            check = check && system.getParentUuid().equals(namePartRevision.getParent().getUuid());
+            check = check && StringUtils.equals(system.getName(), namePartRevision.getName());
+            check = check && StringUtils.equals(system.getMnemonic(), namePartRevision.getMnemonic());
+            check = check && StringUtils.equals(system.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
+            check = check && StringUtils.equals(system.getDescription(), namePartRevision.getDescription());
+            check = check && ((system.getStatus() == null && namePartRevision.getStatus() == null)
+                                || (system.getStatus().name().equals(namePartRevision.getStatus().name())));
+
+            // latest
+            //     true if id = get max id for uuid
+            //     special rules for pending, not consider pending
+            check = check && system.isLatest() == system.getId().equals(mapUuidMaxIdSystem.get(system.getUuid()));
+            check = check && system.isDeleted() == namePartRevision.isDeleted();
+
+            // date may be in different format for different objects, to be formatted before being compared
+            check = check && ((system.getRequested() == null && namePartRevision.getRequestDate() == null)
+                                || StringUtils.equals(SDF.format(system.getRequested()), SDF.format(namePartRevision.getRequestDate())));
+            check = check && (system.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
+                                || 	StringUtils.equals(system.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
+            check = check && StringUtils.equals(system.getRequestedComment(), namePartRevision.getRequesterComment());
+            check = check && ((system.getProcessed() == null && namePartRevision.getProcessDate() == null)
+                                || StringUtils.equals(SDF.format(system.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
+            check = check && (system.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
+                                || 	StringUtils.equals(system.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
+            check = check && StringUtils.equals(system.getProcessedComment(), namePartRevision.getProcessorComment());
+
+            // add to count
+            if (check) {
+                id_ok_namePartRevision.add(system.getId());
+            } else {
+                id_nok_namePartRevision.add(system.getId());
+            }
+        }
+        prepareLogReport("readMigrationNamePartRevision, check, after system,      id_ok_namePartRevision.size:  " + id_ok_namePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, check, after system,      id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
+
+        // subsystem
+        // check entry by entry
+        //         each attribute as expected
+        for (Subsystem subsystem : subsystems) {
+            check = true;
+            namePartRevision = mapIdNamePartRevision.get(subsystem.getId());
+
+            check = namePartRevision != null;
+
+            check = check && subsystem.getId().equals(namePartRevision.getId());
+            check = check && subsystem.getVersion().equals(namePartRevision.getVersion());
+            check = check && subsystem.getUuid().equals(namePartRevision.getNamePart().getUuid());
+
+            // parent uuid
+            check = check && subsystem.getParentUuid().equals(namePartRevision.getParent().getUuid());
+            check = check && StringUtils.equals(subsystem.getName(), namePartRevision.getName());
+            check = check && StringUtils.equals(subsystem.getMnemonic(), namePartRevision.getMnemonic());
+            check = check && StringUtils.equals(subsystem.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
+            check = check && StringUtils.equals(subsystem.getDescription(), namePartRevision.getDescription());
+            check = check && ((subsystem.getStatus() == null && namePartRevision.getStatus() == null)
+                                || (subsystem.getStatus().name().equals(namePartRevision.getStatus().name())));
+
+            // latest
+            //     true if id = get max id for uuid
+            //     special rules for pending, not consider pending
+            check = check && subsystem.isLatest() == subsystem.getId().equals(mapUuidMaxIdSubsystem.get(subsystem.getUuid()));
+            check = check && subsystem.isDeleted() == namePartRevision.isDeleted();
+
+            // date may be in different format for different objects, to be formatted before being compared
+            check = check && ((subsystem.getRequested() == null && namePartRevision.getRequestDate() == null)
+                                || StringUtils.equals(SDF.format(subsystem.getRequested()), SDF.format(namePartRevision.getRequestDate())));
+            check = check && (subsystem.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
+                                || 	StringUtils.equals(subsystem.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
+            check = check && StringUtils.equals(subsystem.getRequestedComment(), namePartRevision.getRequesterComment());
+            check = check && ((subsystem.getProcessed() == null && namePartRevision.getProcessDate() == null)
+                                || StringUtils.equals(SDF.format(subsystem.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
+            check = check && (subsystem.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
+                                || 	StringUtils.equals(subsystem.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
+            check = check && StringUtils.equals(subsystem.getProcessedComment(), namePartRevision.getProcessorComment());
+
+            // add to count
+            if (check) {
+                id_ok_namePartRevision.add(subsystem.getId());
+            } else {
+                id_nok_namePartRevision.add(subsystem.getId());
+            }
+        }
+        prepareLogReport("readMigrationNamePartRevision, check, after subsystem,   id_ok_namePartRevision.size:  " + id_ok_namePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, check, after subsystem,   id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
+
+        // discipline
+        // check entry by entry
+        //         each attribute as expected
+        for (Discipline discipline : disciplines) {
+            check = true;
+            namePartRevision = mapIdNamePartRevision.get(discipline.getId());
+
+            check = namePartRevision != null;
+
+            check = check && discipline.getId().equals(namePartRevision.getId());
+            check = check && discipline.getVersion().equals(namePartRevision.getVersion());
+            check = check && discipline.getUuid().equals(namePartRevision.getNamePart().getUuid());
+
+            // no parent uuid for discipline
+            check = check && StringUtils.equals(discipline.getName(), namePartRevision.getName());
+            check = check && StringUtils.equals(discipline.getMnemonic(), namePartRevision.getMnemonic());
+            check = check && StringUtils.equals(discipline.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
+            check = check && StringUtils.equals(discipline.getDescription(), namePartRevision.getDescription());
+            check = check && ((discipline.getStatus() == null && namePartRevision.getStatus() == null)
+                                || (discipline.getStatus().name().equals(namePartRevision.getStatus().name())));
+
+            // latest
+            //     true if id = get max id for uuid
+            //     special rules for pending, not consider pending
+            check = check && discipline.isLatest() == discipline.getId().equals(mapUuidMaxIdDiscipline.get(discipline.getUuid()));
+            check = check && discipline.isDeleted() == namePartRevision.isDeleted();
+
+            // date may be in different format for different objects, to be formatted before being compared
+            check = check && ((discipline.getRequested() == null && namePartRevision.getRequestDate() == null)
+                                || StringUtils.equals(SDF.format(discipline.getRequested()), SDF.format(namePartRevision.getRequestDate())));
+            check = check && (discipline.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
+                                || 	StringUtils.equals(discipline.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
+            check = check && StringUtils.equals(discipline.getRequestedComment(), namePartRevision.getRequesterComment());
+            check = check && ((discipline.getProcessed() == null && namePartRevision.getProcessDate() == null)
+                                || StringUtils.equals(SDF.format(discipline.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
+            check = check && (discipline.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
+                                || 	StringUtils.equals(discipline.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
+            check = check && StringUtils.equals(discipline.getProcessedComment(), namePartRevision.getProcessorComment());
+
+            // add to count
+            if (check) {
+                id_ok_namePartRevision.add(discipline.getId());
+            } else {
+                id_nok_namePartRevision.add(discipline.getId());
+            }
+        }
+        prepareLogReport("readMigrationNamePartRevision, check, after discipline,  id_ok_namePartRevision.size:  " + id_ok_namePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, check, after discipline,  id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
+
+        // device group
+        // check entry by entry
+        //         each attribute as expected
+        for (DeviceGroup deviceGroup : deviceGroups) {
+            check = true;
+            namePartRevision = mapIdNamePartRevision.get(deviceGroup.getId());
+
+            check = namePartRevision != null;
+
+            check = check && deviceGroup.getId().equals(namePartRevision.getId());
+            check = check && deviceGroup.getVersion().equals(namePartRevision.getVersion());
+            check = check && deviceGroup.getUuid().equals(namePartRevision.getNamePart().getUuid());
+
+            // parent uuid
+            check = check && deviceGroup.getParentUuid().equals(namePartRevision.getParent().getUuid());
+            check = check && StringUtils.equals(deviceGroup.getName(), namePartRevision.getName());
+            check = check && StringUtils.equals(deviceGroup.getMnemonic(), namePartRevision.getMnemonic());
+            check = check && StringUtils.equals(deviceGroup.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
+            check = check && StringUtils.equals(deviceGroup.getDescription(), namePartRevision.getDescription());
+            check = check && ((deviceGroup.getStatus() == null && namePartRevision.getStatus() == null)
+                                || (deviceGroup.getStatus().name().equals(namePartRevision.getStatus().name())));
+
+            // latest
+            //     true if id = get max id for uuid
+            //     special rules for pending, not consider pending
+            check = check && deviceGroup.isLatest() == deviceGroup.getId().equals(mapUuidMaxIdDeviceGroup.get(deviceGroup.getUuid()));
+            check = check && deviceGroup.isDeleted() == namePartRevision.isDeleted();
+
+            // date may be in different format for different objects, to be formatted before being compared
+            check = check && ((deviceGroup.getRequested() == null && namePartRevision.getRequestDate() == null)
+                                || StringUtils.equals(SDF.format(deviceGroup.getRequested()), SDF.format(namePartRevision.getRequestDate())));
+            check = check && (deviceGroup.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
+                                || 	StringUtils.equals(deviceGroup.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
+            check = check && StringUtils.equals(deviceGroup.getRequestedComment(), namePartRevision.getRequesterComment());
+            check = check && ((deviceGroup.getProcessed() == null && namePartRevision.getProcessDate() == null)
+                                || StringUtils.equals(SDF.format(deviceGroup.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
+            check = check && (deviceGroup.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
+                                || 	StringUtils.equals(deviceGroup.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
+            check = check && StringUtils.equals(deviceGroup.getProcessedComment(), namePartRevision.getProcessorComment());
+
+            // add to count
+            if (check) {
+                id_ok_namePartRevision.add(deviceGroup.getId());
+            } else {
+                id_nok_namePartRevision.add(deviceGroup.getId());
+            }
+        }
+        prepareLogReport("readMigrationNamePartRevision, check, after devicegroup, id_ok_namePartRevision.size:  " + id_ok_namePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, check, after devicegroup, id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
+
+        // device type
+        // check entry by entry
+        //         each attribute as expected
+        for (DeviceType deviceType : deviceTypes) {
+            check = true;
+            namePartRevision = mapIdNamePartRevision.get(deviceType.getId());
+
+            check = namePartRevision != null;
+
+            check = check && deviceType.getId().equals(namePartRevision.getId());
+            check = check && deviceType.getVersion().equals(namePartRevision.getVersion());
+            check = check && deviceType.getUuid().equals(namePartRevision.getNamePart().getUuid());
+
+            // parent uuid
+            check = check && deviceType.getParentUuid().equals(namePartRevision.getParent().getUuid());
+            check = check && StringUtils.equals(deviceType.getName(), namePartRevision.getName());
+            check = check && StringUtils.equals(deviceType.getMnemonic(), namePartRevision.getMnemonic());
+            check = check && StringUtils.equals(deviceType.getMnemonicEquivalence(), namePartRevision.getMnemonicEqClass());
+            check = check && StringUtils.equals(deviceType.getDescription(), namePartRevision.getDescription());
+            check = check && ((deviceType.getStatus() == null && namePartRevision.getStatus() == null)
+                                || (deviceType.getStatus().name().equals(namePartRevision.getStatus().name())));
+
+            // latest
+            //     true if id = get max id for uuid
+            //     special rules for pending, not consider pending
+            check = check && deviceType.isLatest() == deviceType.getId().equals(mapUuidMaxIdDeviceType.get(deviceType.getUuid()));
+            check = check && deviceType.isDeleted() == namePartRevision.isDeleted();
+
+            // date may be in different format for different objects, to be formatted before being compared
+            check = check && ((deviceType.getRequested() == null && namePartRevision.getRequestDate() == null)
+                                || StringUtils.equals(SDF.format(deviceType.getRequested()), SDF.format(namePartRevision.getRequestDate())));
+            check = check && (deviceType.getRequestedBy() == null && namePartRevision.getRequestedBy() == null
+                                || 	StringUtils.equals(deviceType.getRequestedBy(), namePartRevision.getRequestedBy().getUsername()));
+            check = check && StringUtils.equals(deviceType.getRequestedComment(), namePartRevision.getRequesterComment());
+            check = check && ((deviceType.getProcessed() == null && namePartRevision.getProcessDate() == null)
+                                || StringUtils.equals(SDF.format(deviceType.getProcessed()), SDF.format(namePartRevision.getProcessDate())));
+            check = check && (deviceType.getProcessedBy() == null && namePartRevision.getProcessedBy() == null
+                                || 	StringUtils.equals(deviceType.getProcessedBy(), namePartRevision.getProcessedBy().getUsername()));
+            check = check && StringUtils.equals(deviceType.getProcessedComment(), namePartRevision.getProcessorComment());
+
+            // add to count
+            if (check) {
+                id_ok_namePartRevision.add(deviceType.getId());
+            } else {
+                id_nok_namePartRevision.add(deviceType.getId());
+            }
+        }
+        prepareLogReport("readMigrationNamePartRevision, check, after devicetype,  id_ok_namePartRevision.size:  " + id_ok_namePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, check, after devicetype,  id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
+
+        // ok if
+        //     all entries ok
+        //     no entry nok
+        boolean ok = id_ok_namePartRevision.size() == namePartRevisions.size()
+                && id_nok_namePartRevision.size() == 0;
+
+        prepareLogReport("readMigrationNamePartRevision, check, after,             id_ok_namePartRevision.size:  " + id_ok_namePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, check, after,             id_nok_namePartRevision.size: " + id_nok_namePartRevision.size(), reportHtml);
+        prepareLogReport("readMigrationNamePartRevision, ok:  " + ok, reportHtml);
+
+        return reportHtml.toString();
+    }
+
+    // ----------------------------------------------------------------------------------------------------
+
+    /**
+     * Perform verification of data in sense that all data can be reached. Current data is one thing but suggested data (pending) and old data (obsolete) is another thing.
+     * All data reached verification can be done like selecting all entries from tables (names, system group, system, subsystem, discipline, device group, device type)
+     * and then take uuid and retrieve history for uuid. By that, all entries should be reached. In a sense, select distinct uuid, then retrieve history by uuid,
+     * all ids should be encompassed by looking at all returned rows. Requires a couple of for loops and maps and sets to keep track of things.
+     *
+     * This verification concerns itself with new database, not old database.
+     *
+     * @return report of reachability of data
+     */
+    @GetMapping ("/data_reachable")
+    public String readDataReachable() {
+        StringBuilder reportHtml = new StringBuilder();
+
+        List<Name>             names             = holderIRepositories.getNameRepository().findAll();
+        List<SystemGroup>      systemGroups      = holderIRepositories.getSystemGroupRepository().findAll();
+        List<System>           systems           = holderIRepositories.getSystemRepository().findAll();
+        List<Subsystem>        subsystems        = holderIRepositories.getSubsystemRepository().findAll();
+        List<Discipline>       disciplines       = holderIRepositories.getDisciplineRepository().findAll();
+        List<DeviceGroup>      deviceGroups      = holderIRepositories.getDeviceGroupRepository().findAll();
+        List<DeviceType>       deviceTypes       = holderIRepositories.getDeviceTypeRepository().findAll();
+
+        prepareLogReport("readDataReachable, find data,                names.size:            " + names.size(), reportHtml);
+        prepareLogReport("readDataReachable, find data,                systemGroups.size:     " + systemGroups.size(), reportHtml);
+        prepareLogReport("readDataReachable, find data,                systems.size:          " + systems.size(), reportHtml);
+        prepareLogReport("readDataReachable, find data,                subsystems.size:       " + subsystems.size(), reportHtml);
+        prepareLogReport("readDataReachable, find data,                disciplines.size:      " + disciplines.size(), reportHtml);
+        prepareLogReport("readDataReachable, find data,                deviceGroups.size:     " + deviceGroups.size(), reportHtml);
+        prepareLogReport("readDataReachable, find data,                deviceTypes.size:      " + deviceTypes.size(), reportHtml);
+
+        HashSet<Long> setIdName        = new HashSet<>();
+        HashSet<Long> setIdSystemGroup = new HashSet<>();
+        HashSet<Long> setIdSystem      = new HashSet<>();
+        HashSet<Long> setIdSubsystem   = new HashSet<>();
+        HashSet<Long> setIdDiscipline  = new HashSet<>();
+        HashSet<Long> setIdDeviceGroup = new HashSet<>();
+        HashSet<Long> setIdDeviceType  = 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;
+
+        prepareLogReport("readDataReachable, check, before", reportHtml);
+
+        // get started
+        //     go through list(s)
+        //     get entries per uuid - to mimic find history through REST API by uuid
+        //     keep track of ids in set(s)
+        //     ok if set(s) size same as list(s) size
+        //     any entry not in set or once in set
+
+        for (Name name : names) {
+            // to mimic - Find history for name by uuid
+            namesByUuid = holderIRepositories.getNameRepository().findByUuid(name.getUuid().toString());
+            for (Name nameByUuid : namesByUuid) {
+                setIdName.add(nameByUuid.getId());
+            }
+        }
+
+        prepareLogReport("readDataReachable, check, after name,        setIdName.size:        " + setIdName.size(), reportHtml);
+
+        for (SystemGroup systemGroup : systemGroups) {
+            // to mimic - Find history for system group by uuid
+            systemGroupsByUuid = holderIRepositories.getSystemGroupRepository().findByUuid(systemGroup.getUuid().toString());
+            for (SystemGroup systemGroupByUuid : systemGroupsByUuid) {
+                setIdSystemGroup.add(systemGroupByUuid.getId());
+            }
+        }
+
+        prepareLogReport("readDataReachable, check, after systemgroup, setIdSystemGroup.size: " + setIdSystemGroup.size(), reportHtml);
+
+        for (System system : systems) {
+            // to mimic - Find history for system by uuid
+            systemsByUuid = holderIRepositories.getSystemRepository().findByUuid(system.getUuid().toString());
+            for (System systemByUuid : systemsByUuid) {
+                setIdSystem.add(systemByUuid.getId());
+            }
+        }
+
+        prepareLogReport("readDataReachable, check, after system,      setIdSystem.size:      " + setIdSystem.size(), reportHtml);
+
+        for (Subsystem subsystem : subsystems) {
+            // to mimic - Find history for subsystem by uuid
+            subsystemsByUuid = holderIRepositories.getSubsystemRepository().findByUuid(subsystem.getUuid().toString());
+            for (Subsystem subsystemByUuid : subsystemsByUuid) {
+                setIdSubsystem.add(subsystemByUuid.getId());
+            }
+        }
+
+        prepareLogReport("readDataReachable, check, after subsystem,   setIdSubsystem.size:   " + setIdSubsystem.size(), reportHtml);
+
+        for (Discipline discipline : disciplines) {
+            // to mimic - Find history for discipline by uuid
+            disciplinesByUuid = holderIRepositories.getDisciplineRepository().findByUuid(discipline.getUuid().toString());
+            for (Discipline disciplineByUuid : disciplinesByUuid) {
+                setIdDiscipline.add(disciplineByUuid.getId());
+            }
+        }
+
+        prepareLogReport("readDataReachable, check, after discipline,  setIdDiscipline.size:  " + setIdDiscipline.size(), reportHtml);
+
+        for (DeviceGroup deviceGroup : deviceGroups) {
+            // to mimic - Find history for device group by uuid
+            deviceGroupsByUuid = holderIRepositories.getDeviceGroupRepository().findByUuid(deviceGroup.getUuid().toString());
+            for (DeviceGroup deviceGroupByUuid : deviceGroupsByUuid) {
+                setIdDeviceGroup.add(deviceGroupByUuid.getId());
+            }
+        }
+
+        prepareLogReport("readDataReachable, check, after devicegroup, setIdDeviceGroup.size: " + setIdDeviceGroup.size(), reportHtml);
+
+        for (DeviceType deviceType : deviceTypes) {
+            // to mimic - Find history for device type by uuid
+            deviceTypesByUuid = holderIRepositories.getDeviceTypeRepository().findByUuid(deviceType.getUuid().toString());
+            for (DeviceType deviceTypeByUuid : deviceTypesByUuid) {
+                setIdDeviceType.add(deviceTypeByUuid.getId());
+            }
+        }
+
+        prepareLogReport("readDataReachable, check, after devicetype,  setIdDeviceType.size:  " + setIdDeviceType.size(), reportHtml);
+
+        boolean ok = names.size() == setIdName.size()
+                && systemGroups.size() == setIdSystemGroup.size()
+                && systems.size() == setIdSystem.size()
+                && subsystems.size() == setIdSubsystem.size()
+                && disciplines.size() == setIdDiscipline.size()
+                && deviceGroups.size() == setIdDeviceGroup.size()
+                && deviceTypes.size() == setIdDeviceType.size();
+
+        prepareLogReport("readDataReachable, check, after", reportHtml);
+        prepareLogReport("readDataReachable, ok: " + ok, reportHtml);
+
+        return reportHtml.toString();
+    }
+
+    /**
+     * Verify difference between old REST API and new REST API.
+     *
+     * Amount is less in new than in old. Verify that all content in new REST API is in old REST API and that difference is old/obsolete data.
+     *
+     * @return
+     */
+    @GetMapping ("/restapi_oldvsnew")
+    public String readRestApiOldVsNew() {
+        StringBuilder reportHtml = new StringBuilder();
+
+        // prepare old REST API
+
+        List<DeviceRevision> deviceRevisions = deviceRevisionRepository.findAll();
+
+        NameViewProvider nameViewProvider = new NameViewProvider();
+        nameViewProvider.update(deviceRevisions);
+
+        // prepare new REST API
+
+        List<Name> names       = holderIRepositories.getNameRepository().findLatestNotDeleted();
+        List<Name> namesLatest = holderIRepositories.getNameRepository().findLatest();
+
+        prepareLogReport("readRestApiOldVsNew, find data,                 deviceRevisions.size:                                " + deviceRevisions.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, find data,                 nameViewProvider.getNameRevisions.entrySet.size:     " + nameViewProvider.getNameRevisions().entrySet().size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, find data,                 names.size:                                          " + names.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, find data,                 namesLatest.size:                                    " + namesLatest.size(), reportHtml);
+
+        // prepare comparison
+
+        HashMap<Long, DeviceRevision> mapIdDeviceRevision           = new HashMap<>((int)(nameViewProvider.getNameRevisions().entrySet().size()/0.75 + 2));
+        HashMap<Long, DeviceRevision> mapIdDeviceRevisionDifference = new HashMap<>((int)(nameViewProvider.getNameRevisions().entrySet().size()/0.75 + 2));
+        HashMap<Long, UUID>           mapIdUuidDeviceRevision       = new HashMap<>((int)(nameViewProvider.getNameRevisions().entrySet().size()/0.75 + 2));
+        for (Map.Entry<String, DeviceRevision> entry : nameViewProvider.getNameRevisions().entrySet()) {
+            mapIdDeviceRevision.put(entry.getValue().getId(), entry.getValue());
+            mapIdDeviceRevisionDifference.put(entry.getValue().getId(), entry.getValue());
+            mapIdUuidDeviceRevision.put(entry.getValue().getId(), entry.getValue().getDevice().getUuid());
+        }
+
+        HashMap<Long, Name> mapIdName   = new HashMap<>((int)(names.size()/0.75 + 2));
+        for (Name name : names) {
+            mapIdName.put(name.getId(), name);
+        }
+        HashMap<UUID, Name> mapUuidNameLatest = new HashMap<>((int)(namesLatest.size()/0.75 + 2));
+        for (Name name : namesLatest) {
+            mapUuidNameLatest.put(name.getUuid(), name);
+        }
+
+        prepareLogReport("readRestApiOldVsNew, utility,                   mapIdDeviceRevision.size:                            " + mapIdDeviceRevision.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, utility,                   mapIdDeviceRevisionDifference.size:                  " + mapIdDeviceRevisionDifference.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, utility,                   mapIdUuidDeviceRevision.size:                        " + mapIdUuidDeviceRevision.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, utility,                   mapIdName.size:                                      " + mapIdName.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, utility,                   mapUuidNameLatest.size:                              " + mapUuidNameLatest.size(), reportHtml);
+
+        prepareLogReport("readRestApiOldVsNew, check, before", reportHtml);
+
+        // compare old REST API with new REST API
+        // 1. difference
+
+        boolean idInOld = true;
+        int countIdInOld = 0;
+        int countNotIdInOld = 0;
+        for (Name name : names) {
+            idInOld = mapIdDeviceRevisionDifference.containsKey(name.getId());
+            if (idInOld) {
+                countIdInOld++;
+            } else if (!idInOld) {
+                countNotIdInOld++;
+                // break;
+            }
+            mapIdDeviceRevisionDifference.remove(name.getId());
+        }
+
+        prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdDeviceRevision.size:                            " + mapIdDeviceRevision.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdDeviceRevisionDifference.size:                  " + mapIdDeviceRevisionDifference.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdUuidDeviceRevision.size:                        " + mapIdUuidDeviceRevision.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapIdName.size:                                      " + mapIdName.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, check, after difference 1, mapUuidNameLatest.size:                              " + mapUuidNameLatest.size(), reportHtml);
+        prepareLogReport("readRestApiOldVsNew, check, after difference 1, countIdInOld:                                        " + countIdInOld, reportHtml);
+        prepareLogReport("readRestApiOldVsNew, check, after difference 1, countNotIdInOld:                                     " + countNotIdInOld, reportHtml);
+
+        // 2. difference is old/obsolete data
+        //        id corresponding to uuid should not be last in line
+        //        <--> last in line should be deleted
+
+        ArrayList<DeviceRevision> listDeviceRevisionWrong = new ArrayList<>();
+        for (Entry<Long, DeviceRevision> entry : mapIdDeviceRevisionDifference.entrySet()) {
+            UUID uuid = mapIdUuidDeviceRevision.get(entry.getKey());
+            Name name = uuid != null ? mapUuidNameLatest.get(uuid) : null;
+
+            // something may be wrong
+            //     if latest for devicerevision is in names then ok
+            //     else if latest for devicerevision is deleted then ok
+            //     else something is wrong
+            //            if (!latestInLine && !name.isDeleted()) {
+            //     <-->
+            //     name != null && (name.isLatest() || name.isDeleted()) --> ok, else wrong
+            if (!(name != null && (name.isLatest() || name.isDeleted()))) {
+                // something is wrong
+                listDeviceRevisionWrong.add(entry.getValue());
+            }
+        }
+
+        prepareLogReport("readRestApiOldVsNew, check, after difference 2, listDeviceRevisionWrong.size:                        " + listDeviceRevisionWrong.size(), reportHtml);
+
+        boolean ok = (mapIdDeviceRevisionDifference.size() == (nameViewProvider.getNameRevisions().entrySet().size() - names.size()))
+                && (listDeviceRevisionWrong.size() == 0);
+
+        prepareLogReport("readRestApiOldVsNew, check, after", reportHtml);
+        prepareLogReport("readRestApiOldVsNew, ok: " + ok, reportHtml);
+
+        return reportHtml.toString();
+    }
+
+    /**
+     * Utility method for preparing reports for logging purposes.
+     *
+     * @param message
+     * @param reportHtml
+     * @param reportLog
+     */
+    private void prepareLogReport(String message, StringBuilder reportHtml) {
+        if (!StringUtils.isEmpty(message)) {
+            LOGGER.log(Level.INFO, message);
+            reportHtml.append(message + NEW_LINE_BR);
+        }
+    }
+
+}