diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyTermGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyTermGrid.java
index 1108808152e0f1aa0ea0059835cb1575bc399a23..c75abfe634eb438cbec41576bfc73d64f93bb9d0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyTermGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/vocabulary/VocabularyTermGrid.java
@@ -173,7 +173,7 @@ public class VocabularyTermGrid extends AbstractSimpleBrowserGrid<VocabularyTerm
         textArea.setWidth(250);
         textArea.setHeight(200);
         textArea.setEmptyText(viewContext.getMessage(Dict.VOCABULARY_TERMS_EMPTY));
-        textArea.setValidator(new VocabularyTermValidator(viewContext, vocabulary.getTerms()));
+        textArea.setValidator(new VocabularyTermValidator(viewContext));
         String heading = viewContext.getMessage(Dict.ADD_VOCABULARY_TERMS_TITLE);
         String okButtonLabel = viewContext.getMessage(Dict.ADD_VOCABULARY_TERMS_OK_BUTTON);
         HorizontalPanel panel = new HorizontalPanel();
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/VocabularyBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/VocabularyBO.java
index 48f0f88e99a25e6d5e9fe72a88307d408cadb142..7724472dd24744e49ea8cba82dbe281516b2aff0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/VocabularyBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/VocabularyBO.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.generic.server.business.bo;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -91,27 +92,27 @@ public class VocabularyBO extends AbstractBusinessObject implements IVocabularyB
             List<VocabularyTermReplacement> termsToBeReplaced)
     {
         assert vocabularyPE != null : "Unspecified vocabulary";
-        
+
         Set<VocabularyTermPE> terms = vocabularyPE.getTerms();
-        System.out.println(terms.size());
-        IKeyExtractor<String, VocabularyTermPE> keyExtractor = KeyExtractorFactory.<VocabularyTermPE>createCodeKeyExtractor();
-        TableMap<String, VocabularyTermPE> termsMap = new TableMap<String, VocabularyTermPE>(terms, keyExtractor);
-        
+        IKeyExtractor<String, VocabularyTermPE> keyExtractor =
+                KeyExtractorFactory.<VocabularyTermPE> createCodeKeyExtractor();
+        TableMap<String, VocabularyTermPE> termsMap =
+                new TableMap<String, VocabularyTermPE>(terms, keyExtractor);
+        Set<String> remainingTerms = new HashSet<String>(termsMap.keySet());
         for (VocabularyTerm termToBeDeleted : termsToBeDeleted)
         {
-            termsMap.remove(termToBeDeleted.getCode()).setVocabulary(null);
+            remainingTerms.remove(termToBeDeleted.getCode());
         }
         for (VocabularyTermReplacement termToBeReplaced : termsToBeReplaced)
         {
-            termsMap.remove(termToBeReplaced.getTerm().getCode()).setVocabulary(null);
+            remainingTerms.remove(termToBeReplaced.getTerm().getCode());
         }
-        System.out.println(terms.size());
         for (VocabularyTermReplacement termToBeReplaced : termsToBeReplaced)
         {
             String code = termToBeReplaced.getTerm().getCode();
             String replacement = termToBeReplaced.getReplacement();
             VocabularyTermPE term = termsMap.tryGet(replacement);
-            if (term == null)
+            if (term == null || remainingTerms.contains(replacement) == false)
             {
                 throw new IllegalArgumentException(
                         "Invalid vocabulary replacement because of unknown replacement: "
@@ -128,6 +129,14 @@ public class VocabularyBO extends AbstractBusinessObject implements IVocabularyB
                 dao.updateProperties(properties);
             }
         }
+        for (VocabularyTerm termToBeDeleted : termsToBeDeleted)
+        {
+            termsMap.remove(termToBeDeleted.getCode()).setVocabulary(null);
+        }
+        for (VocabularyTermReplacement termToBeReplaced : termsToBeReplaced)
+        {
+            termsMap.remove(termToBeReplaced.getTerm().getCode()).setVocabulary(null);
+        }
     }
 
     public void save() throws UserFailureException
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyPE.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyPE.java
index 6606b16b90f95013dd6f936369968eb4c4727e50..c2e015b4de1d39b9ec79ec27a2548d3d7b9cf9e6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyPE.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/VocabularyPE.java
@@ -40,6 +40,7 @@ import javax.persistence.Version;
 import org.apache.commons.lang.builder.EqualsBuilder;
 import org.apache.commons.lang.builder.HashCodeBuilder;
 import org.apache.commons.lang.builder.ToStringBuilder;
+import org.hibernate.annotations.Cascade;
 import org.hibernate.validator.Length;
 import org.hibernate.validator.NotNull;
 import org.hibernate.validator.Pattern;
@@ -144,6 +145,7 @@ public class VocabularyPE extends HibernateAbstractRegistrationHolder implements
     }
 
     @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "vocabularyInternal")
+    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
     private Set<VocabularyTermPE> getVocabularyTerms()
     {
         return terms;