_cleverMerge = (first, second, internalCaching = false) => {
	const firstObject = internalCaching
		? cachedParseObject(first)
		: parseObject(first);
	const { static: firstInfo, dynamic: firstDynamicInfo } = firstObject;

	// If the first argument has a dynamic part we modify the dynamic part to merge the second argument
	if (firstDynamicInfo !== undefined) {
		let { byProperty, fn } = firstDynamicInfo;
		const fnInfo = fn[DYNAMIC_INFO];
		if (fnInfo) {
			second =
				/** @type {TODO} */
				(
					internalCaching
						? cachedCleverMerge(fnInfo[1], second)
						: cleverMerge(fnInfo[1], second)
				);
			fn = fnInfo[0];
		}
		/** @type {DynamicFunction} */
		const newFn = (...args) => {
			const fnResult = fn(...args);
			return internalCaching
				? cachedCleverMerge(fnResult, second)
				: cleverMerge(fnResult, second);
		};
		newFn[DYNAMIC_INFO] = [fn, second];
		return /** @type {T & O} */ (
			serializeObject(firstObject.static, { byProperty, fn: newFn })
		);
	}

	// If the first part is static only, we merge the static parts and keep the dynamic part of the second argument
	const secondObject = internalCaching
		? cachedParseObject(second)
		: parseObject(second);
	const { static: secondInfo, dynamic: secondDynamicInfo } = secondObject;
	/** @type {Map<string, ObjectParsedPropertyEntry>} */
	const resultInfo = new Map();
	for (const [key, firstEntry] of firstInfo) {
		const secondEntry = secondInfo.get(key);
		const entry =
			secondEntry !== undefined
				? mergeEntries(firstEntry, secondEntry, internalCaching)
				: firstEntry;
		resultInfo.set(key, entry);
	}
	for (const [key, secondEntry] of secondInfo) {
		if (!firstInfo.has(key)) {
			resultInfo.set(key, secondEntry);
		}
	}
	return /** @type {T & O} */ (serializeObject(resultInfo, secondDynamicInfo));
}
@template {object} T
@template {object} O
Merges two objects. Objects are deeply clever merged.
@param {T} first first
@param {O} second second
@param {boolean} internalCaching should parsing of objects and nested merges be cached
@returns {T & O} merged object of first and second object