class MemoryManagerFactory implements Function<RamAccounting, MemoryManager> {


    enum MemoryType {
        ON_HEAP("on-heap"),
        OFF_HEAP("off-heap");

        private final String value;

        MemoryType(String value) {
            this.value = value;
        }

        public String value() {
            return value;
        }

        public static MemoryType of(String value) {
            if (value.equals(ON_HEAP.value)) {
                return ON_HEAP;
            } else if (value.equals(OFF_HEAP.value)) {
                return OFF_HEAP;
            }
            throw new IllegalArgumentException("Invalid memory type `" + value + "`. Expected one of: " + TYPES);
        }
    }

    private static final Set<String> TYPES = Set.of(MemoryType.OFF_HEAP.value(), MemoryType.ON_HEAP.value());

    // Explicit generic is required for eclipse JDT, otherwise it won't compile
    public static final Setting<String> MEMORY_ALLOCATION_TYPE = new Setting<String>(
        "memory.allocation.type",
        MemoryType.ON_HEAP.value(),
        input -> {
            if (TYPES.contains(input)) {
                return input;
            }
            throw new IllegalArgumentException(
                "Invalid argument `" + input + "` for `memory.allocation.type`, valid values are: " + TYPES);
        },
        DataTypes.STRING,
        Property.NodeScope,
        Property.Dynamic,
        Property.Exposed
    );

    private volatile MemoryType currentMemoryType = MemoryType.ON_HEAP;

    @Inject
    public MemoryManagerFactory(ClusterSettings clusterSettings) {
        clusterSettings.addSettingsUpdateConsumer(MEMORY_ALLOCATION_TYPE, newValue -> {
            currentMemoryType = MemoryType.of(newValue);
        });
    }

    /**
     * @return a MemoryManager instance that doesn't support concurrent access.
     *         Any component acquiring a MemoryManager must make sure to close it after use.
     */
    public MemoryManager getMemoryManager(RamAccounting ramAccounting) {<FILL_FUNCTION_BODY>}

    @Override
    public MemoryManager apply(RamAccounting ramAccounting) {
        return getMemoryManager(ramAccounting);
    }
}

        switch (currentMemoryType) {
            case ON_HEAP:
                return new OnHeapMemoryManager(ramAccounting::addBytes);
            case OFF_HEAP:
                return new OffHeapMemoryManager();
            default:
                throw new AssertionError("MemoryType is supposed to have only 2 cases");
        }
    
<no_super_class>