diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AllTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AllTests.java
index ab08f8e..e3ef17d 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AllTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AllTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013 IBM Corporation and others.
+ * Copyright (c) 2013, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -24,6 +24,7 @@
 		suite.addTest(new JUnit4TestAdapter(ResolutionReportTest.class));
 		suite.addTest(new JUnit4TestAdapter(ModuleContainerUsageTest.class));
 		suite.addTest(new JUnit4TestAdapter(NamespaceListTest.class));
+		suite.addTest(new JUnit4TestAdapter(NamespaceListBuilderTest.class));
 		return suite;
 	}
 }
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListBuilderTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListBuilderTest.java
new file mode 100644
index 0000000..9e45530
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListBuilderTest.java
@@ -0,0 +1,819 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Hannes Wellmann and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *     Hannes Wellmann - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.container;
+
+import static org.eclipse.osgi.tests.container.NamespaceListTest.build;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.builderAddAfterLastMatch;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.builderAddAll;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.builderCreate;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.builderRemoveElementsOfNamespaceIf;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.builderRemoveNamespaceIf;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.createEmptyNamespaceList;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.getList;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.newNamespace;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.populate;
+import static org.eclipse.osgi.tests.container.NamespaceListTest.randomListSort;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.function.Function;
+import org.eclipse.osgi.tests.container.NamespaceListTest.NamespaceElement;
+import org.junit.Test;
+
+public class NamespaceListBuilderTest {
+
+	@Test
+	public void testCreate() throws Exception {
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		assertTrue("Builder is not initially empty", builder.isEmpty());
+	}
+
+	@Test
+	public void testIteratorsElementSequence_multipleNamespace() throws Exception {
+		List<NamespaceElement> elements = populate(4, 3);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Iterator<NamespaceElement> iterator = builder.iterator();
+
+		for (int i = 0; i < 12; i++) {
+			assertTrue(iterator.hasNext());
+			assertSame(elements.get(i), iterator.next());
+		}
+		assertFalse(iterator.hasNext());
+	}
+
+	@Test
+	public void testIteratorsElementSequence_oneNamespace() throws Exception {
+		List<NamespaceElement> elements = populate(3, "ns-1");
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Iterator<NamespaceElement> iterator = builder.iterator();
+
+		for (int i = 0; i < 3; i++) {
+			assertTrue(iterator.hasNext());
+			assertSame(elements.get(i), iterator.next());
+		}
+		assertFalse(iterator.hasNext());
+	}
+
+	@Test
+	public void testIteratorsElementSequence_empty() throws Exception {
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		Iterator<NamespaceElement> iterator = builder.iterator();
+
+		assertFalse(iterator.hasNext());
+	}
+
+	@Test
+	public void testIteratorsElementSequence_iterationBeyoundEnd_NoSuchElementException() throws Exception {
+		List<NamespaceElement> elements = populate(2, 3);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Iterator<NamespaceElement> iterator = builder.iterator();
+
+		for (int i = 0; i < 6; i++) {
+			assertTrue(iterator.hasNext());
+			assertSame(elements.get(i), iterator.next());
+		}
+		assertFalse(iterator.hasNext());
+		assertThrows(NoSuchElementException.class, iterator::next);
+	}
+
+	@Test
+	public void testIteratorsElementSequence_iterationBeyoundEndOfEmptyBuilder_NoSuchElementException()
+			throws Exception {
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		Iterator<NamespaceElement> iterator = builder.iterator();
+
+		assertFalse(iterator.hasNext());
+		assertThrows(NoSuchElementException.class, iterator::next);
+	}
+
+	@Test
+	public void testIteratorRemove_removeOneElement() throws Exception {
+
+		List<NamespaceElement> elements = populate(4, 3);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Iterator<NamespaceElement> iterator = builder.iterator();
+
+		for (int i = 0; i < 6; i++) {
+			iterator.next();
+		}
+		iterator.remove();
+
+		elements.remove(5);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testIteratorRemove_RemoveAllElements() throws Exception {
+
+		List<NamespaceElement> elements = populate(4, 3);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Iterator<NamespaceElement> iterator = builder.iterator();
+
+		for (int i = 0; i < 12; i++) {
+			iterator.next();
+			iterator.remove();
+		}
+
+		assertStricEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	public void testIteratorRemove_RemoveTwice_IllegalStateException() throws Exception {
+
+		List<NamespaceElement> elements = populate(4, 3);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Iterator<NamespaceElement> iterator = builder.iterator();
+
+		iterator.next();
+		iterator.remove();
+		assertThrows(IllegalStateException.class, iterator::remove);
+
+		elements.remove(0);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testIteratorRemove_NextNotCalled_IllegalStateException() throws Exception {
+
+		List<NamespaceElement> elements = populate(1, 1);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Iterator<NamespaceElement> iterator = builder.iterator();
+
+		assertThrows(IllegalStateException.class, iterator::remove);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testClear() throws Exception {
+		List<NamespaceElement> elements = populate(3, 2);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Object namespaceList = build(builder);
+
+		builder.clear();
+
+		assertEquals(0, builder.size());
+		assertIterationOrderEquals(Collections.emptyList(), builder);
+
+		// assert that a previously build list is not affected
+
+		assertEquals(getList(namespaceList, null), elements);
+		assertEquals(getList(namespaceList, "ns-0"), elements.subList(0, 3));
+		assertEquals(getList(namespaceList, "ns-1"), elements.subList(3, 6));
+	}
+
+	// --- test addition ---
+
+	@Test
+	public void testAdd_singleElement() throws Exception {
+		NamespaceElement e = new NamespaceElement(1, "ns-1");
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		builder.add(e);
+
+		assertEquals(Collections.singletonList(e), getList(build(builder), "ns-1"));
+
+		assertStricEqualContent(builder, Collections.singletonList(e));
+	}
+
+	@Test
+	public void testAdd_multipleElements() throws Exception {
+		List<NamespaceElement> elements = populate(4, 3);
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		for (NamespaceElement element : elements) {
+			builder.add(element);
+		}
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testAddAll_namespaceSortedList() throws Exception {
+		List<NamespaceElement> elements = populate(4, 7);
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		builder.addAll(elements);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testAddAll_randomlySortedList() throws Exception {
+		List<NamespaceElement> elements = populate(4, 7);
+		randomListSort(elements);
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		builder.addAll(elements);
+
+		assertEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testAddAll_emptyList() throws Exception {
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		builder.addAll(Collections.emptyList());
+
+		assertEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	public void testAddAll_namespaceList() throws Exception {
+		List<NamespaceElement> elements = populate(5, 5);
+
+		Object namespaceList = newNamespace(elements);
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		builderAddAll(builder, namespaceList);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testAddAll_emptyNamespaceList() throws Exception {
+
+		Object namespaceList = createEmptyNamespaceList(NamespaceElement::getNamespace);
+
+		Collection<NamespaceElement> builder = builderCreate();
+
+		builderAddAll(builder, namespaceList);
+
+		assertStricEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	public void testAddAfterLastMatch_matchUpUntilTheMiddle() throws Exception {
+		List<NamespaceElement> elements = populate(4, "ns-0");
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		NamespaceElement element = new NamespaceElement(5, "ns-0");
+		builderAddAfterLastMatch(builder, element, e -> e.id < 2);
+
+		elements.add(2, element);
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testAddAfterLastMatch_allElementsMatches() throws Exception {
+		List<NamespaceElement> elements = populate(4, "ns-0");
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		NamespaceElement element = new NamespaceElement(5, "ns-0");
+		builderAddAfterLastMatch(builder, element, e -> true);
+
+		elements.add(4, element);
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testAddAfterLastMatch_noMatch() throws Exception {
+		List<NamespaceElement> elements = populate(4, "ns-0");
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		NamespaceElement element = new NamespaceElement(5, "ns-0");
+		builderAddAfterLastMatch(builder, element, e -> e.id > 100);
+
+		elements.add(0, element);
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testAddAfterLastMatch_emptyNamespaceList() throws Exception {
+		Collection<NamespaceElement> builder = builderCreate();
+
+		NamespaceElement element = new NamespaceElement(5, "ns-0");
+		builderAddAfterLastMatch(builder, element, e -> e.id < 2);
+
+		assertStricEqualContent(builder, Collections.singletonList(element));
+	}
+
+	// --- test removal ---
+
+	@Test
+	public void testRemove_elementIsOneOfMultipleOfNamespace() throws Exception {
+		List<NamespaceElement> elements = populate(4, 4);
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		assertTrue(builder.remove(new NamespaceElement(2, "ns-0")));
+
+		elements.remove(2);
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemove_onlyElementOfNamspace() throws Exception {
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.add(new NamespaceElement(3, "ns-0"));
+
+		assertTrue(builder.remove(new NamespaceElement(3, "ns-0")));
+
+		assertStricEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	public void testRemove_elementNotContainedInNamespaceList() throws Exception {
+		List<NamespaceElement> elements = populate(4, 3);
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		assertFalse(builder.remove(new NamespaceElement(100, "ns-0")));
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemove_elementWithNotPresentNamespace() throws Exception {
+		List<NamespaceElement> elements = populate(4, 3);
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		assertFalse(builder.remove(new NamespaceElement(1, "ns-100")));
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemove_emptyBuilder() throws Exception {
+		Collection<NamespaceElement> builder = builderCreate();
+
+		assertFalse(builder.remove(new NamespaceElement(3, "ns-0")));
+
+		assertStricEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	@SuppressWarnings("unlikely-arg-type")
+	public void testRemove_argumentOfOtherClass() throws Exception {
+		List<NamespaceElement> elements = populate(2, 3);
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		assertFalse(builder.remove("someString"));
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveAll_multipleElementsInMultipleNamsespaces() throws Exception {
+		List<NamespaceElement> elements = populate(4, 5);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		List<NamespaceElement> toRemove = new ArrayList<>();
+		toRemove.add(new NamespaceElement(1, "ns-0")); // has total index 1
+		toRemove.add(new NamespaceElement(2, "ns-1")); // has total index 6
+		toRemove.add(new NamespaceElement(0, "ns-1")); // has total index 4
+		toRemove.add(new NamespaceElement(3, "ns-3")); // has total index 15
+		toRemove.add(new NamespaceElement(2, "ns-3")); // has total index 14
+
+		assertTrue(builder.removeAll(toRemove));
+
+		elements.remove(15);
+		elements.remove(14);
+		elements.remove(6);
+		elements.remove(4);
+		elements.remove(1);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveAll_multipleElementsInMultipleNamsespacesAndSomeNotPresent() throws Exception {
+		List<NamespaceElement> elements = populate(4, 5);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		List<NamespaceElement> toRemove = new ArrayList<>();
+		toRemove.add(new NamespaceElement(1, "ns-0")); // has total index 1
+		toRemove.add(new NamespaceElement(2, "ns-1")); // has total index 6
+		toRemove.add(new NamespaceElement(100, "ns-2")); // not present
+		toRemove.add(new NamespaceElement(0, "ns-1")); // has total index 4
+		toRemove.add(new NamespaceElement(3, "ns-3")); // has total index 15
+		toRemove.add(new NamespaceElement(100, "ns-3")); // not present
+		toRemove.add(new NamespaceElement(2, "ns-3")); // has total index 14
+		toRemove.add(new NamespaceElement(100, "ns-3")); // not present
+		toRemove.add(new NamespaceElement(1, "ns-100")); // not present
+
+		assertTrue(builder.removeAll(toRemove));
+
+		elements.remove(15);
+		elements.remove(14);
+		elements.remove(6);
+		elements.remove(4);
+		elements.remove(1);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveAll_listOfAllElementsInBuilder() throws Exception {
+		List<NamespaceElement> elements = populate(4, 5);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		assertTrue(builder.removeAll(elements));
+
+		assertStricEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	public void testRemoveAll_emptyList() throws Exception {
+		List<NamespaceElement> elements = populate(4, 5);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		assertFalse(builder.removeAll(Collections.emptyList()));
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveAll_emptyBuilder() throws Exception {
+		Collection<NamespaceElement> builder = builderCreate();
+
+		assertFalse(builder.removeAll(populate(4, 3)));
+
+		assertStricEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	@SuppressWarnings("unlikely-arg-type")
+	public void testRemoveAll_argumentListOfOtherClass() throws Exception {
+		List<NamespaceElement> elements = populate(2, 3);
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		List<String> listOfOtherElements = Arrays.asList("someString", "other");
+		assertFalse(builder.removeAll(listOfOtherElements));
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveNamespaceIf_NamespaceMatches() throws Exception {
+		List<NamespaceElement> elements = populate(4, 5);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Collection<String> namespacesToRemove = Arrays.asList("ns-0", "ns-2");
+
+		builderRemoveNamespaceIf(builder, namespacesToRemove::contains);
+
+		elements.subList(8, 12).clear();
+		elements.subList(0, 4).clear();
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveNamespaceIf_NamespaceMatchesExpunging() throws Exception {
+		List<NamespaceElement> elements = populate(3, 2);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builderRemoveNamespaceIf(builder, n -> true);
+
+		assertStricEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	public void testRemoveNamespaceIf_NoNamespaceMatches() throws Exception {
+		List<NamespaceElement> elements = populate(3, 3);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builderRemoveNamespaceIf(builder, "ns-100"::equals);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveIf_multipleMatches() throws Exception {
+		List<NamespaceElement> elements = populate(5, 5);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builder.removeIf(e -> e.id % 3 == 0 || "ns-1".equals(e.namespace));
+
+		elements.remove(23); // first and third of 20-25
+		elements.remove(20);
+
+		elements.remove(18); // first and third of 15-20
+		elements.remove(15);
+
+		elements.remove(13); // first and third of 10-15
+		elements.remove(10);
+
+		elements.subList(5, 10).clear(); // all of 5-10
+
+		elements.remove(3); // first and third of 0-5
+		elements.remove(0);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveIf_allMatches() throws Exception {
+		List<NamespaceElement> elements = populate(4, 3);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builder.removeIf(e -> true);
+
+		assertStricEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	public void testRemoveIf_noMatches() throws Exception {
+		List<NamespaceElement> elements = populate(4, 3);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builder.removeIf(e -> false);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveElementsOfNamespaceIf_multipleMatches() throws Exception {
+		List<NamespaceElement> elements = populate(4, 2);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builderRemoveElementsOfNamespaceIf(builder, "ns-0", e -> e.id == 1 || e.id == 2);
+
+		elements.remove(2);
+		elements.remove(1);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveElementsOfNamespaceIf_allElementsOfNamespaceMatch() throws Exception {
+		List<NamespaceElement> elements = populate(4, 2);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builderRemoveElementsOfNamespaceIf(builder, "ns-0", e -> e.id == 1 || e.id == 2);
+
+		elements.remove(2);
+		elements.remove(1);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveElementsOfNamespaceIf_allElementsMatch() throws Exception {
+		List<NamespaceElement> elements = populate(4, 1);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builderRemoveElementsOfNamespaceIf(builder, "ns-0", e -> true);
+
+		assertStricEqualContent(builder, Collections.emptyList());
+	}
+
+	@Test
+	public void testRemoveElementsOfNamespaceIf_noMatch() throws Exception {
+		List<NamespaceElement> elements = populate(4, 1);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builderRemoveElementsOfNamespaceIf(builder, "ns-0", e -> false);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	@Test
+	public void testRemoveElementsOfNamespaceIf_namespaceNotPresent() throws Exception {
+		List<NamespaceElement> elements = populate(4, 1);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		builderRemoveElementsOfNamespaceIf(builder, "ns-100", e -> true);
+
+		assertStricEqualContent(builder, elements);
+	}
+
+	// --- test build ---
+
+	@Test
+	public void testBuild_notEmptyBuilder() throws Exception {
+		List<NamespaceElement> elements = populate(4, 2);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Object namespaceList1 = build(builder);
+
+		assertEquals(elements, getList(namespaceList1, null));
+		assertEquals(elements.subList(0, 4), getList(namespaceList1, "ns-0"));
+		assertEquals(elements.subList(4, 8), getList(namespaceList1, "ns-1"));
+
+		Object namespaceList2 = build(builder);
+
+		assertEquals(elements, getList(namespaceList1, null));
+		assertEquals(elements.subList(0, 4), getList(namespaceList1, "ns-0"));
+		assertEquals(elements.subList(4, 8), getList(namespaceList1, "ns-1"));
+
+		assertEquals(elements, getList(namespaceList2, null));
+		assertEquals(elements.subList(0, 4), getList(namespaceList2, "ns-0"));
+		assertEquals(elements.subList(4, 8), getList(namespaceList2, "ns-1"));
+	}
+
+	@Test
+	public void testBuild_emptyBuilder() throws Exception {
+		Collection<NamespaceElement> builder = builderCreate();
+
+		Object namespaceList = build(builder);
+
+		assertEquals(Collections.emptyList(), getList(namespaceList, null));
+	}
+
+	@Test
+	public void testBuild_subsequentModificationOfBuilder() throws Exception {
+		List<NamespaceElement> elements = populate(4, 2);
+
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+
+		Object namespaceList1 = build(builder);
+
+		assertEquals(elements, getList(namespaceList1, null));
+		assertEquals(elements.subList(0, 4), getList(namespaceList1, "ns-0"));
+		assertEquals(elements.subList(4, 8), getList(namespaceList1, "ns-1"));
+
+		List<NamespaceElement> additionalElements = populate(1, 3);
+		builder.addAll(additionalElements);
+
+		List<NamespaceElement> newElements = new ArrayList<>(elements);
+
+		newElements.add(8, additionalElements.get(2));
+		newElements.add(8, additionalElements.get(1));
+		newElements.add(4, additionalElements.get(0));
+
+		// assert the first list build is not modified
+		assertEquals(elements, getList(namespaceList1, null));
+		assertEquals(elements.subList(0, 4), getList(namespaceList1, "ns-0"));
+		assertEquals(elements.subList(4, 8), getList(namespaceList1, "ns-1"));
+
+		// asser the new content of the builder is as expected
+		assertStricEqualContent(builder, newElements);
+	}
+
+	// --- utility methods ---
+
+	private static void assertStricEqualContent(Collection<NamespaceElement> builder,
+			List<NamespaceElement> expectedElements) throws Exception {
+		assertStricEqualContent(builder, expectedElements, NamespaceElement::getNamespace);
+	}
+
+	private static <E> void assertStricEqualContent(Collection<E> builder, List<E> expectedElements,
+			Function<E, String> getNamespace) throws Exception {
+		// test all properties of the builder and its build list in order to ensure they
+		// are updated correctly
+
+		assertIterationOrderEquals(expectedElements, builder);
+		assertEquals(expectedElements.size(), builder.size());
+
+		Map<String, List<E>> namespaceElements = getNamespaceElements(expectedElements, getNamespace);
+		Object namespaceList = build(builder);
+
+		assertEquals(expectedElements.size(), getList(namespaceList, null).size());
+
+		for (Entry<String, List<E>> entry : namespaceElements.entrySet()) {
+			String namespace = entry.getKey();
+			List<E> elements = entry.getValue();
+			assertEquals(elements, getList(namespaceList, namespace));
+		}
+
+		assertEquals(expectedElements, getList(namespaceList, null));
+	}
+
+	private static void assertEqualContent(Collection<NamespaceElement> builder,
+			List<NamespaceElement> expectedElements) throws Exception {
+		// test all properties of the builder and its build list in order to ensure they
+		// are updated correctly
+
+		assertContentEquals(expectedElements, builder);
+		assertEquals(expectedElements.size(), builder.size());
+
+		Map<String, List<NamespaceElement>> namespaceElements = getNamespaceElements(expectedElements,
+				NamespaceElement::getNamespace);
+		Object namespaceList = build(builder);
+
+		assertEquals(expectedElements.size(), getList(namespaceList, null).size());
+
+		for (Entry<String, List<NamespaceElement>> entry : namespaceElements.entrySet()) {
+			String namespace = entry.getKey();
+			List<NamespaceElement> elements = entry.getValue();
+			assertContentEquals(elements, getList(namespaceList, namespace));
+		}
+
+		assertContentEquals(expectedElements, getList(namespaceList, null));
+	}
+
+	private static <E> void assertIterationOrderEquals(Collection<E> expected, Collection<E> actual) {
+		// instead of comparing the iterators, simply compare List-copies. They reflect
+		// the iteration order.
+		assertEquals(new ArrayList<>(expected), new ArrayList<>(actual));
+	}
+
+	private static <E> void assertContentEquals(List<E> expected, Collection<E> actual) {
+		assertEquals(new HashSet<>(expected), new HashSet<>(actual));
+	}
+
+	private static <E> Map<String, List<E>> getNamespaceElements(List<E> elements, Function<E, String> getNamespace) {
+		Map<String, List<E>> namespaceElements = new HashMap<>();
+		for (E element : elements) {
+			namespaceElements.computeIfAbsent(getNamespace.apply(element), n -> new ArrayList<>()).add(element);
+		}
+		return namespaceElements;
+	}
+}
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListTest.java
index dea96f9..65a8af7 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListTest.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListTest.java
@@ -10,23 +10,24 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Hannes Wellmann - Bug 573025: introduce and apply NamespaceList.Builder
  *******************************************************************************/
 package org.eclipse.osgi.tests.container;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
-import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Random;
 import java.util.function.Function;
+import java.util.function.Predicate;
 import org.junit.Test;
 import org.osgi.framework.Bundle;
 
@@ -34,24 +35,96 @@
  * Using reflection because to avoid exporting internals.
  */
 public class NamespaceListTest extends AbstractTest {
-	static final Method getList;
-	static final Method isEmpty;
-	static final Method getNamespaceIndex;
-	static final Method copyList;
-	static final Constructor<?> newNamespaceList;
+	static final Method NAMESPACELIST_GET_LIST;
+	static final Method NAMESPACELIST_IS_EMPTY;
+	static final Method NAMESPACELIST_EMPTY;
+	static final Method NAMESPACELIST_CREATE_BUILDER;
+
+	// only access fields reflectively that are not part of the Collection-API
+	static final Method BUILDER_CREATE;
+	static final Method BUILDER_ADD_ALL;
+	static final Method BUILDER_ADD_AFTER_LAST_MATCH;
+	static final Method BUILDER_REMOVE_NAMESPACE_IF;
+	static final Method BUILDER_REMOVE_ELEMENTS_OF_NAMESPACE_IF;
+	static final Method BUILDER_BUILD;
+
 	static {
 		try {
-			Class<?> namespaceList = Bundle.class.getClassLoader()
-					.loadClass("org.eclipse.osgi.internal.container.NamespaceList");
-			getList = namespaceList.getMethod("getList", String.class);
-			isEmpty = namespaceList.getMethod("isEmpty");
-			getNamespaceIndex = namespaceList.getMethod("getNamespaceIndex", String.class);
-			copyList = namespaceList.getMethod("copyList");
-			newNamespaceList = namespaceList.getConstructor(List.class, Function.class);
+			ClassLoader classLoader = Bundle.class.getClassLoader();
+			Class<?> namespaceList = classLoader.loadClass("org.eclipse.osgi.internal.container.NamespaceList");
+			Class<?> namespaceListBuilder = classLoader
+					.loadClass("org.eclipse.osgi.internal.container.NamespaceList$Builder");
+
+			NAMESPACELIST_GET_LIST = namespaceList.getMethod("getList", String.class);
+			NAMESPACELIST_IS_EMPTY = namespaceList.getMethod("isEmpty");
+			NAMESPACELIST_EMPTY = namespaceList.getMethod("empty", Function.class);
+			NAMESPACELIST_CREATE_BUILDER = namespaceList.getMethod("createBuilder");
+
+			BUILDER_CREATE = namespaceListBuilder.getMethod("create", Function.class);
+			BUILDER_ADD_ALL = namespaceListBuilder.getMethod("addAll", namespaceList);
+			BUILDER_ADD_AFTER_LAST_MATCH = namespaceListBuilder.getMethod("addAfterLastMatch", Object.class,
+					Predicate.class);
+			BUILDER_REMOVE_NAMESPACE_IF = namespaceListBuilder.getMethod("removeNamespaceIf", Predicate.class);
+			BUILDER_REMOVE_ELEMENTS_OF_NAMESPACE_IF = namespaceListBuilder.getMethod("removeElementsOfNamespaceIf",
+					String.class, Predicate.class);
+			BUILDER_BUILD = namespaceListBuilder.getMethod("build");
 		} catch (Throwable t) {
 			throw new RuntimeException(t);
 		}
 	}
+
+	static Object newNamespace(List<NamespaceElement> elements) throws Exception {
+		Collection<NamespaceElement> builder = builderCreate();
+		builder.addAll(elements);
+		return build(builder);
+	}
+
+	// --- reflectively invoked methods of NamespaceList ---
+
+	static <E> Object createEmptyNamespaceList(Function<E, String> getNamespace) throws Exception {
+		return NAMESPACELIST_EMPTY.invoke(null, getNamespace);
+	}
+
+	static boolean isEmpty(Object namespaceList) throws Exception {
+		return (boolean) NAMESPACELIST_IS_EMPTY.invoke(namespaceList);
+	}
+
+	static List<NamespaceElement> getList(Object namespaceList, String namespace) throws Exception {
+		return (List<NamespaceElement>) NAMESPACELIST_GET_LIST.invoke(namespaceList, namespace);
+	}
+
+	static Collection<NamespaceElement> createBuilder(Object namespaceList) throws Exception {
+		return (Collection<NamespaceElement>) NAMESPACELIST_CREATE_BUILDER.invoke(namespaceList);
+	}
+
+	// --- reflectively invoked non-Collection methods of NamespaceList$Builder ---
+
+	static Collection<NamespaceElement> builderCreate() throws Exception {
+		Function<NamespaceElement, String> getNamespace = NamespaceElement::getNamespace;
+		return (Collection<NamespaceElement>) BUILDER_CREATE.invoke(null, getNamespace);
+	}
+
+	static <E> void builderAddAll(Collection<E> builder, Object namespaceList) throws Exception {
+		BUILDER_ADD_ALL.invoke(builder, namespaceList);
+	}
+
+	static <E> void builderAddAfterLastMatch(Collection<E> builder, E e, Predicate<E> matcher) throws Exception {
+		BUILDER_ADD_AFTER_LAST_MATCH.invoke(builder, e, matcher);
+	}
+
+	static <E> void builderRemoveNamespaceIf(Collection<E> builder, Predicate<String> filter) throws Exception {
+		BUILDER_REMOVE_NAMESPACE_IF.invoke(builder, filter);
+	}
+
+	static <E> void builderRemoveElementsOfNamespaceIf(Collection<E> builder, String namespace, Predicate<E> filter)
+			throws Exception {
+		BUILDER_REMOVE_ELEMENTS_OF_NAMESPACE_IF.invoke(builder, namespace, filter);
+	}
+
+	static <E> Object build(Collection<E> builder) throws Exception {
+		return BUILDER_BUILD.invoke(builder);
+	}
+
 	static class NamespaceElement {
 		final int id;
 		final String namespace;
@@ -81,7 +154,7 @@
 
 		@Override
 		public int hashCode() {
-			return namespace.hashCode() ^ id;
+			return Objects.hash(namespace, id);
 		}
 
 		@Override
@@ -90,10 +163,14 @@
 		}
 	}
 
-	static final Function<NamespaceElement, String> getNamespaceFunc = (Function<NamespaceElement, String>) NamespaceElement::getNamespace;
-	Object newNamespace(List<NamespaceElement> elements) throws Exception {
-		return newNamespaceList.newInstance(elements, getNamespaceFunc);
+	// --- tests ---
+
+	@Test
+	public void testCreateEmptyList() throws Exception {
+		Object namespaceList = createEmptyNamespaceList(NamespaceElement::getNamespace);
+		assertTrue("List is not empty.", isEmpty(namespaceList));
 	}
+
 	@Test
 	public void testIsEmpty() throws Exception {
 		Object namespaceList = newNamespace(Collections.emptyList());
@@ -109,14 +186,6 @@
 		assertFalse("List is empty.", isEmpty(namespaceList));
 	}
 
-	private boolean isEmpty(Object namespaceList) throws Exception {
-		return (boolean) isEmpty.invoke(namespaceList);
-	}
-
-	private List<NamespaceElement> getList(Object namespaceList, String namespace) throws Exception {
-		return (List<NamespaceElement>) getList.invoke(namespaceList, namespace);
-	}
-
 	@Test
 	public void testGetList() throws Exception {
 		Object namespaceList = newNamespace(Collections.emptyList());
@@ -145,31 +214,9 @@
 	}
 
 	@Test
-	public void testGetNamespaceIndex() throws Exception {
-		Object namespaceList = newNamespace(Collections.emptyList());
-		assertNull("Unexpected index.", getNamespaceIndex(namespaceList, "ns-0"));
-
-		List<NamespaceElement> elements = populate(21, 13);
-
-		namespaceList = newNamespace(elements);
-		Entry<Integer, Integer> nsIndex = getNamespaceIndex(namespaceList, "ns-0");
-		assertNotNull("Expected an index", nsIndex);
-		checkIndex(nsIndex, 0, 21);
-
-		nsIndex = getNamespaceIndex(namespaceList, "ns-12");
-		assertNotNull("Expected an index", nsIndex);
-		checkIndex(nsIndex, 21 * 12, 21 * 13);
-
-		nsIndex = getNamespaceIndex(namespaceList, "ns-4");
-		assertNotNull("Expected an index", nsIndex);
-		checkIndex(nsIndex, 21 * 4, 21 * 5);
-	}
-
-	@Test
 	public void testOutOfOrderNamespace() throws Exception {
 		List<NamespaceElement> elements = populate(4, 4);
-		// random sort by hashcode
-		elements.sort((n1, n2) -> n1.hashCode() - n2.hashCode());
+		randomListSort(elements);
 		Object namespaceList = newNamespace(elements);
 		for (int i = 0; i < 4; i++) {
 			List<NamespaceElement> list = getList(namespaceList, "ns-" + i);
@@ -183,54 +230,29 @@
 	}
 
 	@Test
-	public void testCopyList() throws Exception {
-		Object namespaceList = newNamespace(Collections.emptyList());
-		List<NamespaceElement> copy = copyList(namespaceList);
-		assertEquals("Wrong list.", Collections.emptyList(), copy);
-		successAdd(copy);
-		copy = copyList(namespaceList);
-		assertEquals("Wrong list.", Collections.emptyList(), copy);
+	public void testCreateBuilder() throws Exception {
 
-		List<NamespaceElement> elements = populate(100, 13);
-		namespaceList = newNamespace(elements);
-		copy = copyList(namespaceList);
-		assertEquals("Wrong list.", elements, copy);
-		successAdd(copy);
-		copy = copyList(namespaceList);
-		assertEquals("Wrong list.", elements, copy);
+		List<NamespaceElement> elements = populate(5, 10);
+		Object namespaceList = newNamespace(elements);
+		Collection<NamespaceElement> builder = createBuilder(namespaceList);
+
+		Object buildNamespaceList = build(builder);
+
+		// The order of all elements should be maintained
+
+		assertEquals("Builder not populated correctly", getList(buildNamespaceList, null),
+				getList(namespaceList, null));
 	}
 
-	private List<NamespaceElement> copyList(Object namespaceList) throws Exception {
-		return (List<NamespaceElement>) copyList.invoke(namespaceList);
-	}
-
-	private void checkIndex(Entry<Integer, Integer> nsIndex, int start, int end) {
-		assertEquals("Unexpected Start", start, (int) nsIndex.getKey());
-	}
-
-	private Entry<Integer, Integer> getNamespaceIndex(Object namespaceList, String namespace) throws Exception {
-		return (Entry<Integer, Integer>) getNamespaceIndex.invoke(namespaceList, namespace);
-	}
+	// --- uility methods ---
 
 	private void failAdd(List<NamespaceElement> list) {
-		try {
-			list.add(new NamespaceElement(0, "ns"));
-			fail("Should fail to modify list");
-		} catch (UnsupportedOperationException e) {
-			// expected
-		}
+		NamespaceElement e = new NamespaceElement(0, "ns");
+		assertThrows(UnsupportedOperationException.class, () -> list.add(e));
 	}
 
-	private void successAdd(List<NamespaceElement> list) {
-		try {
-			list.add(new NamespaceElement(0, "ns"));
-		} catch (UnsupportedOperationException e) {
-			fail("Should not fail to modify list");
-		}
-	}
-
-	private List<NamespaceElement> populate(int numElementsPerNS, int numNS) {
-		ArrayList<NamespaceElement> elements = new ArrayList<>(numElementsPerNS * numNS);
+	static List<NamespaceElement> populate(int numElementsPerNS, int numNS) {
+		List<NamespaceElement> elements = new ArrayList<>(numElementsPerNS * numNS);
 		for (int namespace = 0; namespace < numNS; namespace++) {
 			for (int element = 0; element < numElementsPerNS; element++) {
 				elements.add(new NamespaceElement(element, "ns-" + namespace));
@@ -239,11 +261,16 @@
 		return elements;
 	}
 
-	private List<NamespaceElement> populate(int numElements, String namespace) {
-		ArrayList<NamespaceElement> elements = new ArrayList<>(numElements);
+	static List<NamespaceElement> populate(int numElements, String namespace) {
+		List<NamespaceElement> elements = new ArrayList<>(numElements);
 		for (int element = 0; element < numElements; element++) {
 			elements.add(new NamespaceElement(element, namespace));
 		}
 		return elements;
 	}
+
+	static void randomListSort(List<NamespaceElement> elements) {
+		// random sort in reproducible order
+		Collections.shuffle(elements, new Random(43L));
+	}
 }
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java
index 52367f3..c8f1919 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleContainer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2020 IBM Corporation and others.
+ * Copyright (c) 2012, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -13,8 +13,6 @@
  *******************************************************************************/
 package org.eclipse.osgi.container;
 
-import static org.eclipse.osgi.internal.container.NamespaceList.WIRE;
-
 import java.io.Closeable;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -1049,9 +1047,9 @@
 					return null; // need to try again
 				// remove any wires from unresolved wirings that got removed
 				for (Map.Entry<ModuleWiring, Collection<ModuleWire>> entry : toRemoveWireLists.entrySet()) {
-					List<ModuleWire> provided = entry.getKey().getProvidedWires().copyList();
+					NamespaceList.Builder<ModuleWire> provided = entry.getKey().getProvidedWires().createBuilder();
 					provided.removeAll(entry.getValue());
-					entry.getKey().setProvidedWires(new NamespaceList<>(provided, WIRE));
+					entry.getKey().setProvidedWires(provided.build());
 					for (ModuleWire removedWire : entry.getValue()) {
 						// invalidate the wire
 						removedWire.invalidate();
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java
index 4e8689a..108714d 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2020 IBM Corporation and others.
+ * Copyright (c) 2012, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -13,8 +13,6 @@
  *******************************************************************************/
 package org.eclipse.osgi.container;
 
-import static org.eclipse.osgi.internal.container.NamespaceList.WIRE;
-
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -44,6 +42,7 @@
 import org.eclipse.osgi.internal.container.Capabilities;
 import org.eclipse.osgi.internal.container.ComputeNodeOrder;
 import org.eclipse.osgi.internal.container.NamespaceList;
+import org.eclipse.osgi.internal.container.NamespaceList.Builder;
 import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.Constants;
@@ -412,9 +411,9 @@
 				}
 				// remove any wires from unresolved wirings that got removed
 				for (Map.Entry<ModuleWiring, Collection<ModuleWire>> entry : toRemoveWireLists.entrySet()) {
-					List<ModuleWire> provided = entry.getKey().getProvidedWires().copyList();
+					NamespaceList.Builder<ModuleWire> provided = entry.getKey().getProvidedWires().createBuilder();
 					provided.removeAll(entry.getValue());
-					entry.getKey().setProvidedWires(new NamespaceList<>(provided, WIRE));
+					entry.getKey().setProvidedWires(provided.build());
 					for (ModuleWire removedWire : entry.getValue()) {
 						// invalidate the wire
 						removedWire.invalidate();
@@ -503,13 +502,9 @@
 	final Map<ModuleRevision, ModuleWiring> getWiringsClone() {
 		readLock();
 		try {
-			Map<ModuleRevision, ModuleWiring> clonedWirings = new HashMap<>();
-			for (Map.Entry<ModuleRevision, ModuleWiring> entry : wirings.entrySet()) {
-				ModuleWiring wiring = new ModuleWiring(entry.getKey(), entry.getValue().getCapabilities(),
-						entry.getValue().getRequirements(), entry.getValue().getProvidedWires(),
-						entry.getValue().getRequiredWires(), entry.getValue().getSubstitutedNames());
-				clonedWirings.put(entry.getKey(), wiring);
-			}
+			Map<ModuleRevision, ModuleWiring> clonedWirings = new HashMap<>(wirings);
+			clonedWirings.replaceAll((r, w) -> new ModuleWiring(r, w.getCapabilities(), w.getRequirements(),
+					w.getProvidedWires(), w.getRequiredWires(), w.getSubstitutedNames()));
 			return clonedWirings;
 		} finally {
 			readUnlock();
@@ -1393,25 +1388,25 @@
 				throw new NullPointerException("Could not find revision for wiring."); //$NON-NLS-1$
 
 			int numCapabilities = in.readInt();
-			List<ModuleCapability> capabilities = new ArrayList<>(numCapabilities);
+			NamespaceList.Builder<ModuleCapability> capabilities = Builder.create(NamespaceList.CAPABILITY);
 			for (int i = 0; i < numCapabilities; i++) {
 				capabilities.add((ModuleCapability) objectTable.get(in.readInt()));
 			}
 
 			int numRequirements = in.readInt();
-			List<ModuleRequirement> requirements = new ArrayList<>(numRequirements);
+			NamespaceList.Builder<ModuleRequirement> requirements = Builder.create(NamespaceList.REQUIREMENT);
 			for (int i = 0; i < numRequirements; i++) {
 				requirements.add((ModuleRequirement) objectTable.get(in.readInt()));
 			}
 
 			int numProvidedWires = in.readInt();
-			List<ModuleWire> providedWires = new ArrayList<>(numProvidedWires);
+			NamespaceList.Builder<ModuleWire> providedWires = Builder.create(NamespaceList.WIRE);
 			for (int i = 0; i < numProvidedWires; i++) {
 				providedWires.add((ModuleWire) objectTable.get(in.readInt()));
 			}
 
 			int numRequiredWires = in.readInt();
-			List<ModuleWire> requiredWires = new ArrayList<>(numRequiredWires);
+			NamespaceList.Builder<ModuleWire> requiredWires = Builder.create(NamespaceList.WIRE);
 			for (int i = 0; i < numRequiredWires; i++) {
 				requiredWires.add((ModuleWire) objectTable.get(in.readInt()));
 			}
@@ -1422,7 +1417,8 @@
 				substituted.add(readString(in, objectTable));
 			}
 
-			return new ModuleWiring(revision, capabilities, requirements, providedWires, requiredWires, substituted);
+			return new ModuleWiring(revision, capabilities.build(), requirements.build(), providedWires.build(),
+					requiredWires.build(), substituted);
 		}
 
 		private static void writeGenericInfo(String namespace, Map<String, ?> attributes, Map<String, String> directives, DataOutputStream out, Map<Object, Integer> objectTable) throws IOException {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java
index 3a40b5b..91eebcf 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2020 IBM Corporation and others.
+ * Copyright (c) 2012, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -29,7 +29,6 @@
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.CancellationException;
@@ -40,7 +39,6 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Function;
 import org.apache.felix.resolver.Logger;
 import org.apache.felix.resolver.ResolutionError;
 import org.apache.felix.resolver.ResolverImpl;
@@ -48,6 +46,7 @@
 import org.eclipse.osgi.container.namespaces.EquinoxFragmentNamespace;
 import org.eclipse.osgi.internal.container.InternalUtils;
 import org.eclipse.osgi.internal.container.NamespaceList;
+import org.eclipse.osgi.internal.container.NamespaceList.Builder;
 import org.eclipse.osgi.internal.debug.Debug;
 import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
 import org.eclipse.osgi.internal.framework.EquinoxContainer;
@@ -183,17 +182,15 @@
 
 	Map<ModuleRevision, ModuleWiring> generateDelta(Map<Resource, List<Wire>> result, Map<ModuleRevision, ModuleWiring> wiringCopy) {
 		Map<ModuleRevision, Map<ModuleCapability, List<ModuleWire>>> provided = new HashMap<>();
-		Map<ModuleRevision, List<ModuleWire>> required = new HashMap<>();
+		Map<ModuleRevision, NamespaceList<ModuleWire>> required = new HashMap<>(result.size() * 4 / 3 + 1);
 		// First populate the list of provided and required wires for revision
 		// This is done this way to share the wire object between both the provider and requirer
 		for (Map.Entry<Resource, List<Wire>> resultEntry : result.entrySet()) {
 			ModuleRevision revision = (ModuleRevision) resultEntry.getKey();
-			List<ModuleWire> requiredWires = new ArrayList<>(resultEntry.getValue().size());
-			List<String> seen = new ArrayList<>(5);
+			NamespaceList.Builder<ModuleWire> requiredWires = NamespaceList.Builder.create(WIRE);
 			for (Wire wire : resultEntry.getValue()) {
 				ModuleWire moduleWire = new ModuleWire((ModuleCapability) wire.getCapability(), (ModuleRevision) wire.getProvider(), (ModuleRequirement) wire.getRequirement(), (ModuleRevision) wire.getRequirer());
-				requiredWires.add(getInsertIndex(moduleWire.getCapability().getNamespace(), requiredWires, seen,
-						NamespaceList.WIRE), moduleWire);
+				requiredWires.add(moduleWire);
 				Map<ModuleCapability, List<ModuleWire>> providedWiresMap = provided.get(moduleWire.getProvider());
 				if (providedWiresMap == null) {
 					providedWiresMap = new HashMap<>();
@@ -206,7 +203,7 @@
 				}
 				providedWires.add(moduleWire);
 			}
-			required.put(revision, requiredWires);
+			required.put(revision, requiredWires.build());
 		}
 
 		Map<ModuleRevision, ModuleWiring> delta = new HashMap<>();
@@ -232,148 +229,96 @@
 		return delta;
 	}
 
-	private ModuleWiring createNewWiring(ModuleRevision revision, Map<ModuleRevision, Map<ModuleCapability, List<ModuleWire>>> provided, Map<ModuleRevision, List<ModuleWire>> required) {
-		Map<ModuleCapability, List<ModuleWire>> providedWireMap = provided.get(revision);
-		if (providedWireMap == null)
-			providedWireMap = Collections.emptyMap();
-		List<ModuleWire> requiredWires = required.get(revision);
-		if (requiredWires == null)
-			requiredWires = Collections.emptyList();
+	private ModuleWiring createNewWiring(ModuleRevision revision, Map<ModuleRevision, Map<ModuleCapability, List<ModuleWire>>> provided, Map<ModuleRevision, NamespaceList<ModuleWire>> required) {
 
-		List<ModuleCapability> capabilities = sortByNamespaceCopy(revision.getModuleCapabilities(null), CAPABILITY);
-		ListIterator<ModuleCapability> iCapabilities = capabilities.listIterator(capabilities.size());
-		List<ModuleRequirement> requirements = sortByNamespaceCopy(revision.getModuleRequirements(null), REQUIREMENT);
-		ListIterator<ModuleRequirement> iRequirements = requirements.listIterator(requirements.size());
+		Map<ModuleCapability, List<ModuleWire>> providedWireMap = provided.getOrDefault(revision, Collections.emptyMap());
+		NamespaceList<ModuleWire> requiredWires = required.getOrDefault(revision, NamespaceList.empty(WIRE));
+
+		NamespaceList.Builder<ModuleCapability> capabilities = Builder.create(CAPABILITY);
+		capabilities.addAll(revision.getModuleCapabilities(null));
+		NamespaceList.Builder<ModuleRequirement> requirements = Builder.create(REQUIREMENT);
+		requirements.addAll(revision.getModuleRequirements(null));
 
 		// if revision is a fragment remove payload requirements and capabilities
 		if ((BundleRevision.TYPE_FRAGMENT & revision.getTypes()) != 0) {
-			removePayloadContent(iCapabilities, iRequirements);
+			removePayloadContent(capabilities, requirements);
 		} else {
 			// add fragment capabilities and requirements
 			List<ModuleCapability> hostCapabilities = revision.getModuleCapabilities(HostNamespace.HOST_NAMESPACE);
 			ModuleCapability hostCapability = hostCapabilities.isEmpty() ? null : hostCapabilities.get(0);
 			if (hostCapability != null) {
-				addPayloadContent(providedWireMap.get(hostCapability), iCapabilities, iRequirements);
+				addPayloadContent(providedWireMap.get(hostCapability), capabilities, requirements);
 			}
 		}
 
-		removeNonEffectiveCapabilities(iCapabilities);
-		removeNonEffectiveRequirements(iRequirements, requiredWires);
-		Collection<String> substituted = removeSubstitutedCapabilities(iCapabilities, requiredWires);
+		removeNonEffectiveCapabilities(capabilities);
+		removeNonEffectiveRequirements(requirements, requiredWires);
+		Collection<String> substituted = removeSubstitutedCapabilities(capabilities, requiredWires);
 
-		List<ModuleWire> providedWires = new ArrayList<>();
+		NamespaceList.Builder<ModuleWire> providedWires = NamespaceList.Builder.create(WIRE);
 		addProvidedWires(providedWireMap, providedWires, capabilities);
 
 		InternalUtils.filterCapabilityPermissions(capabilities);
-		return new ModuleWiring(revision, new NamespaceList<>(capabilities, CAPABILITY),
-				new NamespaceList<>(requirements, REQUIREMENT), new NamespaceList<>(providedWires, WIRE),
-				new NamespaceList<>(requiredWires, WIRE), substituted);
+		return new ModuleWiring(revision, capabilities.build(), requirements.build(), providedWires.build(),
+				requiredWires, substituted);
+
 	}
 
-	private <E> List<E> sortByNamespaceCopy(List<E> elements, Function<E, String> getNamespace) {
-		List<E> result = new ArrayList<>(elements.size());
-		List<String> seen = new ArrayList<>();
-		for (E e : elements) {
-			String namespace = getNamespace.apply(e);
-			result.add(getInsertIndex(namespace, result, seen, getNamespace), e);
-		}
-		return result;
+	private static void removePayloadContent(NamespaceList.Builder<ModuleCapability> capabilities,
+			NamespaceList.Builder<ModuleRequirement> requirements) {
+
+		capabilities.removeNamespaceIf(namespace -> !NON_PAYLOAD_CAPABILITIES.contains(namespace));
+		requirements.removeNamespaceIf(namespace -> !NON_PAYLOAD_REQUIREMENTS.contains(namespace));
 	}
 
-	private <E> int getInsertIndex(String namespace, List<E> elements, List<String> seen,
-			Function<E, String> getNamespace) {
-		if (seen.contains(namespace)) {
-			for (int i = elements.size() - 1; i > -1; i--) {
-				if (namespace.equals(getNamespace.apply(elements.get(i)))) {
-					return i + 1;
-				}
-			}
-			throw new IllegalStateException();
-		}
-		seen.add(namespace);
-		return elements.size();
-	}
-
-	private static void removePayloadContent(ListIterator<ModuleCapability> iCapabilities, ListIterator<ModuleRequirement> iRequirements) {
-		rewind(iCapabilities);
-		while (iCapabilities.hasNext()) {
-			if (!NON_PAYLOAD_CAPABILITIES.contains(iCapabilities.next().getNamespace())) {
-				iCapabilities.remove();
-			}
-		}
-
-		rewind(iRequirements);
-		while (iRequirements.hasNext()) {
-			if (!NON_PAYLOAD_REQUIREMENTS.contains(iRequirements.next().getNamespace())) {
-				iRequirements.remove();
-			}
-		}
-	}
-
-	private static Collection<String> removeSubstitutedCapabilities(ListIterator<ModuleCapability> iCapabilities, List<ModuleWire> requiredWires) {
-		Collection<String> substituted = null;
-		for (ModuleWire moduleWire : requiredWires) {
-			if (!PackageNamespace.PACKAGE_NAMESPACE.equals(moduleWire.getCapability().getNamespace()))
-				continue;
+	private static Collection<String> removeSubstitutedCapabilities(NamespaceList.Builder<ModuleCapability> capabilities, NamespaceList<ModuleWire> requiredWires) {
+		Collection<String> substituted = new ArrayList<>();
+		for (ModuleWire moduleWire : requiredWires.getList(PackageNamespace.PACKAGE_NAMESPACE)) {
 			String packageName = (String) moduleWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
-			rewind(iCapabilities);
-			while (iCapabilities.hasNext()) {
-				ModuleCapability capability = iCapabilities.next();
-				if (PackageNamespace.PACKAGE_NAMESPACE.equals(capability.getNamespace())) {
-					if (packageName.equals(capability.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))) {
-						// found a package capability with the same name as a package that got imported
-						// this indicates a substitution
-						iCapabilities.remove();
-						if (substituted == null) {
-							substituted = new ArrayList<>();
-						}
-						if (!substituted.contains(packageName)) {
-							substituted.add(packageName);
-						}
+			capabilities.removeElementsOfNamespaceIf(PackageNamespace.PACKAGE_NAMESPACE, capability -> {
+				if (packageName.equals(capability.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))) {
+					// found a package capability with the same name as a package that got imported
+					// this indicates a substitution
+					if (!substituted.contains(packageName)) {
+						substituted.add(packageName);
 					}
+					return true;
 				}
-			}
+				return false;
+			});
 		}
-		return substituted == null ? Collections.<String> emptyList() : substituted;
+		return substituted.isEmpty() ? Collections.emptyList() : substituted;
 	}
 
-	private static void removeNonEffectiveRequirements(ListIterator<ModuleRequirement> iRequirements, List<ModuleWire> requiredWires) {
+	private static void removeNonEffectiveRequirements(NamespaceList.Builder<ModuleRequirement> requirements, NamespaceList<ModuleWire> requiredWires) {
 
 		Set<ModuleRequirement> wireRequirements = new HashSet<>();
-		for (ModuleWire mw : requiredWires) {
+		for (ModuleWire mw : requiredWires.getList(null)) {
 			wireRequirements.add(mw.getRequirement());
 		}
-
-		rewind(iRequirements);
-		while (iRequirements.hasNext()) {
-			ModuleRequirement requirement = iRequirements.next();
+		requirements.removeIf(requirement -> {
 			// check the effective directive;
 			Object effective = requirement.getDirectives().get(Namespace.REQUIREMENT_EFFECTIVE_DIRECTIVE);
 			if (effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective)) {
-				iRequirements.remove();
-			} else {
-
-				if (!wireRequirements.contains(requirement)) {
-					if (!PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace())) {
-						iRequirements.remove();
-					} else {
-						Object resolution = requirement.getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
-						if (!PackageNamespace.RESOLUTION_DYNAMIC.equals(resolution)) {
-							iRequirements.remove();
-						}
-					}
+				return true;
+			}
+			if (!wireRequirements.contains(requirement)) {
+				if (!PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace())) {
+					return true;
+				}
+				Object resolution = requirement.getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
+				if (!PackageNamespace.RESOLUTION_DYNAMIC.equals(resolution)) {
+					return true;
 				}
 			}
-		}
+			return false;
+		});
 	}
 
-	void removeNonEffectiveCapabilities(ListIterator<ModuleCapability> iCapabilities) {
-		rewind(iCapabilities);
-		while (iCapabilities.hasNext()) {
-			Capability capability = iCapabilities.next();
+	void removeNonEffectiveCapabilities(Collection<ModuleCapability> capabilities) {
+		capabilities.removeIf(capability -> {
 			Object effective = capability.getDirectives().get(Namespace.CAPABILITY_EFFECTIVE_DIRECTIVE);
 			if (effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective)) {
-				iCapabilities.remove();
 				if (DEBUG_PROVIDERS) {
 					Debug.println(new StringBuilder("RESOLVER: Capability filtered because it was not effective") //$NON-NLS-1$
 							.append(SEPARATOR).append(TAB) //
@@ -384,16 +329,18 @@
 							.append(capability.getResource()) //
 							.toString());
 				}
+				return true;
 			}
-		}
+			return false;
+		});
 	}
 
-	private static void addPayloadContent(List<ModuleWire> hostWires, ListIterator<ModuleCapability> iCapabilities, ListIterator<ModuleRequirement> iRequirements) {
+	private static void addPayloadContent(List<ModuleWire> hostWires, NamespaceList.Builder<ModuleCapability> capabilities, NamespaceList.Builder<ModuleRequirement> requirements) {
 		if (hostWires == null)
 			return;
 		for (ModuleWire hostWire : hostWires) {
+
 			// add fragment capabilities
-			String currentNamespace = null;
 			List<ModuleCapability> fragmentCapabilities = hostWire.getRequirer().getModuleCapabilities(null);
 			for (ModuleCapability fragmentCapability : fragmentCapabilities) {
 				if (NON_PAYLOAD_CAPABILITIES.contains(fragmentCapability.getNamespace())) {
@@ -403,23 +350,10 @@
 				if (effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective)) {
 					continue; // don't include, not effective
 				}
-				if (!fragmentCapability.getNamespace().equals(currentNamespace)) {
-					currentNamespace = fragmentCapability.getNamespace();
-					fastForward(iCapabilities);
-					while (iCapabilities.hasPrevious()) {
-						if (iCapabilities.previous().getNamespace().equals(currentNamespace)) {
-							iCapabilities.next(); // put position after the last one
-							break;
-						}
-					}
-				}
-				if (!iCapabilities.hasPrevious()) {
-					fastForward(iCapabilities);
-				}
-				iCapabilities.add(fragmentCapability);
+				capabilities.add(fragmentCapability);
 			}
+
 			// add fragment requirements
-			currentNamespace = null;
 			List<ModuleRequirement> fragmentRequriements = hostWire.getRequirer().getModuleRequirements(null);
 			for (ModuleRequirement fragmentRequirement : fragmentRequriements) {
 				if (NON_PAYLOAD_REQUIREMENTS.contains(fragmentRequirement.getNamespace())) {
@@ -429,24 +363,12 @@
 				if (effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective)) {
 					continue; // don't include, not effective
 				}
-				if (!fragmentRequirement.getNamespace().equals(currentNamespace)) {
-					currentNamespace = fragmentRequirement.getNamespace();
-					boolean isDynamic = isDynamic(fragmentRequirement);
-					fastForward(iRequirements);
-					while (iRequirements.hasPrevious()) {
-						ModuleRequirement previous = iRequirements.previous();
-						if (previous.getNamespace().equals(currentNamespace)) {
-							if (isDynamic || !isDynamic(previous)) {
-								iRequirements.next(); // put position after the last one
-								break;
-							}
-						}
-					}
+				if (!PackageNamespace.PACKAGE_NAMESPACE.equals(fragmentRequirement.getNamespace())
+						|| isDynamic(fragmentRequirement)) {
+					requirements.add(fragmentRequirement);
+				} else {
+					requirements.addAfterLastMatch(fragmentRequirement, r -> !isDynamic(r));
 				}
-				if (!iRequirements.hasPrevious()) {
-					fastForward(iRequirements);
-				}
-				iRequirements.add(fragmentRequirement);
 			}
 		}
 	}
@@ -455,61 +377,24 @@
 		return PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace()) && PackageNamespace.RESOLUTION_DYNAMIC.equals(requirement.getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE));
 	}
 
-	private static void addProvidedWires(Map<ModuleCapability, List<ModuleWire>> toAdd, List<ModuleWire> existing, final List<ModuleCapability> orderedCapabilities) {
+	private static void addProvidedWires(Map<ModuleCapability, List<ModuleWire>> toAdd,
+			NamespaceList.Builder<ModuleWire> existing, NamespaceList.Builder<ModuleCapability> capabilities) {
 		if (toAdd == null)
 			return;
-		int originalSize = existing.size();
-		for (ModuleCapability capability : orderedCapabilities) {
+		for (ModuleCapability capability : capabilities) {
 			List<ModuleWire> newWires = toAdd.get(capability);
 			if (newWires != null) {
 				existing.addAll(newWires);
 			}
 		}
-		if (originalSize != 0) {
-			Collections.sort(existing, new Comparator<ModuleWire>() {
-				@Override
-				public int compare(ModuleWire w1, ModuleWire w2) {
-					int index1 = orderedCapabilities.indexOf(w1.getCapability());
-					int index2 = orderedCapabilities.indexOf(w2.getCapability());
-					return index1 - index2;
-				}
-			});
-		}
 	}
 
-	private static void addRequiredWires(List<ModuleWire> toAdd, List<ModuleWire> existing, final List<ModuleRequirement> orderedRequirements) {
-		if (toAdd == null)
-			return;
-		int originalSize = existing.size();
-		existing.addAll(toAdd);
-		if (originalSize != 0) {
-			Collections.sort(existing, new Comparator<ModuleWire>() {
-				@Override
-				public int compare(ModuleWire w1, ModuleWire w2) {
-					int index1 = orderedRequirements.indexOf(w1.getRequirement());
-					int index2 = orderedRequirements.indexOf(w2.getRequirement());
-					return index1 - index2;
-				}
-			});
-		}
-	}
-
-	private static void fastForward(ListIterator<?> listIterator) {
-		while (listIterator.hasNext())
-			listIterator.next();
-	}
-
-	static void rewind(ListIterator<?> listIterator) {
-		while (listIterator.hasPrevious())
-			listIterator.previous();
-	}
-
-	private static ModuleWiring createWiringDelta(ModuleRevision revision, ModuleWiring existingWiring, Map<ModuleCapability, List<ModuleWire>> providedWireMap, List<ModuleWire> requiredWires) {
+	private static ModuleWiring createWiringDelta(ModuleRevision revision, ModuleWiring existingWiring, Map<ModuleCapability, List<ModuleWire>> providedWireMap, NamespaceList<ModuleWire> requiredWires) {
 		// No null checks are done here on the wires since this is a copy.
-		List<ModuleWire> existingProvidedWires = existingWiring.getProvidedWires().copyList();
-		List<ModuleCapability> existingCapabilities = existingWiring.getCapabilities().copyList();
-		List<ModuleWire> existingRequiredWires = existingWiring.getRequiredWires().copyList();
-		List<ModuleRequirement> existingRequirements = existingWiring.getRequirements().copyList();
+		NamespaceList.Builder<ModuleWire> existingProvidedWires = existingWiring.getProvidedWires().createBuilder();
+		NamespaceList.Builder<ModuleCapability> existingCapabilities = existingWiring.getCapabilities().createBuilder();
+		NamespaceList.Builder<ModuleWire> existingRequiredWires = existingWiring.getRequiredWires().createBuilder();
+		NamespaceList.Builder<ModuleRequirement> existingRequirements = existingWiring.getRequirements().createBuilder();
 
 		// First, add newly resolved fragment capabilities and requirements
 		if (providedWireMap != null) {
@@ -517,7 +402,7 @@
 			ModuleCapability hostCapability = hostCapabilities.isEmpty() ? null : hostCapabilities.get(0);
 			List<ModuleWire> newHostWires = hostCapability == null ? null : providedWireMap.get(hostCapability);
 			if (newHostWires != null) {
-				addPayloadContent(newHostWires, existingCapabilities.listIterator(), existingRequirements.listIterator());
+				addPayloadContent(newHostWires, existingCapabilities, existingRequirements);
 			}
 		}
 
@@ -526,11 +411,13 @@
 
 		// Also need to include any new required wires that may have be added for fragment hosts
 		// Also will be needed for dynamic imports
-		addRequiredWires(requiredWires, existingRequiredWires, existingRequirements);
+		if (requiredWires != null) {
+			existingRequiredWires.addAll(requiredWires);
+		}
 
 		InternalUtils.filterCapabilityPermissions(existingCapabilities);
-		return new ModuleWiring(revision, existingCapabilities, existingRequirements, existingProvidedWires,
-				existingRequiredWires, existingWiring.getSubstitutedNames());
+		return new ModuleWiring(revision, existingCapabilities.build(), existingRequirements.build(),
+				existingProvidedWires.build(), existingRequiredWires.build(), existingWiring.getSubstitutedNames());
 	}
 
 	static boolean isSingleton(ModuleRevision revision) {
@@ -721,11 +608,10 @@
 		}
 
 		List<Capability> filterProviders(Requirement requirement, List<ModuleCapability> candidates, boolean filterResolvedHosts) {
-			ListIterator<ModuleCapability> iCandidates = candidates.listIterator();
-			filterDisabled(iCandidates);
-			removeNonEffectiveCapabilities(iCandidates);
-			removeSubstituted(iCandidates);
-			filterPermissions((BundleRequirement) requirement, iCandidates);
+			filterDisabled(candidates);
+			removeNonEffectiveCapabilities(candidates);
+			removeSubstituted(candidates);
+			filterPermissions((BundleRequirement) requirement, candidates);
 
 			List<ModuleCapability> filteredMatches = null;
 			if (DEBUG_PROVIDERS || DEBUG_HOOKS) {
@@ -800,9 +686,8 @@
 			}
 		}
 
-		private void filterPermissions(BundleRequirement requirement, ListIterator<ModuleCapability> iCandidates) {
-			rewind(iCandidates);
-			if (System.getSecurityManager() == null || !iCandidates.hasNext()) {
+		private void filterPermissions(BundleRequirement requirement, List<ModuleCapability> candidates) {
+			if (System.getSecurityManager() == null) {
 				return;
 			}
 
@@ -811,18 +696,16 @@
 				return;
 			}
 
-			candidates: while (iCandidates.hasNext()) {
-				ModuleCapability candidate = iCandidates.next();
+			candidates.removeIf(candidate -> {
 				// TODO this is a hack for when a bundle imports and exports the same package
 				if (PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace())) {
 					if (requirement.getRevision().equals(candidate.getRevision())) {
-						continue candidates;
+						return false;
 					}
 				}
 				Permission requirePermission = InternalUtils.getRequirePermission(candidate);
 				Permission providePermission = InternalUtils.getProvidePermission(candidate);
 				if (!requirement.getRevision().getBundle().hasPermission(requirePermission)) {
-					iCandidates.remove();
 					if (DEBUG_PROVIDERS) {
 						Debug.println(new StringBuilder("RESOLVER: Capability filtered because requirer did not have permission") //$NON-NLS-1$
 								.append(SEPARATOR).append(TAB) //
@@ -833,8 +716,8 @@
 								.append(candidate.getResource()) //
 								.toString());
 					}
+					return true;
 				} else if (!candidate.getRevision().getBundle().hasPermission(providePermission)) {
-					iCandidates.remove();
 					if (DEBUG_PROVIDERS) {
 						Debug.println(new StringBuilder("RESOLVER: Capability filtered because provider did not have permission") //$NON-NLS-1$
 								.append(SEPARATOR).append(TAB) //
@@ -845,16 +728,15 @@
 								.append(candidate.getResource()) //
 								.toString());
 					}
+					return true;
 				}
-			}
+				return false;
+			});
 		}
 
-		private void filterDisabled(ListIterator<ModuleCapability> iCandidates) {
-			rewind(iCandidates);
-			while (iCandidates.hasNext()) {
-				Capability capability = iCandidates.next();
+		private void filterDisabled(List<ModuleCapability> candidates) {
+			candidates.removeIf(capability -> {
 				if (disabled.contains(capability.getResource())) {
-					iCandidates.remove();
 					if (DEBUG_PROVIDERS) {
 						Debug.println(new StringBuilder("RESOLVER: Capability filtered because it was disabled") //$NON-NLS-1$
 								.append(SEPARATOR).append(TAB) //
@@ -865,17 +747,16 @@
 								.append(capability.getResource()) //
 								.toString());
 					}
+					return true;
 				}
-			}
+				return false;
+			});
 		}
 
-		private void removeSubstituted(ListIterator<ModuleCapability> iCapabilities) {
-			rewind(iCapabilities);
-			while (iCapabilities.hasNext()) {
-				ModuleCapability capability = iCapabilities.next();
+		private void removeSubstituted(List<ModuleCapability> capabilities) {
+			capabilities.removeIf(capability -> {
 				ModuleWiring wiring = wirings.get(capability.getRevision());
 				if (wiring != null && wiring.isSubtituted(capability)) {
-					iCapabilities.remove();
 					if (DEBUG_PROVIDERS) {
 						Debug.println(new StringBuilder("RESOLVER: Capability filtered because it was substituted") //$NON-NLS-1$
 								.append(SEPARATOR).append(TAB) //
@@ -886,8 +767,10 @@
 								.append(capability.getResource()) //
 								.toString());
 					}
+					return true;
 				}
-			}
+				return false;
+			});
 		}
 
 		@Override
@@ -942,7 +825,7 @@
 				Requirement fragmentRequirement = ModuleContainer.createRequirement(EquinoxFragmentNamespace.FRAGMENT_NAMESPACE, Collections.<String, String> singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, matchFilter), Collections.<String, Object> emptyMap());
 				List<ModuleCapability> candidates = moduleDatabase.findCapabilities(fragmentRequirement);
 				// filter out disabled fragments and singletons
-				filterDisabled(candidates.listIterator());
+				filterDisabled(candidates);
 				for (ModuleCapability candidate : candidates) {
 					ModuleRequirement hostReq = candidate.getRevision().getModuleRequirements(HostNamespace.HOST_NAMESPACE).get(0);
 					for (ModuleCapability hostCap : hostCaps) {
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java
index e63df7f..9e6777e 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012, 2017 IBM Corporation and others.
+ * Copyright (c) 2012, 2021 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -13,10 +13,6 @@
  *******************************************************************************/
 package org.eclipse.osgi.container;
 
-import static org.eclipse.osgi.internal.container.NamespaceList.CAPABILITY;
-import static org.eclipse.osgi.internal.container.NamespaceList.REQUIREMENT;
-import static org.eclipse.osgi.internal.container.NamespaceList.WIRE;
-
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -26,7 +22,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicReference;
@@ -75,17 +70,6 @@
 	volatile boolean isValid = true;
 	private final AtomicReference<Set<String>> dynamicMissRef = new AtomicReference<>();
 
-	ModuleWiring(ModuleRevision revision, List<ModuleCapability> capabilities, List<ModuleRequirement> requirements,
-			List<ModuleWire> providedWires, List<ModuleWire> requiredWires, Collection<String> substitutedPkgNames) {
-		super();
-		this.revision = revision;
-		this.capabilities = new NamespaceList<>(capabilities, CAPABILITY);
-		this.requirements = new NamespaceList<>(requirements, REQUIREMENT);
-		this.providedWires = new NamespaceList<>(providedWires, WIRE);
-		this.requiredWires = new NamespaceList<>(requiredWires, WIRE);
-		this.substitutedPkgNames = substitutedPkgNames.isEmpty() ? Collections.<String> emptyList() : substitutedPkgNames;
-	}
-
 	ModuleWiring(ModuleRevision revision, NamespaceList<ModuleCapability> capabilities,
 			NamespaceList<ModuleRequirement> requirements, NamespaceList<ModuleWire> providedWires,
 			NamespaceList<ModuleWire> requiredWires, Collection<String> substitutedPkgNames) {
@@ -156,7 +140,7 @@
 		if (!isValid) {
 			return null;
 		}
-		List<ModuleRequirement> persistentRequriements = requirements.copyList();
+		List<ModuleRequirement> persistentRequriements = new ArrayList<>(requirements.getList(null));
 		for (Iterator<ModuleRequirement> iRequirements = persistentRequriements.iterator(); iRequirements.hasNext();) {
 			ModuleRequirement requirement = iRequirements.next();
 			if (PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace())) {
@@ -213,7 +197,7 @@
 		if (!isValid) {
 			return null;
 		}
-		List<ModuleWire> persistentWires = allWires.copyList();
+		List<ModuleWire> persistentWires = new ArrayList<>(allWires.getList(null));
 		for (Iterator<ModuleWire> iWires = persistentWires.iterator(); iWires.hasNext();) {
 			ModuleWire wire = iWires.next();
 			if (PackageNamespace.PACKAGE_NAMESPACE.equals(wire.getRequirement().getNamespace())) {
@@ -436,15 +420,9 @@
 		ModuleDatabase moduleDatabase = revision.getRevisions().getContainer().moduleDatabase;
 		moduleDatabase.writeLock();
 		try {
-			List<ModuleRequirement> updatedRequirements = requirements.copyList();
-			Entry<Integer, Integer> packageStartEnd = requirements
-					.getNamespaceIndex(PackageNamespace.PACKAGE_NAMESPACE);
-			if (packageStartEnd == null) {
-				updatedRequirements.addAll(newRequirements);
-			} else {
-				updatedRequirements.addAll(packageStartEnd.getValue(), newRequirements);
-			}
-			requirements = new NamespaceList<>(updatedRequirements, REQUIREMENT);
+			NamespaceList.Builder<ModuleRequirement> requirmentsBuilder = requirements.createBuilder();
+			requirmentsBuilder.addAll(newRequirements);
+			requirements = requirmentsBuilder.build();
 		} finally {
 			moduleDatabase.writeUnlock();
 		}
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/NamespaceList.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/NamespaceList.java
index 74375c1..ce320de 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/NamespaceList.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/NamespaceList.java
@@ -10,154 +10,402 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Hannes Wellmann - Bug 573025: introduce and apply NamespaceList.Builder
  *******************************************************************************/
 package org.eclipse.osgi.internal.container;
 
-import java.util.AbstractMap;
+import java.util.AbstractCollection;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
+import java.util.NoSuchElementException;
 import java.util.function.Function;
+import java.util.function.Predicate;
 import org.eclipse.osgi.container.ModuleCapability;
 import org.eclipse.osgi.container.ModuleRequirement;
 import org.eclipse.osgi.container.ModuleWire;
 
 /**
- * An immutable list of elements for which each element has a name space. All
- * elements are kept in a single list to avoid creating a list for each name
- * space. The elements provided at construction are assumed to be ordered such
- * that all elements with the same name space are ordered together in one
- * continuous sequence An indexes list is used to keep track of the beginning
- * indexes for each namespace contained in the list. Assuming the number of
- * namespaces used by a bundle is relatively small compared to the overall
- * number of elements this makes it faster to find the first index for a
- * specific namespace without having to iterate over the complete list of
- * elements.
+ * An immutable list of elements for which each element has a namespace.
+ * <p>
+ * The elements are stored in a map where each key is a namespace and the
+ * associated value is the list of all elements with that namespace in this
+ * NamespaceList. Within one namespace the element's order is stable. Due to
+ * this internal structure access to the elements of off one or all namespace(s)
+ * has always constant runtime regardless of the number of namespaces present.
+ * <p>
  * 
- * @param <E> The element type which will have a name space associated with it
+ * @param <E> the type of elements in this list, which have a name-space
+ *            associated
  */
 public class NamespaceList<E> {
 
-	public final static Function<ModuleWire, String> WIRE = wire -> {
-		return wire.getCapability().getNamespace();
-	};
+	public final static Function<ModuleWire, String> WIRE = wire -> wire.getCapability().getNamespace();
 	public final static Function<ModuleCapability, String> CAPABILITY = ModuleCapability::getNamespace;
 	public final static Function<ModuleRequirement, String> REQUIREMENT = ModuleRequirement::getNamespace;
 
+	/**
+	 * Returns an empty NamespaceList.
+	 * <p>
+	 * The required argument is used to derive the type of elements and if a builder
+	 * is created from the returned list.
+	 * </p>
+	 * 
+	 * @param <E>          the type of elements in the NamespaceList
+	 * @param getNamespace the function to compute the namespace of an element
+	 * @return an empty NamespaceList
+	 */
+	public static <E> NamespaceList<E> empty(Function<E, String> getNamespace) {
+		return new NamespaceList<>(getNamespace, Collections.emptyMap(), Collections.emptyList());
+	}
+
 	private final List<E> elements;
 	private final Map<String, List<E>> namespaces;
+	private final Function<E, String> getNamespace;
+
+	NamespaceList(Function<E, String> getNamespace, Map<String, List<E>> namespaces, List<E> fullList) {
+		this.getNamespace = getNamespace;
+		this.namespaces = namespaces;
+		this.elements = fullList;
+	}
+
+	Map<String, List<E>> namespaces() {
+		return namespaces;
+	}
 
 	/**
-	 * Create a new name space list with the specified elements. The elements must
-	 * be sorted properly by name space.
+	 * Returns {@code true} if this NamespaceList contains no elements.
 	 * 
-	 * @param elements     the ordered list of elements
-	 * @param getNamespace a function that retrieves the namespace for each element
+	 * @return {@code true} if this list contains no elements
 	 */
-	public NamespaceList(List<E> elements, Function<E, String> getNamespace) {
-		List<E> unmodifiableElements = Collections.unmodifiableList(elements);
-
-		Map<String, List<E>> tmpNamespaces = new LinkedHashMap<>(5);
-		int size = unmodifiableElements.size();
-		int currentStart = 0;
-		String current = null;
-
-		boolean consolidated = false;
-		for (int i = 0; i < size; i++) {
-			String namespace = getNamespace.apply(unmodifiableElements.get(i));
-			if (current == null) {
-				current = namespace;
-			}
-			if (!current.equals(namespace)) {
-				int currentEnd = i;
-				consolidated |= addNamespaceList(tmpNamespaces, unmodifiableElements, current, currentStart,
-						currentEnd);
-				current = namespace;
-				currentStart = i;
-			}
-		}
-		if (size > 0) {
-			// add the last namespace
-			consolidated |= addNamespaceList(tmpNamespaces, unmodifiableElements, current, currentStart, size);
-		}
-		if (consolidated) {
-			List<E> tmpElements = new ArrayList<>(size);
-			for (Entry<String, List<E>> e : tmpNamespaces.entrySet()) {
-				tmpElements.addAll(e.getValue());
-			}
-			this.elements = Collections.unmodifiableList(tmpElements);
-		} else {
-			this.elements = unmodifiableElements;
-		}
-		this.namespaces = Collections.unmodifiableMap(tmpNamespaces);
-	}
-
-	private boolean addNamespaceList(Map<String, List<E>> tmpNamespaces, List<E> unmodifiableElements, String namespace,
-			int start, int end) {
-		List<E> namespaceList = unmodifiableElements.subList(start, end);
-		List<E> existing = tmpNamespaces.get(namespace);
-		boolean consolidated = false;
-		if (existing != null) {
-			// This should be an error, consolidate the lists
-			List<E> consolidateList = new ArrayList<>(existing);
-			consolidateList.addAll(namespaceList);
-			namespaceList = Collections.unmodifiableList(consolidateList);
-			consolidated = true;
-		}
-		tmpNamespaces.put(namespace, namespaceList);
-		return consolidated;
-	}
-
 	public boolean isEmpty() {
 		return elements.isEmpty();
 	}
 
 	/**
-	 * returns an unmodifiable list of elements with the specified name space. An
-	 * empty list is returned if there are no elements with the specified namespace.
-	 * A {@code null} namespace can be used to get all elements.
+	 * Returns an immutable list of elements with the specified namespace.
+	 * <p>
+	 * An empty list is returned if there are no elements with the specified
+	 * namespace. For the {@code null} namespace the elements of all namespaces are
+	 * returned as flat.
+	 * </p>
 	 * 
-	 * @param namespace the name space of the elements to return. May be
-	 *                  {@code null}
+	 * @param namespace the namespace of the elements to return. May be {@code null}
 	 * @return The list of elements found
 	 */
 	public List<E> getList(String namespace) {
 		if (namespace == null) {
 			return elements;
 		}
-
 		return namespaces.getOrDefault(namespace, Collections.emptyList());
 	}
 
 	/**
-	 * Returns the beginning index (inclusively) and ending index (exclusively) or
-	 * {@code null} if no element has the specified namespace
+	 * Returns a new {@link Builder NamespaceList.Builder} that contains all
+	 * elements of this NamespaceList.
+	 * <p>
+	 * The returned builder uses the same function to compute the namespace of an
+	 * element like this NamespaceList.
+	 * </p>
 	 * 
-	 * @param namespace the name space to find the indexes for
-	 * @return indexes found for the namespace or {@code null} if no elements exist
-	 *         with the name space.
+	 * @return a new builder containing all elements of this list
 	 */
-	public Entry<Integer, Integer> getNamespaceIndex(String namespace) {
-		int startIndex = 0;
-		for (Entry<String, ? extends List<E>> entry : namespaces.entrySet()) {
-			if (entry.getKey().equals(namespace)) {
-				int end = startIndex + entry.getValue().size();
-				return new AbstractMap.SimpleEntry<>(startIndex, end);
-			}
-			startIndex += entry.getValue().size();
-		}
-		return null;
+	public Builder<E> createBuilder() {
+		Builder<E> builder = Builder.create(getNamespace);
+		builder.addAll(this);
+		return builder;
 	}
 
 	/**
-	 * Returns a copy of all the elements in this list
+	 * A reusable builder to create {@link NamespaceList NamespaceLists}.
 	 * 
-	 * @return a copy of all the elements in this list
+	 * @param <E> the type of elements in this builder
+	 * @author Hannes Wellmann
 	 */
-	public List<E> copyList() {
-		return new ArrayList<>(elements);
+	public static class Builder<E> extends AbstractCollection<E> {
+
+		/**
+		 * Returns a new {@link Builder NamespaceList.Builder} that uses the specified
+		 * function to compute the namespace of its elements.
+		 * 
+		 * @param <E>          the type of elements in this builder
+		 * @param getNamespace the function to compute the namespace of an element
+		 * @return a new builder
+		 */
+		public static <E> Builder<E> create(Function<E, String> getNamespace) {
+			return new Builder<>(getNamespace, 3);
+		}
+
+		private final Function<E, String> getNamespace;
+		private LinkedHashMap<String, List<E>> namespaceElements;
+		private int size = 0;
+
+		private List<E> lastBuildElements;
+
+		private Builder(Function<E, String> getNamespace, int expectedNamespaces) {
+			this.getNamespace = getNamespace;
+			this.namespaceElements = new LinkedHashMap<>(expectedNamespaces * 4 / 3 + 1);
+		}
+
+		@Override
+		public int size() {
+			return size;
+		}
+
+		@Override
+		public Iterator<E> iterator() {
+			prepareModification();
+
+			final Iterator<? extends List<E>> outer = namespaceElements.values().iterator();
+			return new Iterator<E>() {
+				Iterator<E> inner = Collections.emptyIterator();
+				List<E> lastInnerList = null;
+
+				@Override
+				public boolean hasNext() {
+					while (!inner.hasNext() && outer.hasNext()) {
+						lastInnerList = outer.next();
+						inner = lastInnerList.iterator();
+					}
+					return inner.hasNext();
+				}
+
+				public E next() {
+					if (!hasNext()) {
+						throw new NoSuchElementException();
+					}
+					return inner.next();
+				}
+
+				@Override
+				@SuppressWarnings("synthetic-access")
+				public void remove() {
+					inner.remove();
+					Builder.this.size--;
+					if (lastInnerList.isEmpty()) {
+						outer.remove();
+					}
+				}
+			};
+		}
+
+		@Override
+		public void clear() {
+			namespaceElements = new LinkedHashMap<>(); // could have been build before, so map must not be cleared
+			lastBuildElements = null;
+			size = 0;
+		}
+
+		// --- addition ---
+
+		@Override
+		public boolean add(E e) {
+			prepareModification();
+
+			String namespace = getNamespace.apply(e);
+			getNamespaceList(namespace).add(e);
+			this.size++;
+			return true;
+		}
+
+		@Override
+		public boolean addAll(Collection<? extends E> c) {
+			if (c.isEmpty()) {
+				return false;
+			}
+			prepareModification();
+
+			String currentNamespace = null; // $NON-NLS-1$
+			List<E> currentNamespaceList = null;
+			for (E e : c) {
+				String namespace = getNamespace.apply(e);
+				// optimization if elements are already grouped per namespace
+				if (currentNamespace == null || !currentNamespace.equals(namespace)) {
+					currentNamespace = namespace;
+					currentNamespaceList = getNamespaceList(namespace);
+				}
+				currentNamespaceList.add(e);
+			}
+			this.size += c.size();
+			return true;
+		}
+
+		/**
+		 * Adds all elements in the specified NamespaceList to this builder.
+		 * 
+		 * @param list the NamespaceList containing elements to be added
+		 * @return true if any element was added to this builder
+		 */
+		public boolean addAll(NamespaceList<E> list) {
+			if (list.isEmpty()) {
+				return false;
+			}
+			prepareModification();
+
+			list.namespaces().forEach((n, es) -> {
+				getNamespaceList(n).addAll(es);
+				this.size += es.size();
+			});
+			return true;
+		}
+
+		private List<E> getNamespaceList(String namespace) {
+			return namespaceElements.computeIfAbsent(namespace, n -> new ArrayList<>());
+		}
+
+		public void addAfterLastMatch(E toAdd, Predicate<E> matcher) {
+			prepareModification();
+
+			String namespace = getNamespace.apply(toAdd);
+			List<E> namespaceList = getNamespaceList(namespace);
+			addAfterLastMatch(toAdd, namespaceList, matcher);
+			this.size++;
+		}
+
+		private void addAfterLastMatch(E e, List<E> list, Predicate<E> matcher) {
+			for (int i = list.size() - 1; 0 <= i; i--) {
+				if (matcher.test(list.get(i))) {
+					list.add(i + 1, e);
+					return;
+				}
+			}
+			list.add(0, e);
+		}
+
+		// --- removal ---
+
+		@Override
+		public boolean remove(Object o) {
+			@SuppressWarnings("unchecked")
+			E e = (E) o;
+			String namespace;
+			try {
+				namespace = getNamespace.apply(e);
+			} catch (ClassCastException ex) {
+				return false; // e does not seem to be of type E after all
+			}
+			prepareModification();
+
+			int sizeBefore = this.size;
+			removeNamespaceElement(namespace, e);
+			return this.size < sizeBefore;
+		}
+
+		private void removeNamespaceElement(String namespace, E element) {
+			namespaceElements.computeIfPresent(namespace, (n, es) -> {
+				if (es.remove(element)) {
+					this.size--;
+				}
+				return es.isEmpty() ? null : es;
+			});
+		}
+
+		@Override
+		public boolean removeAll(Collection<?> c) {
+			if (c.isEmpty()) {
+				return false;
+			}
+			prepareModification();
+
+			// this is more efficient than the super implementation
+			boolean removed = false;
+			for (Object e : c) {
+				removed |= remove(e);
+			}
+			return removed;
+		}
+
+		/**
+		 * Removes from this builder all elements of each namespace that satisfies the
+		 * specified predicate.
+		 * 
+		 * @param filter the predicate which returns true for a namespace to remove
+		 */
+		public void removeNamespaceIf(Predicate<String> filter) {
+			prepareModification();
+
+			namespaceElements.entrySet().removeIf(e -> {
+				if (filter.test(e.getKey())) {
+					this.size -= e.getValue().size();
+					return true;
+				}
+				return false;
+			});
+		}
+
+		@Override
+		public boolean removeIf(Predicate<? super E> filter) {
+			prepareModification();
+
+			int s = size;
+			namespaceElements.values().removeIf(es -> removeElementsIf(es, filter) == null);
+			return size < s;
+		}
+
+		/**
+		 * Removes from this builder those elements of the specified namespace that
+		 * satisfy the specified predicate.
+		 * 
+		 * @param namespace the namespace of
+		 * @param filter    the predicate which returns true for elements to remove
+		 */
+		public void removeElementsOfNamespaceIf(String namespace, Predicate<? super E> filter) {
+			prepareModification();
+
+			namespaceElements.computeIfPresent(namespace, (n, es) -> removeElementsIf(es, filter));
+		}
+
+		private List<E> removeElementsIf(List<E> list, Predicate<? super E> filter) {
+			int sizeBefore = list.size();
+			list.removeIf(filter);
+			this.size -= sizeBefore - list.size();
+			return list.isEmpty() ? null : list;
+		}
+
+		// --- build ---
+
+		/**
+		 * Returns an immutable {@link NamespaceList} containing a snapshot of the
+		 * current elements of this builder.
+		 * <p>
+		 * The content of this builder is not changed by this call and subsequent
+		 * modifications to this builder do not reflect into the returned list (the
+		 * returned list is not connected to this builder at all).
+		 * </p>
+		 * 
+		 * @return a {@link NamespaceList} reflecting the current state of this builder
+		 */
+		public NamespaceList<E> build() {
+			if (size == 0) {
+				return empty(getNamespace);
+			}
+			if (lastBuildElements == null) {
+				lastBuildElements = new ArrayList<>(size);
+				namespaceElements.values().forEach(lastBuildElements::addAll);
+				lastBuildElements = Collections.unmodifiableList(lastBuildElements);
+
+				int[] start = new int[] { 0 };
+				namespaceElements.replaceAll((n, es) -> {
+					int from = start[0];
+					int to = start[0] += es.size();
+					return lastBuildElements.subList(from, to);
+				});
+			}
+			return new NamespaceList<>(getNamespace, namespaceElements, lastBuildElements);
+		}
+
+		private void prepareModification() {
+			if (lastBuildElements != null) {
+				// this builder was build before. Create a copy of the Map and their
+				// namespace-lists for subsequent modification
+				namespaceElements = new LinkedHashMap<>(namespaceElements);
+				namespaceElements.replaceAll((n, es) -> new ArrayList<>(es));
+				lastBuildElements = null;
+			}
+		}
 	}
 }
