commit cf12d56147af2a61a58927da0f8191450fafbebe
Author: Jakub Smid <jaksmid@seznam.cz>
Date:   Wed May 11 10:31:23 2022 +0200

    Catalog change
     - one-to-many associations now persist order
     - text for search persists separators
    
    re #9751
    re #9754

diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/AlternativeName.java b/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/AlternativeName.java
deleted file mode 100644
index 051f7f9..0000000
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/AlternativeName.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package cz.zcu.kiv.backendapi.alternativename;
-
-import cz.zcu.kiv.backendapi.catalog.CatalogItem;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-
-import javax.persistence.*;
-
-/**
- * Alternative name entity representing alternative name of catalog item
- */
-@Getter
-@Setter
-@NoArgsConstructor
-@AllArgsConstructor
-@Entity
-@Table(name = "alternative_names")
-@IdClass(AlternativeNamePK.class)
-public class AlternativeName {
-    /**
-     * Name, serves as ID
-     */
-    @Id
-    private String name;
-
-    /**
-     * Catalog entity
-     */
-    @ManyToOne(fetch = FetchType.LAZY)
-    @Id
-    @JoinColumn(name = "catalog_item_id")
-    private CatalogItem catalogItem;
-}
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/AlternativeNamePK.java b/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/AlternativeNamePK.java
deleted file mode 100644
index 0b8b491..0000000
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/AlternativeNamePK.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package cz.zcu.kiv.backendapi.alternativename;
-
-import lombok.AllArgsConstructor;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-import java.util.UUID;
-
-/**
- * Class representing alternative name primary key
- */
-@EqualsAndHashCode
-@AllArgsConstructor
-@NoArgsConstructor
-public class AlternativeNamePK implements Serializable {
-    /**
-     * Name
-     */
-    private String name;
-
-    /**
-     * ID of catalog item
-     */
-    private UUID catalogItem;
-}
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/CatalogItemName.java b/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/CatalogItemName.java
new file mode 100644
index 0000000..95f1509
--- /dev/null
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/CatalogItemName.java
@@ -0,0 +1,40 @@
+package cz.zcu.kiv.backendapi.alternativename;
+
+import cz.zcu.kiv.backendapi.catalog.CatalogItem;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import javax.persistence.*;
+
+/**
+ * Catalog item name entity representing alternative name of catalog item
+ */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
+@Entity
+@Table(name = "catalog_item_names")
+@IdClass(CatalogItemNamePK.class)
+public class CatalogItemName {
+    /**
+     * Name, serves as ID
+     */
+    @Id
+    private String name;
+
+    /**
+     * Catalog item
+     */
+    @ManyToOne(fetch = FetchType.LAZY)
+    @Id
+    @JoinColumn(name = "catalog_item_id")
+    private CatalogItem catalogItem;
+
+    /**
+     * Order of name for given catalog item
+     */
+    private int entryOrder;
+}
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/CatalogItemNamePK.java b/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/CatalogItemNamePK.java
new file mode 100644
index 0000000..0fd219e
--- /dev/null
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/alternativename/CatalogItemNamePK.java
@@ -0,0 +1,26 @@
+package cz.zcu.kiv.backendapi.alternativename;
+
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+/**
+ * Class representing catalog item name primary key
+ */
+@EqualsAndHashCode
+@AllArgsConstructor
+@NoArgsConstructor
+public class CatalogItemNamePK implements Serializable {
+    /**
+     * Name
+     */
+    private String name;
+
+    /**
+     * ID of catalog item
+     */
+    private UUID catalogItem;
+}
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/bibliography/Bibliography.java b/backend/src/main/java/cz/zcu/kiv/backendapi/bibliography/Bibliography.java
index 0758a7a..7bd92e7 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/bibliography/Bibliography.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/bibliography/Bibliography.java
@@ -29,4 +29,9 @@ public class Bibliography {
     @Id
     @JoinColumn(name = "catalog_item_id")
     private CatalogItem catalogItem;
+
+    /**
+     * Order of bibliography for given catalog item
+     */
+    private int entryOrder;
 }
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItem.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItem.java
index 41df83a..2418913 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItem.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItem.java
@@ -1,6 +1,6 @@
 package cz.zcu.kiv.backendapi.catalog;
 
-import cz.zcu.kiv.backendapi.alternativename.AlternativeName;
+import cz.zcu.kiv.backendapi.alternativename.CatalogItemName;
 import cz.zcu.kiv.backendapi.bibliography.Bibliography;
 import cz.zcu.kiv.backendapi.country.Country;
 import cz.zcu.kiv.backendapi.type.Type;
@@ -16,12 +16,13 @@ import org.hibernate.annotations.LazyCollectionOption;
 
 import javax.persistence.*;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**
- * Catalog entity representing catalog item
+ * Catalog item entity representing catalog item
  */
 @Getter
 @Setter
@@ -73,7 +74,8 @@ public class CatalogItem {
     @OneToMany(mappedBy = "catalogItem", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
     @LazyCollection(LazyCollectionOption.FALSE)
     @Fetch(FetchMode.SUBSELECT)
-    private Set<Bibliography> bibliography = new HashSet<>();
+    @OrderBy("entryOrder")
+    private Set<Bibliography> bibliography = new LinkedHashSet<>(0);
 
     /**
      * Countries
@@ -81,7 +83,8 @@ public class CatalogItem {
     @OneToMany(mappedBy = "catalogItem", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
     @LazyCollection(LazyCollectionOption.FALSE)
     @Fetch(FetchMode.SUBSELECT)
-    private Set<Country> countries = new HashSet<>();
+    @OrderBy("entryOrder")
+    private Set<Country> countries = new LinkedHashSet<>(0);
 
     /**
      * Written forms
@@ -89,15 +92,17 @@ public class CatalogItem {
     @OneToMany(mappedBy = "catalogItem", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
     @LazyCollection(LazyCollectionOption.FALSE)
     @Fetch(FetchMode.SUBSELECT)
-    private Set<WrittenForm> writtenForms = new HashSet<>();
+    @OrderBy("entryOrder")
+    private Set<WrittenForm> writtenForms = new LinkedHashSet<>(0);
 
     /**
-     * Alternative names
+     * All names
      */
     @OneToMany(mappedBy = "catalogItem", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
     @LazyCollection(LazyCollectionOption.FALSE)
     @Fetch(FetchMode.SUBSELECT)
-    private Set<AlternativeName> alternativeNames = new HashSet<>();
+    @OrderBy("entryOrder")
+    private Set<CatalogItemName> allNames = new LinkedHashSet<>(0);
 
     /**
      * Set of user roles - many-to-many relationship
@@ -113,30 +118,35 @@ public class CatalogItem {
                     @JoinColumn(name = "type", referencedColumnName = "type")
             }
     )
-    private Set<Type> types = new HashSet<>();
+    private Set<Type> types = new LinkedHashSet<>(0);
 
     public CatalogItem(List<String> csvFields) {
+        AtomicInteger counter = new AtomicInteger(1);
 
         this.name = csvFields.get(1);
-        Set<String> stringList = processListField(csvFields.get(2));
-        stringList.add(this.name);
-        this.alternativeNames = stringList.stream().map(s -> new AlternativeName(s, this)).collect(Collectors.toSet());
+        Set<String> stringLinkedSet = new LinkedHashSet<>();
+        stringLinkedSet.add(this.name);
+        stringLinkedSet.addAll(processListField(csvFields.get(2)));
+        this.allNames = stringLinkedSet.stream().map(s -> new CatalogItemName(s, this, counter.getAndIncrement())).collect(Collectors.toCollection(LinkedHashSet::new));
 
         this.certainty = processIntField(csvFields.get(3));
         this.latitude = processDoubleField(csvFields.get(4));
         this.longitude = processDoubleField(csvFields.get(5));
 
-        stringList = processListField(csvFields.get(6));
-        this.writtenForms = stringList.stream().map(s -> new WrittenForm(s, this)).collect(Collectors.toSet());
+        stringLinkedSet = processListField(csvFields.get(6));
+        counter.set(1);
+        this.writtenForms = stringLinkedSet.stream().map(s -> new WrittenForm(s, this, counter.getAndIncrement())).collect(Collectors.toCollection(LinkedHashSet::new));
 
-        stringList = processListField(csvFields.get(7));
-        this.types = stringList.stream().map(Type::new).collect(Collectors.toSet());
+        stringLinkedSet = processListField(csvFields.get(7));
+        this.types = stringLinkedSet.stream().map(Type::new).collect(Collectors.toCollection(LinkedHashSet::new));
 
-        stringList = processListField(csvFields.get(8));
-        this.countries = stringList.stream().map(s -> new Country(s, this)).collect(Collectors.toSet());
+        stringLinkedSet = processListField(csvFields.get(8));
+        counter.set(1);
+        this.countries = stringLinkedSet.stream().map(s -> new Country(s, this, counter.getAndIncrement())).collect(Collectors.toCollection(LinkedHashSet::new));
 
-        stringList = processListField(csvFields.get(9));
-        this.bibliography = stringList.stream().map(s -> new Bibliography(s, this)).collect(Collectors.toSet());
+        stringLinkedSet = processListField(csvFields.get(9));
+        counter.set(1);
+        this.bibliography = stringLinkedSet.stream().map(s -> new Bibliography(s, this, counter.getAndIncrement())).collect(Collectors.toCollection(LinkedHashSet::new));
     }
 
     private Integer processIntField(String field) {
@@ -159,8 +169,8 @@ public class CatalogItem {
 
     private Set<String> processListField(String field) {
         if (field.isEmpty() || field.equals(EMPTY_ENTRY)) {
-            return new HashSet<>();
+            return new LinkedHashSet<>();
         }
-        return Arrays.stream(field.split(",")).map(String::trim).filter(item -> !item.isEmpty()).collect(Collectors.toSet());
+        return Arrays.stream(field.split(",")).map(String::trim).filter(item -> !item.isEmpty()).collect(Collectors.toCollection(LinkedHashSet::new));
     }
 }
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemDto.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemDto.java
index e404aa2..153b86a 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemDto.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemDto.java
@@ -5,8 +5,7 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-import java.util.Collections;
-import java.util.Set;
+import java.util.LinkedHashSet;
 import java.util.UUID;
 
 /**
@@ -28,29 +27,29 @@ public class CatalogItemDto {
     private String name = "";
 
     /**
-     * Alternative names
+     * All names
      */
-    private Set<String> alternativeNames = Collections.emptySet();
+    private LinkedHashSet<String> allNames = new LinkedHashSet<>();
 
     /**
      * Written forms
      */
-    private Set<String> writtenForms = Collections.emptySet();
+    private LinkedHashSet<String> writtenForms = new LinkedHashSet<>();
 
     /**
      * Types
      */
-    private Set<String> types = Collections.emptySet();
+    private LinkedHashSet<String> types = new LinkedHashSet<>();
 
     /**
      * Countries
      */
-    private Set<String> countries = Collections.emptySet();
+    private LinkedHashSet<String> countries = new LinkedHashSet<>();
 
     /**
      * Bibliography
      */
-    private Set<String> bibliography = Collections.emptySet();
+    private LinkedHashSet<String> bibliography = new LinkedHashSet<>();
 
     /**
      * Longitude
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemRepository.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemRepository.java
index 7dc53bc..a617597 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemRepository.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemRepository.java
@@ -19,6 +19,6 @@ public interface CatalogItemRepository extends JpaRepository<CatalogItem, UUID>
      * @param name name
      * @return list of catalog items with given name
      */
-    @Query("SELECT DISTINCT a.catalogItem FROM AlternativeName a WHERE ?1 = a.name")
+    @Query("SELECT DISTINCT a.catalogItem FROM CatalogItemName a WHERE ?1 = a.name")
     List<CatalogItem> getItemsByName(String name);
 }
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImpl.java b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImpl.java
index 9310aa8..0fc8ec2 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImpl.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImpl.java
@@ -1,6 +1,6 @@
 package cz.zcu.kiv.backendapi.catalog;
 
-import cz.zcu.kiv.backendapi.alternativename.AlternativeName;
+import cz.zcu.kiv.backendapi.alternativename.CatalogItemName;
 import cz.zcu.kiv.backendapi.bibliography.Bibliography;
 import cz.zcu.kiv.backendapi.country.Country;
 import cz.zcu.kiv.backendapi.exception.ApiRequestException;
@@ -10,14 +10,13 @@ import cz.zcu.kiv.backendapi.type.Type;
 import cz.zcu.kiv.backendapi.writtenform.WrittenForm;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.UUID;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Predicate;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -140,8 +139,12 @@ public class CatalogItemServiceImpl implements ICatalogItemService {
 
         Set<String> types = typeService.getAllTypesAsString();
 
-        String[] tokens = text.split("\\s+");
+        String[] tokens = text.split("((?<=\\s)|(?=\\s+))");
         for (String token : tokens) {
+            if (StringUtils.isBlank(token)) {
+                highlightedText.append(token);
+                continue;
+            }
             Matcher matcherStart = START_PUNCTUATION_PATTERN.matcher(token);
             Matcher matcherEnd = END_PUNCTUATION_PATTERN.matcher(token);
             String prefix = "";
@@ -162,7 +165,7 @@ public class CatalogItemServiceImpl implements ICatalogItemService {
             }
 
             if (endTextIndex < startTextIndex) {
-                highlightedText.append(prefix).append(" ");
+                highlightedText.append(prefix);
                 continue;
             }
 
@@ -181,9 +184,8 @@ public class CatalogItemServiceImpl implements ICatalogItemService {
                     foundCatalogItems.add(foundItems.stream().map(this::convertEntityToDto).collect(Collectors.toList()));
                 }
             }
-            highlightedText.append(prefix).append(textToFind).append(suffix).append(" ");
+            highlightedText.append(prefix).append(textToFind).append(suffix);
         }
-        highlightedText.setLength(highlightedText.length() - 1);
 
         pathDto.setText(highlightedText.toString());
         pathDto.setFoundCatalogItems(foundCatalogItems);
@@ -207,7 +209,7 @@ public class CatalogItemServiceImpl implements ICatalogItemService {
 
         Predicate<CatalogItem> predicateType = i -> finalType.equals("") || i.getTypes().stream().anyMatch(t -> patternType.matcher(t.getType()).matches());
         Predicate<CatalogItem> predicateCountry = i -> finalCountry.equals("") || i.getCountries().stream().anyMatch(t -> patternCountry.matcher(t.getName()).matches());
-        Predicate<CatalogItem> predicateName = i -> finalName.equals("") || patternName.matcher(i.getName()).matches() || i.getAlternativeNames().stream().anyMatch(t -> patternName.matcher(t.getName()).matches());
+        Predicate<CatalogItem> predicateName = i -> finalName.equals("") || patternName.matcher(i.getName()).matches() || i.getAllNames().stream().anyMatch(t -> patternName.matcher(t.getName()).matches());
         Predicate<CatalogItem> predicateWrittenForm = i -> finalWrittenForm.equals("") || i.getWrittenForms().stream().anyMatch(t -> patternWrittenForm.matcher(t.getForm()).matches());
 
         catalogItems = catalogItems.stream().filter(predicateName.and(predicateCountry).and(predicateType).and(predicateWrittenForm)).collect(Collectors.toList());
@@ -215,9 +217,9 @@ public class CatalogItemServiceImpl implements ICatalogItemService {
     }
 
     /**
-     * Saves catalog entity to database
+     * Saves catalog item to database
      *
-     * @param catalogItem catalog entity
+     * @param catalogItem catalog item
      */
     private void saveCatalogEntity(CatalogItem catalogItem) {
         for (Type type : catalogItem.getTypes()) {
@@ -235,6 +237,8 @@ public class CatalogItemServiceImpl implements ICatalogItemService {
      * @param catalogItem    catalog item entity
      */
     private void convertDtoToEntity(CatalogItemDto catalogItemDto, CatalogItem catalogItem) {
+        AtomicInteger counter = new AtomicInteger(1);
+
         catalogItem.setName(catalogItemDto.getName());
         catalogItem.setCertainty(catalogItemDto.getCertainty());
         catalogItem.setLatitude(catalogItemDto.getLatitude());
@@ -242,24 +246,29 @@ public class CatalogItemServiceImpl implements ICatalogItemService {
 
         catalogItem.getBibliography().clear();
         catalogItem.getBibliography().addAll(catalogItemDto.getBibliography()
-                .stream().map(s -> new Bibliography(s, catalogItem)).collect(Collectors.toSet()));
+                .stream().map(s -> new Bibliography(s, catalogItem, counter.getAndIncrement())).collect(Collectors.toCollection(LinkedHashSet::new)));
 
         catalogItem.getTypes().clear();
         catalogItem.getTypes().addAll(catalogItemDto.getTypes()
-                .stream().map(Type::new).collect(Collectors.toSet()));
+                .stream().map(Type::new).collect(Collectors.toCollection(LinkedHashSet::new)));
 
         catalogItem.getCountries().clear();
+        counter.set(1);
         catalogItem.getCountries().addAll(catalogItemDto.getCountries()
-                .stream().map(s -> new Country(s, catalogItem)).collect(Collectors.toSet()));
+                .stream().map(s -> new Country(s, catalogItem, counter.getAndIncrement())).collect(Collectors.toCollection(LinkedHashSet::new)));
 
-        catalogItemDto.getAlternativeNames().add(catalogItemDto.getName());
-        catalogItem.getAlternativeNames().clear();
-        catalogItem.getAlternativeNames().addAll(catalogItemDto.getAlternativeNames()
-                .stream().map(s -> new AlternativeName(s, catalogItem)).collect(Collectors.toSet()));
+        catalogItem.getAllNames().clear();
+        counter.set(1);
+        Set<String> allNames = new LinkedHashSet<>();
+        allNames.add(catalogItemDto.getName());
+        allNames.addAll(catalogItemDto.getAllNames());
+        catalogItem.getAllNames().addAll(allNames
+                .stream().map(s -> new CatalogItemName(s, catalogItem, counter.getAndIncrement())).collect(Collectors.toCollection(LinkedHashSet::new)));
 
         catalogItem.getWrittenForms().clear();
+        counter.set(1);
         catalogItem.getWrittenForms().addAll(catalogItemDto.getWrittenForms()
-                .stream().map(s -> new WrittenForm(s, catalogItem)).collect(Collectors.toSet()));
+                .stream().map(s -> new WrittenForm(s, catalogItem, counter.getAndIncrement())).collect(Collectors.toCollection(LinkedHashSet::new)));
 
         catalogItem.setDescription(catalogItemDto.getDescription());
     }
@@ -278,15 +287,15 @@ public class CatalogItemServiceImpl implements ICatalogItemService {
         catalogItemDto.setLongitude(catalogItem.getLongitude());
         catalogItemDto.setCertainty(catalogItem.getCertainty());
         catalogItemDto.setBibliography(catalogItem.getBibliography()
-                .stream().map(Bibliography::getSource).collect(Collectors.toSet()));
+                .stream().map(Bibliography::getSource).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto.setTypes(catalogItem.getTypes()
-                .stream().map(Type::getType).collect(Collectors.toSet()));
+                .stream().map(Type::getType).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto.setCountries(catalogItem.getCountries()
-                .stream().map(Country::getName).collect(Collectors.toSet()));
-        catalogItemDto.setAlternativeNames(catalogItem.getAlternativeNames()
-                .stream().map(AlternativeName::getName).collect(Collectors.toSet()));
+                .stream().map(Country::getName).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setAllNames(catalogItem.getAllNames()
+                .stream().map(CatalogItemName::getName).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto.setWrittenForms(catalogItem.getWrittenForms()
-                .stream().map(WrittenForm::getForm).collect(Collectors.toSet()));
+                .stream().map(WrittenForm::getForm).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto.setDescription(catalogItem.getDescription());
         return catalogItemDto;
     }
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/country/Country.java b/backend/src/main/java/cz/zcu/kiv/backendapi/country/Country.java
index 5415f95..38edf49 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/country/Country.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/country/Country.java
@@ -29,4 +29,9 @@ public class Country {
     @Id
     @JoinColumn(name = "catalog_item_id")
     private CatalogItem catalogItem;
+
+    /**
+     * Order of country for given catalog item
+     */
+    private int entryOrder;
 }
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/writtenform/WrittenForm.java b/backend/src/main/java/cz/zcu/kiv/backendapi/writtenform/WrittenForm.java
index ea28745..bb8d860 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/writtenform/WrittenForm.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/writtenform/WrittenForm.java
@@ -29,4 +29,9 @@ public class WrittenForm {
     @Id
     @JoinColumn(name = "catalog_item_id")
     private CatalogItem catalogItem;
+
+    /**
+     * Order of written form for given catalog item
+     */
+    private int entryOrder;
 }
diff --git a/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemRepositoryTest.java b/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemRepositoryTest.java
index e3c7f20..b7dddfc 100644
--- a/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemRepositoryTest.java
+++ b/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemRepositoryTest.java
@@ -1,12 +1,14 @@
 package cz.zcu.kiv.backendapi.catalog;
 
-import cz.zcu.kiv.backendapi.alternativename.AlternativeName;
+import cz.zcu.kiv.backendapi.alternativename.CatalogItemName;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
 
+import java.util.LinkedHashSet;
 import java.util.List;
-import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -37,15 +39,15 @@ class CatalogItemRepositoryTest {
         catalogItem1.setName(nameFirst);
 
         catalogItem2.setName(nameSecond);
-        catalogItem2.setAlternativeNames(Set.of(new AlternativeName(nameTwelve, catalogItem2), new AlternativeName(nameThird, catalogItem2)));
+        catalogItem2.setAllNames(Stream.of(new CatalogItemName(nameTwelve, catalogItem2, 1), new CatalogItemName(nameThird, catalogItem2, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
 
         catalogItem3.setName(nameThird);
-        catalogItem3.setAlternativeNames(Set.of(new AlternativeName(nameTwentyUpper, catalogItem3), new AlternativeName(nameSedond, catalogItem3)));
+        catalogItem3.setAllNames(Stream.of(new CatalogItemName(nameTwentyUpper, catalogItem3, 1), new CatalogItemName(nameSedond, catalogItem3, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
 
-        catalogItem4.setAlternativeNames(Set.of(new AlternativeName(nameTwelve, catalogItem4), new AlternativeName(nameFirstUpper, catalogItem4)));
+        catalogItem4.setAllNames(Stream.of(new CatalogItemName(nameTwelve, catalogItem4, 1), new CatalogItemName(nameFirstUpper, catalogItem4, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
 
         catalogItem5.setName(nameSedond);
-        catalogItem5.setAlternativeNames(Set.of(new AlternativeName(nameThird, catalogItem5)));
+        catalogItem5.setAllNames(Stream.of(new CatalogItemName(nameThird, catalogItem5, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
 
         underTest.saveAll(List.of(catalogItem1, catalogItem2, catalogItem3, catalogItem4, catalogItem5));
 
diff --git a/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImplFilterTest.java b/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImplFilterTest.java
index 21ed37b..bcd3287 100644
--- a/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImplFilterTest.java
+++ b/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImplFilterTest.java
@@ -1,6 +1,6 @@
 package cz.zcu.kiv.backendapi.catalog;
 
-import cz.zcu.kiv.backendapi.alternativename.AlternativeName;
+import cz.zcu.kiv.backendapi.alternativename.CatalogItemName;
 import cz.zcu.kiv.backendapi.country.Country;
 import cz.zcu.kiv.backendapi.type.Type;
 import cz.zcu.kiv.backendapi.type.TypeServiceImpl;
@@ -11,10 +11,11 @@ import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
-import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -92,40 +93,54 @@ class CatalogItemServiceImplFilterTest {
         catalogItem5.setId(catalogItemId5);
 
         catalogItem1.setName(nameFirst);
-        catalogItem1.setTypes(Set.of(typeCountry, typeCity));
-        catalogItem1.setCountries(Set.of(new Country(countryAaa, catalogItem1), new Country(countryDcd, catalogItem1)));
-        catalogItem1.setWrittenForms(Set.of(new WrittenForm(writtenForm, catalogItem1)));
+        catalogItem1.setTypes(Stream.of(typeCountry, typeCity).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem1.setCountries(Stream.of(new Country(countryAaa, catalogItem1, 1), new Country(countryDcd, catalogItem1, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem1.setWrittenForms(Stream.of(new WrittenForm(writtenForm, catalogItem1, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
 
-        catalogItemDto1 = new CatalogItemDto(catalogItemId1, nameFirst, Collections.emptySet(), Set.of(writtenForm), Set.of(country, city), Set.of(countryAaa, countryDcd), Collections.emptySet(), null, null, null, "");
+        catalogItemDto1 = new CatalogItemDto(catalogItemId1, nameFirst, new LinkedHashSet<>(), Stream.of(writtenForm).collect(Collectors.toCollection(LinkedHashSet::new)),
+                Stream.of(country, city).collect(Collectors.toCollection(LinkedHashSet::new)), Stream.of(countryAaa, countryDcd).collect(Collectors.toCollection(LinkedHashSet::new)),
+                new LinkedHashSet<>(), null, null, null, "");
 
         catalogItem2.setName(nameSecond);
-        catalogItem2.setAlternativeNames(Set.of(new AlternativeName(nameTwelve, catalogItem2), new AlternativeName(nameThird, catalogItem2)));
-        catalogItem2.setTypes(Set.of(typeCountry, typeCityUpper));
-        catalogItem2.setCountries(Set.of(new Country(countryAaa, catalogItem2), new Country(countryBbb, catalogItem2)));
-        catalogItem2.setWrittenForms(Set.of(new WrittenForm(writtenFormUpper, catalogItem2)));
+        catalogItem2.setAllNames(Stream.of(new CatalogItemName(nameTwelve, catalogItem2, 1), new CatalogItemName(nameThird, catalogItem2, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem2.setTypes(Stream.of(typeCountry, typeCityUpper).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem2.setCountries(Stream.of(new Country(countryAaa, catalogItem2, 1), new Country(countryBbb, catalogItem2, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem2.setWrittenForms(Stream.of(new WrittenForm(writtenFormUpper, catalogItem2, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
 
-        catalogItemDto2 = new CatalogItemDto(catalogItemId2, nameSecond, Set.of(nameTwelve, nameThird), Set.of(writtenFormUpper), Set.of(country, cityUpper), Set.of(countryAaa, countryBbb), Collections.emptySet(), null, null, null, "");
+        catalogItemDto2 = new CatalogItemDto(catalogItemId2, nameSecond, Stream.of(nameTwelve, nameThird).collect(Collectors.toCollection(LinkedHashSet::new)),
+                Stream.of(writtenFormUpper).collect(Collectors.toCollection(LinkedHashSet::new)), Stream.of(country, cityUpper).collect(Collectors.toCollection(LinkedHashSet::new)),
+                Stream.of(countryAaa, countryBbb).collect(Collectors.toCollection(LinkedHashSet::new)), new LinkedHashSet<>(),
+                null, null, null, "");
 
         catalogItem3.setName(nameThird);
-        catalogItem3.setAlternativeNames(Set.of(new AlternativeName(nameTwentyUpper, catalogItem3), new AlternativeName(nameSedond, catalogItem3)));
-        catalogItem3.setTypes(Set.of(typeCountri, typeCapitalCity));
-        catalogItem3.setCountries(Set.of(new Country(countryAaaUpper, catalogItem3), new Country(countryCcc, catalogItem3)));
-        catalogItem3.setWrittenForms(Set.of(new WrittenForm(writtenFormForOr, catalogItem3)));
-
-        catalogItemDto3 = new CatalogItemDto(catalogItemId3, nameThird, Set.of(nameTwentyUpper, nameSedond), Set.of(writtenFormForOr), Set.of(countri, capitalCityNew), Set.of(countryAaaUpper, countryCcc), Collections.emptySet(), null, null, null, "");
-
-        catalogItem4.setAlternativeNames(Set.of(new AlternativeName(nameTwelve, catalogItem4), new AlternativeName(nameFirstUpper, catalogItem4)));
-        catalogItem4.setTypes(Set.of(typeCountri, typeCountry));
-        catalogItem4.setCountries(Set.of(new Country(countryBccb, catalogItem4), new Country(countryDdd, catalogItem4)));
-        catalogItem4.setWrittenForms(Set.of(new WrittenForm(writtenForm, catalogItem4), new WrittenForm(writtenFormForOr, catalogItem4)));
-
-        catalogItemDto4 = new CatalogItemDto(catalogItemId4, "", Set.of(nameTwelve, nameFirstUpper), Set.of(writtenForm, writtenFormForOr), Set.of(countri, country), Set.of(countryBccb, countryDdd), Collections.emptySet(), null, null, null, "");
+        catalogItem3.setAllNames(Stream.of(new CatalogItemName(nameTwentyUpper, catalogItem3, 1), new CatalogItemName(nameSedond, catalogItem3, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem3.setTypes(Stream.of(typeCountri, typeCapitalCity).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem3.setCountries(Stream.of(new Country(countryAaaUpper, catalogItem3, 1), new Country(countryCcc, catalogItem3, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem3.setWrittenForms(Stream.of(new WrittenForm(writtenFormForOr, catalogItem3, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+
+        catalogItemDto3 = new CatalogItemDto(catalogItemId3, nameThird, Stream.of(nameTwentyUpper, nameSedond).collect(Collectors.toCollection(LinkedHashSet::new)),
+                Stream.of(writtenFormForOr).collect(Collectors.toCollection(LinkedHashSet::new)), Stream.of(countri, capitalCityNew).collect(Collectors.toCollection(LinkedHashSet::new)),
+                Stream.of(countryAaaUpper, countryCcc).collect(Collectors.toCollection(LinkedHashSet::new)), new LinkedHashSet<>(),
+                null, null, null, "");
+
+        catalogItem4.setAllNames(Stream.of(new CatalogItemName(nameTwelve, catalogItem4, 1), new CatalogItemName(nameFirstUpper, catalogItem4, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem4.setTypes(Stream.of(typeCountri, typeCountry).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem4.setCountries(Stream.of(new Country(countryBccb, catalogItem4, 1), new Country(countryDdd, catalogItem4, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem4.setWrittenForms(Stream.of(new WrittenForm(writtenForm, catalogItem4, 1), new WrittenForm(writtenFormForOr, catalogItem4, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
+
+        catalogItemDto4 = new CatalogItemDto(catalogItemId4, "", Stream.of(nameTwelve, nameFirstUpper).collect(Collectors.toCollection(LinkedHashSet::new)),
+                Stream.of(writtenForm, writtenFormForOr).collect(Collectors.toCollection(LinkedHashSet::new)), Stream.of(countri, country).collect(Collectors.toCollection(LinkedHashSet::new)),
+                Stream.of(countryBccb, countryDdd).collect(Collectors.toCollection(LinkedHashSet::new)), new LinkedHashSet<>(),
+                null, null, null, "");
 
         catalogItem5.setName(nameSedond);
-        catalogItem5.setAlternativeNames(Set.of(new AlternativeName(nameThird, catalogItem5)));
-        catalogItem5.setTypes(Set.of(typeCountri));
+        catalogItem5.setAllNames(Stream.of(new CatalogItemName(nameThird, catalogItem5, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem5.setTypes(Stream.of(typeCountri).collect(Collectors.toCollection(LinkedHashSet::new)));
 
-        catalogItemDto5 = new CatalogItemDto(catalogItemId5, nameSedond, Set.of(nameThird), Collections.emptySet(), Set.of(countri), Collections.emptySet(), Collections.emptySet(), null, null, null, "");
+        catalogItemDto5 = new CatalogItemDto(catalogItemId5, nameSedond, Stream.of(nameThird).collect(Collectors.toCollection(LinkedHashSet::new)),
+                new LinkedHashSet<>(), Stream.of(countri).collect(Collectors.toCollection(LinkedHashSet::new)),
+                new LinkedHashSet<>(), new LinkedHashSet<>(),
+                null, null, null, "");
 
         given(catalogItemRepository.findAll()).willReturn(List.of(catalogItem1, catalogItem2, catalogItem3, catalogItem4, catalogItem5));
     }
diff --git a/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImplTest.java b/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImplTest.java
index 3506f77..5802958 100644
--- a/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImplTest.java
+++ b/backend/src/test/java/cz/zcu/kiv/backendapi/catalog/CatalogItemServiceImplTest.java
@@ -1,6 +1,6 @@
 package cz.zcu.kiv.backendapi.catalog;
 
-import cz.zcu.kiv.backendapi.alternativename.AlternativeName;
+import cz.zcu.kiv.backendapi.alternativename.CatalogItemName;
 import cz.zcu.kiv.backendapi.bibliography.Bibliography;
 import cz.zcu.kiv.backendapi.country.Country;
 import cz.zcu.kiv.backendapi.exception.ApiRequestException;
@@ -50,22 +50,22 @@ class CatalogItemServiceImplTest {
 
         CatalogItem catalogItem = new CatalogItem();
         catalogItem.setName("aaacbbbbbbbaa");
-        catalogItem.setBibliography(Set.of(new Bibliography("bibl", catalogItem)));
-        catalogItem.setTypes(Set.of(type));
-        catalogItem.setAlternativeNames(Set.of(new AlternativeName("altName", catalogItem)));
-        catalogItem.setCountries(Set.of(new Country("aaaabbaa", catalogItem)));
-        catalogItem.setWrittenForms(Set.of(new WrittenForm("written", catalogItem)));
+        catalogItem.setBibliography(Stream.of(new Bibliography("bibl", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setTypes(Stream.of(type).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setAllNames(Stream.of(new CatalogItemName("altName", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setCountries(Stream.of(new Country("aaaabbaa", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setWrittenForms(Stream.of(new WrittenForm("written", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem.setCertainty(0);
         catalogItem.setLatitude(0.1);
         catalogItem.setLongitude(0.2);
 
         CatalogItem catalogItem2 = new CatalogItem();
         catalogItem2.setName("name");
-        catalogItem2.setBibliography(Set.of(new Bibliography("bibl", catalogItem2)));
-        catalogItem2.setTypes(Set.of(type));
-        catalogItem2.setAlternativeNames(Set.of(new AlternativeName("aaaabbbbbbaa", catalogItem2)));
-        catalogItem2.setCountries(Set.of(new Country("aaaabbcccefaa", catalogItem2)));
-        catalogItem2.setWrittenForms(Set.of(new WrittenForm("written", catalogItem2)));
+        catalogItem2.setBibliography(Stream.of(new Bibliography("bibl", catalogItem2, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem2.setTypes(Stream.of(type).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem2.setAllNames(Stream.of(new CatalogItemName("aaaabbbbbbaa", catalogItem2, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem2.setCountries(Stream.of(new Country("aaaabbcccefaa", catalogItem2, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem2.setWrittenForms(Stream.of(new WrittenForm("written", catalogItem2, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem2.setCertainty(1);
         catalogItem2.setLatitude(1.1);
         catalogItem2.setLongitude(1.2);
@@ -88,11 +88,11 @@ class CatalogItemServiceImplTest {
         // given
         CatalogItemDto catalogItemDto = new CatalogItemDto();
         catalogItemDto.setName("name");
-        catalogItemDto.setBibliography(Stream.of("bibl").collect(Collectors.toSet()));
-        catalogItemDto.setTypes(Stream.of("type").collect(Collectors.toSet()));
-        catalogItemDto.setAlternativeNames(Stream.of("altName").collect(Collectors.toSet()));
-        catalogItemDto.setCountries(Stream.of("country").collect(Collectors.toSet()));
-        catalogItemDto.setWrittenForms(Stream.of("written").collect(Collectors.toSet()));
+        catalogItemDto.setBibliography(Stream.of("bibl").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setTypes(Stream.of("type").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setAllNames(Stream.of("altName").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setCountries(Stream.of("country").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setWrittenForms(Stream.of("written").collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto.setCertainty(0);
         catalogItemDto.setLatitude(0.1);
         catalogItemDto.setLongitude(0.2);
@@ -102,11 +102,11 @@ class CatalogItemServiceImplTest {
 
         CatalogItem catalogItem = new CatalogItem();
         catalogItem.setName("name");
-        catalogItem.setBibliography(Stream.of(new Bibliography("bibl", catalogItem)).collect(Collectors.toSet()));
-        catalogItem.setTypes(Stream.of(type).collect(Collectors.toSet()));
-        catalogItem.setAlternativeNames(Stream.of(new AlternativeName("altName", catalogItem), new AlternativeName("name", catalogItem)).collect(Collectors.toSet()));
-        catalogItem.setCountries(Stream.of(new Country("country", catalogItem)).collect(Collectors.toSet()));
-        catalogItem.setWrittenForms(Stream.of(new WrittenForm("written", catalogItem)).collect(Collectors.toSet()));
+        catalogItem.setBibliography(Stream.of(new Bibliography("bibl", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setTypes(Stream.of(type).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setAllNames(Stream.of(new CatalogItemName("altName", catalogItem, 1), new CatalogItemName("name", catalogItem, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setCountries(Stream.of(new Country("country", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setWrittenForms(Stream.of(new WrittenForm("written", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem.setCertainty(0);
         catalogItem.setLatitude(0.1);
         catalogItem.setLongitude(0.2);
@@ -129,7 +129,7 @@ class CatalogItemServiceImplTest {
         assertThat(capturedItem.getLongitude()).isEqualTo(catalogItem.getLongitude());
         assertThat(capturedItem.getLatitude()).isEqualTo(catalogItem.getLatitude());
         assertThat(capturedItem.getCertainty()).isEqualTo(catalogItem.getCertainty());
-        assertThat(capturedItem.getAlternativeNames().size()).isEqualTo(catalogItem.getAlternativeNames().size());
+        assertThat(capturedItem.getAllNames().size()).isEqualTo(catalogItem.getAllNames().size());
         assertThat(capturedItem.getBibliography().size()).isEqualTo(catalogItem.getBibliography().size());
         assertThat(capturedItem.getCountries().size()).isEqualTo(catalogItem.getCountries().size());
         assertThat(capturedItem.getWrittenForms().size()).isEqualTo(catalogItem.getWrittenForms().size());
@@ -177,11 +177,11 @@ class CatalogItemServiceImplTest {
 
         CatalogItemDto catalogItemDto = new CatalogItemDto();
         catalogItemDto.setName("name");
-        catalogItemDto.setBibliography(Stream.of("bibl").collect(Collectors.toSet()));
-        catalogItemDto.setTypes(Stream.of("type").collect(Collectors.toSet()));
-        catalogItemDto.setAlternativeNames(Stream.of("altName").collect(Collectors.toSet()));
-        catalogItemDto.setCountries(Stream.of("country").collect(Collectors.toSet()));
-        catalogItemDto.setWrittenForms(Stream.of("written").collect(Collectors.toSet()));
+        catalogItemDto.setBibliography(Stream.of("bibl").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setTypes(Stream.of("type").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setAllNames(Stream.of("altName").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setCountries(Stream.of("country").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setWrittenForms(Stream.of("written").collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto.setCertainty(0);
         catalogItemDto.setLatitude(0.1);
         catalogItemDto.setLongitude(0.2);
@@ -193,11 +193,11 @@ class CatalogItemServiceImplTest {
         CatalogItem catalogItem = new CatalogItem();
         catalogItem.setId(id);
         catalogItem.setName("name");
-        catalogItem.setBibliography(Stream.of(new Bibliography("bibl", catalogItem)).collect(Collectors.toSet()));
-        catalogItem.setTypes(Stream.of(type).collect(Collectors.toSet()));
-        catalogItem.setAlternativeNames(Stream.of(new AlternativeName("altName", catalogItem)).collect(Collectors.toSet()));
-        catalogItem.setCountries(Stream.of(new Country("country", catalogItem)).collect(Collectors.toSet()));
-        catalogItem.setWrittenForms(Stream.of(new WrittenForm("written", catalogItem)).collect(Collectors.toSet()));
+        catalogItem.setBibliography(Stream.of(new Bibliography("bibl", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setTypes(Stream.of(type).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setAllNames(Stream.of(new CatalogItemName("altName", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setCountries(Stream.of(new Country("country", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItem.setWrittenForms(Stream.of(new WrittenForm("written", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem.setCertainty(0);
         catalogItem.setLatitude(0.1);
         catalogItem.setLongitude(0.2);
@@ -206,11 +206,11 @@ class CatalogItemServiceImplTest {
         CatalogItem oldCatalogItem = new CatalogItem();
         oldCatalogItem.setId(id);
         oldCatalogItem.setName("old");
-        oldCatalogItem.setBibliography(Stream.of(new Bibliography("old", oldCatalogItem)).collect(Collectors.toSet()));
-        oldCatalogItem.setTypes(Stream.of(typeOld).collect(Collectors.toSet()));
-        oldCatalogItem.setAlternativeNames(Stream.of(new AlternativeName("old", oldCatalogItem)).collect(Collectors.toSet()));
-        oldCatalogItem.setCountries(Stream.of(new Country("old", oldCatalogItem)).collect(Collectors.toSet()));
-        oldCatalogItem.setWrittenForms(Stream.of(new WrittenForm("old", catalogItem)).collect(Collectors.toSet()));
+        oldCatalogItem.setBibliography(Stream.of(new Bibliography("old", oldCatalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        oldCatalogItem.setTypes(Stream.of(typeOld).collect(Collectors.toCollection(LinkedHashSet::new)));
+        oldCatalogItem.setAllNames(Stream.of(new CatalogItemName("old", oldCatalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        oldCatalogItem.setCountries(Stream.of(new Country("old", oldCatalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
+        oldCatalogItem.setWrittenForms(Stream.of(new WrittenForm("old", catalogItem, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
         oldCatalogItem.setCertainty(10);
         oldCatalogItem.setLatitude(10.1);
         oldCatalogItem.setLongitude(10.2);
@@ -236,13 +236,13 @@ class CatalogItemServiceImplTest {
         assertThat(capturedCatalogItem.getLatitude()).isEqualTo(catalogItem.getLatitude());
         assertThat(capturedCatalogItem.getLongitude()).isEqualTo(catalogItem.getLongitude());
         assertThat(capturedCatalogItem.getDescription()).isEqualTo(catalogItem.getDescription());
-        assertThat(capturedCatalogItem.getTypes().stream().map(Type::getType).collect(Collectors.toSet())).isEqualTo(catalogItem.getTypes().stream().map(Type::getType).collect(Collectors.toSet()));
-        Set<String> alternativeNamesEntity = catalogItem.getAlternativeNames().stream().map(AlternativeName::getName).collect(Collectors.toSet());
+        assertThat(capturedCatalogItem.getTypes().stream().map(Type::getType).collect(Collectors.toSet())).isEqualTo(catalogItem.getTypes().stream().map(Type::getType).collect(Collectors.toCollection(LinkedHashSet::new)));
+        Set<String> alternativeNamesEntity = catalogItem.getAllNames().stream().map(CatalogItemName::getName).collect(Collectors.toCollection(LinkedHashSet::new));
         alternativeNamesEntity.add(catalogItem.getName());
-        assertThat(capturedCatalogItem.getAlternativeNames().stream().map(AlternativeName::getName).collect(Collectors.toSet())).isEqualTo(alternativeNamesEntity);
-        assertThat(capturedCatalogItem.getCountries().stream().map(Country::getName).collect(Collectors.toSet())).isEqualTo(catalogItem.getCountries().stream().map(Country::getName).collect(Collectors.toSet()));
-        assertThat(capturedCatalogItem.getBibliography().stream().map(Bibliography::getSource).collect(Collectors.toSet())).isEqualTo(catalogItem.getBibliography().stream().map(Bibliography::getSource).collect(Collectors.toSet()));
-        assertThat(capturedCatalogItem.getWrittenForms().stream().map(WrittenForm::getForm).collect(Collectors.toSet())).isEqualTo(catalogItem.getWrittenForms().stream().map(WrittenForm::getForm).collect(Collectors.toSet()));
+        assertThat(capturedCatalogItem.getAllNames().stream().map(CatalogItemName::getName).collect(Collectors.toSet())).isEqualTo(alternativeNamesEntity);
+        assertThat(capturedCatalogItem.getCountries().stream().map(Country::getName).collect(Collectors.toSet())).isEqualTo(catalogItem.getCountries().stream().map(Country::getName).collect(Collectors.toCollection(LinkedHashSet::new)));
+        assertThat(capturedCatalogItem.getBibliography().stream().map(Bibliography::getSource).collect(Collectors.toSet())).isEqualTo(catalogItem.getBibliography().stream().map(Bibliography::getSource).collect(Collectors.toCollection(LinkedHashSet::new)));
+        assertThat(capturedCatalogItem.getWrittenForms().stream().map(WrittenForm::getForm).collect(Collectors.toSet())).isEqualTo(catalogItem.getWrittenForms().stream().map(WrittenForm::getForm).collect(Collectors.toCollection(LinkedHashSet::new)));
     }
 
     @Test
@@ -252,11 +252,11 @@ class CatalogItemServiceImplTest {
 
         CatalogItemDto catalogItemDto = new CatalogItemDto();
         catalogItemDto.setName("name");
-        catalogItemDto.setBibliography(Set.of("bibl"));
-        catalogItemDto.setTypes(Set.of("type"));
-        catalogItemDto.setAlternativeNames(Set.of("altName"));
-        catalogItemDto.setCountries(Set.of("country"));
-        catalogItemDto.setWrittenForms(Set.of("written"));
+        catalogItemDto.setBibliography(Stream.of("bibl").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setTypes(Stream.of("type").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setAllNames(Stream.of("altName").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setCountries(Stream.of("country").collect(Collectors.toCollection(LinkedHashSet::new)));
+        catalogItemDto.setWrittenForms(Stream.of("written").collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto.setCertainty(0);
         catalogItemDto.setLatitude(0.1);
         catalogItemDto.setLongitude(0.2);
@@ -300,85 +300,84 @@ class CatalogItemServiceImplTest {
     }
 
 
-
     @Test
     void testSearchedTest() {
         // given
-        String text = "The city of Azbar was found in first century near the ocean. " +
-                "⌈U-re-me-re⌉, another town, was found " +
-                "in 1956. The location of Huga and Duga is not known, but it was probably near Puga.";
-        String highlightedText = "The <b>city</b> of <span style='color:green'>Azbar</span> was found in first century near the <b>ocean</b>. " +
-                "⌈<span style='color:green'>U-re-me-re</span>⌉, another town, was found " +
-                "in 1956. The location of <span style='color:red'>Huga</span> and <span style='color:red'>Duga</span> is not known, but it was probably near Puga.";
+        String text = "The city of Azbar was found in first century near the ocean.  " +
+                "⌈U-re-me-re⌉, another town , was found " +
+                "in 1956.\nThe location of Huga and Duga is not known, but it was probably near Puga.";
+        String highlightedText = "The <b>city</b> of <span style='color:green'>Azbar</span> was found in first century near the <b>ocean</b>.  " +
+                "⌈<span style='color:green'>U-re-me-re</span>⌉, another town , was found " +
+                "in 1956.\nThe location of <span style='color:red'>Huga</span> and <span style='color:red'>Duga</span> is not known, but it was probably near Puga.";
 
         CatalogItem catalogItem1 = new CatalogItem();
-        catalogItem1.setAlternativeNames(Stream.of(new AlternativeName("Azbar", catalogItem1)).collect(Collectors.toSet()));
+        catalogItem1.setAllNames(Stream.of(new CatalogItemName("Azbar", catalogItem1, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem1.setLatitude(5.0);
         catalogItem1.setLongitude(5.0);
 
         CatalogItem catalogItem2 = new CatalogItem();
-        catalogItem2.setAlternativeNames(Stream.of(new AlternativeName("Azbar", catalogItem2), new AlternativeName("Azbarasdf", catalogItem2)).collect(Collectors.toSet()));
+        catalogItem2.setAllNames(Stream.of(new CatalogItemName("Azbar", catalogItem2, 1), new CatalogItemName("Azbarasdf", catalogItem2, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem2.setLatitude(null);
         catalogItem2.setLongitude(null);
 
         CatalogItem catalogItem3 = new CatalogItem();
-        catalogItem3.setAlternativeNames(Stream.of(new AlternativeName("U-re-me-re", catalogItem3)).collect(Collectors.toSet()));
+        catalogItem3.setAllNames(Stream.of(new CatalogItemName("U-re-me-re", catalogItem3, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem3.setLatitude(55.0);
         catalogItem3.setLongitude(68.0);
 
         CatalogItem catalogItem4 = new CatalogItem();
-        catalogItem4.setAlternativeNames(Stream.of(new AlternativeName("Huga", catalogItem4)).collect(Collectors.toSet()));
+        catalogItem4.setAllNames(Stream.of(new CatalogItemName("Huga", catalogItem4, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem4.setLatitude(null);
         catalogItem4.setLongitude(null);
 
         CatalogItem catalogItem5 = new CatalogItem();
-        catalogItem5.setAlternativeNames(Stream.of(new AlternativeName("Huga", catalogItem5), new AlternativeName("Hugaa", catalogItem5)).collect(Collectors.toSet()));
+        catalogItem5.setAllNames(Stream.of(new CatalogItemName("Huga", catalogItem5, 1), new CatalogItemName("Hugaa", catalogItem5, 2)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem5.setLatitude(null);
         catalogItem5.setLongitude(null);
 
         CatalogItem catalogItem6 = new CatalogItem();
-        catalogItem6.setAlternativeNames(Stream.of(new AlternativeName("Duga", catalogItem6)).collect(Collectors.toSet()));
+        catalogItem6.setAllNames(Stream.of(new CatalogItemName("Duga", catalogItem6, 1)).collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItem6.setLatitude(null);
         catalogItem6.setLongitude(null);
 
         CatalogItemDto catalogItemDto1 = new CatalogItemDto();
         catalogItemDto1.setId(catalogItem1.getId());
-        catalogItemDto1.setAlternativeNames(Stream.of("Azbar").collect(Collectors.toSet()));
+        catalogItemDto1.setAllNames(Stream.of("Azbar").collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto1.setLatitude(5.0);
         catalogItemDto1.setLongitude(5.0);
 
         CatalogItemDto catalogItemDto2 = new CatalogItemDto();
         catalogItemDto2.setId(catalogItem2.getId());
-        catalogItemDto2.setAlternativeNames(Stream.of("Azbar", "Azbarasdf").collect(Collectors.toSet()));
+        catalogItemDto2.setAllNames(Stream.of("Azbar", "Azbarasdf").collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto2.setLatitude(null);
         catalogItemDto2.setLongitude(null);
 
         CatalogItemDto catalogItemDto3 = new CatalogItemDto();
         catalogItemDto3.setId(catalogItem3.getId());
-        catalogItemDto3.setAlternativeNames(Stream.of("U-re-me-re").collect(Collectors.toSet()));
+        catalogItemDto3.setAllNames(Stream.of("U-re-me-re").collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto3.setLatitude(55.0);
         catalogItemDto3.setLongitude(68.0);
 
         CatalogItemDto catalogItemDto4 = new CatalogItemDto();
         catalogItemDto4.setId(catalogItem4.getId());
-        catalogItemDto4.setAlternativeNames(Stream.of("Huga").collect(Collectors.toSet()));
+        catalogItemDto4.setAllNames(Stream.of("Huga").collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto4.setLatitude(null);
         catalogItemDto4.setLongitude(null);
 
         CatalogItemDto catalogItemDto5 = new CatalogItemDto();
         catalogItemDto5.setId(catalogItem5.getId());
-        catalogItemDto5.setAlternativeNames(Stream.of("Huga", "Hugaa").collect(Collectors.toSet()));
+        catalogItemDto5.setAllNames(Stream.of("Huga", "Hugaa").collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto5.setLatitude(null);
         catalogItemDto5.setLongitude(null);
 
         CatalogItemDto catalogItemDto6 = new CatalogItemDto();
         catalogItemDto6.setId(catalogItem6.getId());
-        catalogItemDto6.setAlternativeNames(Stream.of("Duga").collect(Collectors.toSet()));
+        catalogItemDto6.setAllNames(Stream.of("Duga").collect(Collectors.toCollection(LinkedHashSet::new)));
         catalogItemDto6.setLatitude(null);
         catalogItemDto6.setLongitude(null);
 
 
-        given(typeService.getAllTypesAsString()).willReturn(Stream.of("city", "ocean").collect(Collectors.toSet()));
+        given(typeService.getAllTypesAsString()).willReturn(Stream.of("city", "ocean").collect(Collectors.toCollection(LinkedHashSet::new)));
         given(catalogItemRepository.getItemsByName(anyString())).willReturn(Collections.emptyList());
         given(catalogItemRepository.getItemsByName("Azbar")).willReturn(Stream.of(catalogItem1, catalogItem2).collect(Collectors.toList()));
         given(catalogItemRepository.getItemsByName("U-re-me-re")).willReturn(Stream.of(catalogItem3).collect(Collectors.toList()));
