diff --git a/src/004-base/000-proxies.js b/src/004-base/000-proxies.js
index 69b72acd7d6e9cf89d4301989b3a20a0c8de9df6..9738e68bf063ed42b792f6cf905465fcf22ba7f9 100644
--- a/src/004-base/000-proxies.js
+++ b/src/004-base/000-proxies.js
@@ -1,43 +1,50 @@
 (function() {
 	const readOnlySymbol = Symbol("readonly proxy");
+	const dummy = () => true;
+
+	/**
+	 * Creates a readonly proxy for all the target properties except banned methods
+	 * @param {any} target
+	 * @param {string[]} bannedMethodNames The list of method names that are banned and can't be accesses via the proxy
+	 * @param {string} errorMessage message for throwing exceptions
+	 */
+	const createProxyWithBannedMethods = (target, bannedMethodNames, errorMessage) => {
+		return new Proxy(target, {
+			get: function(o, prop) {
+				if (prop === readOnlySymbol) { return true; }
+				const val = o[prop];
+				if (typeof val === 'function') {
+					if (bannedMethodNames.includes(prop)) {
+						return function() {
+							throw Error(errorMessage);
+						};
+					}
+					return val.bind(target);
+				}
+				return createReadonlyProxy(val);
+			},
+			set: dummy,
+			deleteProperty: dummy
+		});
+	};
+
 	globalThis.createReadonlyProxy = function(target) {
 		if (target == null) { return target; } // intentionally ==
 		if (target[readOnlySymbol]) { return target; }
 		if (_.isArray(target)) {
-			return new Proxy(target, {
-				get: function(o, prop) {
-					if (prop === readOnlySymbol) { return true; }
-					const val = o[prop];
-					if (typeof val === 'function') {
-						if (['push', 'unshift', 'pop'].includes(prop)) {
-							return function() {
-								throw Error("Cannot modify a readonly array");
-							};
-						}
-						return val.bind(target);
-					}
-					return createReadonlyProxy(val);
-				},
-				set: function(o, prop, value) {
-					return true;
-				},
-				deleteProperty: function(o, prop) {
-					return true;
-				}
-			});
-		}
-		if (_.isObject(target)) {
+			return createProxyWithBannedMethods(target, ['push', 'unshift', 'pop'], "Cannot modify a readonly array");
+		} else if (_.isMap(target)) {
+			return createProxyWithBannedMethods(target, ['clear', 'delete', 'set'], "Cannot modify a readonly Map");
+		} else if (_.isSet(target)) {
+			return createProxyWithBannedMethods(target, ['add', 'clear', 'delete'], "Cannot modify a readonly Set");
+		} else if (_.isObject(target)) {
 			return new Proxy(target, {
 				get: function(o, prop) {
 					if (prop === readOnlySymbol) { return true; }
 					return createReadonlyProxy(o[prop]);
 				},
-				set: function(o, prop, value) {
-					return true;
-				},
-				deleteProperty: function(o, prop) {
-					return true;
-				}
+				set: dummy,
+				deleteProperty: dummy
 			});
 		}
 		return target;