diff --git a/src/main/java/gripe/_90/appliede/me/strategy/EMCExportStrategy.java b/src/main/java/gripe/_90/appliede/me/strategy/EMCExportStrategy.java
index e402899..105c441 100644
--- a/src/main/java/gripe/_90/appliede/me/strategy/EMCExportStrategy.java
+++ b/src/main/java/gripe/_90/appliede/me/strategy/EMCExportStrategy.java
@@ -1,5 +1,7 @@
 package gripe._90.appliede.me.strategy;
 
+import java.util.concurrent.atomic.AtomicLong;
+
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
 import net.minecraft.server.level.ServerLevel;
@@ -9,7 +11,6 @@
 import appeng.api.config.Actionable;
 import appeng.api.stacks.AEKey;
 import appeng.api.storage.StorageHelper;
-import appeng.util.BlockApiCache;
 
 import gripe._90.appliede.me.key.EMCKey;
 
@@ -17,24 +18,22 @@
 import moze_intel.projecte.api.capabilities.block_entity.IEmcStorage;
 
 @SuppressWarnings("UnstableApiUsage")
-public class EMCExportStrategy implements StackExportStrategy {
-    private final BlockApiCache<IEmcStorage> apiCache;
-    private final Direction fromSide;
-
-    public EMCExportStrategy(ServerLevel level, BlockPos fromPos, Direction fromSide) {
-        apiCache = BlockApiCache.create(PECapabilities.EMC_STORAGE_CAPABILITY, level, fromPos);
-        this.fromSide = fromSide;
-    }
-
+public record EMCExportStrategy(ServerLevel level, BlockPos pos, Direction side) implements StackExportStrategy {
     @Override
     public long transfer(StackTransferContext context, AEKey what, long maxAmount) {
         if (!(what instanceof EMCKey)) {
             return 0;
         }
 
-        var emcStorage = apiCache.find(fromSide);
+        var be = level.getBlockEntity(pos);
+
+        if (be == null) {
+            return 0;
+        }
+
+        var transferred = new AtomicLong(0);
 
-        if (emcStorage != null) {
+        be.getCapability(PECapabilities.EMC_STORAGE_CAPABILITY).ifPresent(emcStorage -> {
             var insertable = emcStorage.insertEmc(maxAmount, IEmcStorage.EmcAction.SIMULATE);
             var extracted = StorageHelper.poweredExtraction(
                     context.getEnergySource(),
@@ -48,10 +47,10 @@ public long transfer(StackTransferContext context, AEKey what, long maxAmount) {
                 emcStorage.insertEmc(extracted, IEmcStorage.EmcAction.EXECUTE);
             }
 
-            return extracted;
-        }
+            transferred.addAndGet(extracted);
+        });
 
-        return 0;
+        return transferred.get();
     }
 
     @Override
@@ -60,18 +59,24 @@ public long push(AEKey what, long maxAmount, Actionable mode) {
             return 0;
         }
 
-        var emcStorage = apiCache.find(fromSide);
+        var be = level.getBlockEntity(pos);
 
-        if (emcStorage != null) {
+        if (be == null) {
+            return 0;
+        }
+
+        var transferred = new AtomicLong(0);
+
+        be.getCapability(PECapabilities.EMC_STORAGE_CAPABILITY).ifPresent(emcStorage -> {
             var inserted = Math.min(maxAmount, emcStorage.insertEmc(maxAmount, IEmcStorage.EmcAction.SIMULATE));
 
             if (inserted > 0) {
                 emcStorage.insertEmc(inserted, IEmcStorage.EmcAction.EXECUTE);
             }
 
-            return inserted;
-        }
+            transferred.addAndGet(inserted);
+        });
 
-        return 0;
+        return transferred.get();
     }
 }
diff --git a/src/main/java/gripe/_90/appliede/me/strategy/EMCImportStrategy.java b/src/main/java/gripe/_90/appliede/me/strategy/EMCImportStrategy.java
index 86d4e81..6a66f71 100644
--- a/src/main/java/gripe/_90/appliede/me/strategy/EMCImportStrategy.java
+++ b/src/main/java/gripe/_90/appliede/me/strategy/EMCImportStrategy.java
@@ -1,5 +1,7 @@
 package gripe._90.appliede.me.strategy;
 
+import java.util.concurrent.atomic.AtomicLong;
+
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
 import net.minecraft.server.level.ServerLevel;
@@ -8,7 +10,6 @@
 import appeng.api.behaviors.StackTransferContext;
 import appeng.api.config.Actionable;
 import appeng.api.storage.StorageHelper;
-import appeng.util.BlockApiCache;
 
 import gripe._90.appliede.me.key.EMCKey;
 import gripe._90.appliede.me.key.EMCKeyType;
@@ -17,42 +18,37 @@
 import moze_intel.projecte.api.capabilities.block_entity.IEmcStorage;
 
 @SuppressWarnings("UnstableApiUsage")
-public class EMCImportStrategy implements StackImportStrategy {
-    private final BlockApiCache<IEmcStorage> apiCache;
-    private final Direction fromSide;
-
-    public EMCImportStrategy(ServerLevel level, BlockPos fromPos, Direction fromSide) {
-        apiCache = BlockApiCache.create(PECapabilities.EMC_STORAGE_CAPABILITY, level, fromPos);
-        this.fromSide = fromSide;
-    }
-
+public record EMCImportStrategy(ServerLevel level, BlockPos pos, Direction side) implements StackImportStrategy {
     @Override
     public boolean transfer(StackTransferContext context) {
         if (!context.isKeyTypeEnabled(EMCKeyType.TYPE)) {
             return false;
         }
 
-        var emcStorage = apiCache.find(fromSide);
+        var be = level.getBlockEntity(pos);
 
-        if (emcStorage == null) {
+        if (be == null) {
             return false;
         }
 
         var remainingTransfer = context.getOperationsRemaining() * EMCKeyType.TYPE.getAmountPerOperation();
-        var inserted = Math.min(remainingTransfer, emcStorage.getStoredEmc());
-
-        StorageHelper.poweredInsert(
-                context.getEnergySource(),
-                context.getInternalStorage().getInventory(),
-                EMCKey.BASE,
-                inserted,
-                context.getActionSource(),
-                Actionable.MODULATE);
-        emcStorage.extractEmc(inserted, IEmcStorage.EmcAction.EXECUTE);
-
-        var opsUsed = Math.max(1, inserted / EMCKeyType.TYPE.getAmountPerOperation());
-        context.reduceOperationsRemaining(opsUsed);
-
-        return inserted > 0;
+        var inserted = new AtomicLong(0);
+
+        be.getCapability(PECapabilities.EMC_STORAGE_CAPABILITY).ifPresent(emcStorage -> {
+            inserted.set(Math.min(remainingTransfer, emcStorage.getStoredEmc()));
+            StorageHelper.poweredInsert(
+                    context.getEnergySource(),
+                    context.getInternalStorage().getInventory(),
+                    EMCKey.BASE,
+                    inserted.get(),
+                    context.getActionSource(),
+                    Actionable.MODULATE);
+            emcStorage.extractEmc(inserted.get(), IEmcStorage.EmcAction.EXECUTE);
+
+            var opsUsed = Math.max(1, inserted.get() / EMCKeyType.TYPE.getAmountPerOperation());
+            context.reduceOperationsRemaining(opsUsed);
+        });
+
+        return inserted.get() > 0;
     }
 }
diff --git a/src/main/java/gripe/_90/appliede/me/strategy/EMCItemExportStrategy.java b/src/main/java/gripe/_90/appliede/me/strategy/EMCItemExportStrategy.java
deleted file mode 100644
index 7cccd58..0000000
--- a/src/main/java/gripe/_90/appliede/me/strategy/EMCItemExportStrategy.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package gripe._90.appliede.me.strategy;
-
-import com.google.common.primitives.Ints;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraftforge.common.capabilities.ForgeCapabilities;
-import net.minecraftforge.items.IItemHandler;
-import net.minecraftforge.items.ItemHandlerHelper;
-
-import appeng.api.behaviors.StackExportStrategy;
-import appeng.api.behaviors.StackTransferContext;
-import appeng.api.config.Actionable;
-import appeng.api.stacks.AEItemKey;
-import appeng.api.stacks.AEKey;
-import appeng.util.BlockApiCache;
-
-@SuppressWarnings("UnstableApiUsage")
-public class EMCItemExportStrategy implements StackExportStrategy {
-    private static final Logger LOGGER = LoggerFactory.getLogger(EMCItemExportStrategy.class);
-
-    private final BlockApiCache<IItemHandler> apiCache;
-    private final Direction fromSide;
-
-    public EMCItemExportStrategy(ServerLevel level, BlockPos fromPos, Direction fromSide) {
-        apiCache = BlockApiCache.create(ForgeCapabilities.ITEM_HANDLER, level, fromPos);
-        this.fromSide = fromSide;
-    }
-
-    @Override
-    public long transfer(StackTransferContext context, AEKey what, long amount) {
-        if (!(context instanceof EMCTransferContext emcContext)) {
-            return 0;
-        }
-
-        if (!(what instanceof AEItemKey item)) {
-            return 0;
-        }
-
-        var adjacentStorage = apiCache.find(fromSide);
-
-        if (adjacentStorage != null) {
-            var emcStorage = emcContext.getEmcStorage();
-            var stack = item.toStack(Ints.saturatedCast(amount));
-
-            var extracted = emcStorage.extractItem(item, amount, Actionable.SIMULATE, context.getActionSource(), true);
-            var remainder = ItemHandlerHelper.insertItem(adjacentStorage, stack, true);
-            var wasInserted = extracted - remainder.getCount();
-
-            if (wasInserted > 0) {
-                extracted = emcStorage.extractItem(item, amount, Actionable.MODULATE, context.getActionSource(), true);
-                remainder = ItemHandlerHelper.insertItem(adjacentStorage, stack, false);
-                wasInserted = extracted - remainder.getCount();
-
-                if (wasInserted < extracted) {
-                    var leftover = extracted - wasInserted;
-                    emcStorage.insertItem(item, leftover, Actionable.MODULATE, context.getActionSource(), false);
-
-                    if (leftover > 0) {
-                        LOGGER.error(
-                                "Storage export: adjacent block unexpectedly refused insert, voided {}x{}",
-                                leftover,
-                                item);
-                    }
-                }
-            }
-
-            return wasInserted;
-        }
-
-        return 0;
-    }
-
-    @Override
-    public long push(AEKey what, long maxAmount, Actionable mode) {
-        if (!(what instanceof AEItemKey item)) {
-            return 0;
-        }
-
-        var adjacentStorage = apiCache.find(fromSide);
-
-        if (adjacentStorage != null) {
-            var stack = item.toStack(Ints.saturatedCast(maxAmount));
-            var remainder = ItemHandlerHelper.insertItem(adjacentStorage, stack, mode.isSimulate());
-            return maxAmount - remainder.getCount();
-        }
-
-        return 0;
-    }
-}
diff --git a/src/main/java/gripe/_90/appliede/me/strategy/EMCItemImportStrategy.java b/src/main/java/gripe/_90/appliede/me/strategy/EMCItemImportStrategy.java
deleted file mode 100644
index 6826806..0000000
--- a/src/main/java/gripe/_90/appliede/me/strategy/EMCItemImportStrategy.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package gripe._90.appliede.me.strategy;
-
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraftforge.common.capabilities.ForgeCapabilities;
-import net.minecraftforge.items.IItemHandler;
-
-import appeng.api.behaviors.StackImportStrategy;
-import appeng.api.behaviors.StackTransferContext;
-import appeng.api.config.Actionable;
-import appeng.api.stacks.AEItemKey;
-import appeng.me.storage.ExternalStorageFacade;
-import appeng.util.BlockApiCache;
-
-@SuppressWarnings("UnstableApiUsage")
-public class EMCItemImportStrategy implements StackImportStrategy {
-    private final BlockApiCache<IItemHandler> apiCache;
-    private final Direction fromSide;
-
-    public EMCItemImportStrategy(ServerLevel level, BlockPos fromPos, Direction fromSide) {
-        apiCache = BlockApiCache.create(ForgeCapabilities.ITEM_HANDLER, level, fromPos);
-        this.fromSide = fromSide;
-    }
-
-    @Override
-    public boolean transfer(StackTransferContext context) {
-        if (!(context instanceof EMCTransferContext ctx)) {
-            return false;
-        }
-
-        var itemHandler = apiCache.find(fromSide);
-
-        if (itemHandler == null) {
-            return false;
-        }
-
-        var adjacentStorage = ExternalStorageFacade.of(itemHandler);
-        var remaining = ctx.getOperationsRemaining();
-
-        for (var i = 0; i < adjacentStorage.getSlots() && remaining > 0; i++) {
-            var resource = adjacentStorage.getStackInSlot(i);
-
-            if (resource == null || !(resource.what() instanceof AEItemKey item)) {
-                continue;
-            }
-
-            if (context.isInFilter(resource.what()) == context.isInverted()) {
-                continue;
-            }
-
-            var amount = adjacentStorage.extract(item, remaining, Actionable.SIMULATE, context.getActionSource());
-
-            if (amount > 0) {
-                var inserted = ctx.getEmcStorage()
-                        .insertItem(item, amount, Actionable.MODULATE, context.getActionSource(), ctx.canLearn());
-                adjacentStorage.extract(item, inserted, Actionable.MODULATE, context.getActionSource());
-                context.reduceOperationsRemaining(inserted);
-                remaining -= (int) inserted;
-            }
-        }
-
-        return true;
-    }
-}
diff --git a/src/main/java/gripe/_90/appliede/me/strategy/EMCTransferContext.java b/src/main/java/gripe/_90/appliede/me/strategy/EMCTransferContext.java
deleted file mode 100644
index 2163926..0000000
--- a/src/main/java/gripe/_90/appliede/me/strategy/EMCTransferContext.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package gripe._90.appliede.me.strategy;
-
-import com.google.common.primitives.Ints;
-
-import appeng.api.behaviors.StackTransferContext;
-import appeng.api.networking.energy.IEnergySource;
-import appeng.api.networking.security.IActionSource;
-import appeng.api.networking.storage.IStorageService;
-import appeng.api.stacks.AEItemKey;
-import appeng.api.stacks.AEKey;
-import appeng.api.stacks.AEKeyType;
-import appeng.util.prioritylist.IPartitionList;
-
-import gripe._90.appliede.me.service.EMCStorage;
-
-@SuppressWarnings({"UnstableApiUsage", "NonExtendableApiUsage"})
-public class EMCTransferContext implements StackTransferContext {
-    private final EMCStorage emcStorage;
-    private final IActionSource actionSource;
-    private final IPartitionList filter;
-    private final int initialOperations;
-
-    private int operationsRemaining;
-    private boolean isInverted;
-    private boolean canLearn;
-
-    public EMCTransferContext(
-            EMCStorage emcStorage, IActionSource actionSource, IPartitionList filter, int operationsRemaining) {
-        this.emcStorage = emcStorage;
-        this.actionSource = actionSource;
-        this.filter = filter;
-
-        initialOperations = operationsRemaining;
-        this.operationsRemaining = operationsRemaining;
-    }
-
-    public EMCStorage getEmcStorage() {
-        return emcStorage;
-    }
-
-    @Override
-    public IStorageService getInternalStorage() {
-        return null;
-    }
-
-    @Override
-    public IEnergySource getEnergySource() {
-        return null;
-    }
-
-    @Override
-    public IActionSource getActionSource() {
-        return actionSource;
-    }
-
-    @Override
-    public int getOperationsRemaining() {
-        return operationsRemaining;
-    }
-
-    @Override
-    public void setOperationsRemaining(int operationsRemaining) {
-        this.operationsRemaining = operationsRemaining;
-    }
-
-    @Override
-    public boolean hasOperationsLeft() {
-        return operationsRemaining > 0;
-    }
-
-    @Override
-    public boolean hasDoneWork() {
-        return initialOperations > operationsRemaining;
-    }
-
-    @Override
-    public boolean isKeyTypeEnabled(AEKeyType space) {
-        return space.equals(AEKeyType.items());
-    }
-
-    @Override
-    public boolean isInFilter(AEKey key) {
-        return filter.isEmpty() || filter.isListed(key);
-    }
-
-    @Override
-    public IPartitionList getFilter() {
-        return filter;
-    }
-
-    @Override
-    public void setInverted(boolean inverted) {
-        isInverted = inverted;
-    }
-
-    @Override
-    public boolean isInverted() {
-        return isInverted;
-    }
-
-    public void setCanLearn(boolean learn) {
-        canLearn = learn;
-    }
-
-    public boolean canLearn() {
-        return canLearn;
-    }
-
-    @Override
-    public boolean canInsert(AEItemKey what, long amount) {
-        return true;
-    }
-
-    @Override
-    public void reduceOperationsRemaining(long inserted) {
-        operationsRemaining -= Ints.saturatedCast(inserted);
-    }
-}
diff --git a/src/main/java/gripe/_90/appliede/part/EMCExportBusPart.java b/src/main/java/gripe/_90/appliede/part/EMCExportBusPart.java
index 911b373..b75cb50 100644
--- a/src/main/java/gripe/_90/appliede/part/EMCExportBusPart.java
+++ b/src/main/java/gripe/_90/appliede/part/EMCExportBusPart.java
@@ -1,11 +1,19 @@
 package gripe._90.appliede.part;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.google.common.primitives.Ints;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import net.minecraft.nbt.CompoundTag;
 import net.minecraft.resources.ResourceLocation;
-import net.minecraft.server.level.ServerLevel;
 import net.minecraft.world.inventory.MenuType;
+import net.minecraftforge.common.capabilities.ForgeCapabilities;
+import net.minecraftforge.items.ItemHandlerHelper;
 
-import appeng.api.behaviors.StackExportStrategy;
+import appeng.api.config.Actionable;
 import appeng.api.config.SchedulingMode;
 import appeng.api.config.Settings;
 import appeng.api.networking.IGrid;
@@ -20,14 +28,10 @@
 import appeng.menu.implementations.MenuTypeBuilder;
 import appeng.parts.PartModel;
 import appeng.parts.automation.IOBusPart;
-import appeng.util.prioritylist.DefaultPriorityList;
 
 import gripe._90.appliede.AppliedE;
 import gripe._90.appliede.me.service.KnowledgeService;
-import gripe._90.appliede.me.strategy.EMCItemExportStrategy;
-import gripe._90.appliede.me.strategy.EMCTransferContext;
 
-@SuppressWarnings("UnstableApiUsage")
 public class EMCExportBusPart extends IOBusPart {
     public static final MenuType<IOBusMenu> MENU =
             MenuTypeBuilder.create(IOBusMenu::new, EMCExportBusPart.class).build("emc_export_bus");
@@ -44,7 +48,8 @@ public class EMCExportBusPart extends IOBusPart {
     private static final PartModel MODELS_HAS_CHANNEL =
             new PartModel(MODEL_BASE, AppEng.makeId("part/export_bus_has_channel"));
 
-    private StackExportStrategy strategy;
+    private static final Logger LOGGER = LoggerFactory.getLogger(EMCExportBusPart.class);
+
     private int nextSlot = 0;
 
     public EMCExportBusPart(IPartItem<?> partItem) {
@@ -66,59 +71,73 @@ public void writeToNBT(CompoundTag extra) {
 
     @Override
     protected boolean doBusWork(IGrid grid) {
-        var emcStorage = grid.getService(KnowledgeService.class).getStorage();
-        var schedulingMode = getConfigManager().getSetting(Settings.SCHEDULING_MODE);
-        var context = new EMCTransferContext(emcStorage, source, DefaultPriorityList.INSTANCE, getOperationsPerTick());
-        var slot = 0;
+        var adjacentPos = getHost().getBlockEntity().getBlockPos().relative(getSide());
+        var blockEntity = getLevel().getBlockEntity(adjacentPos);
 
-        for (slot = 0; slot < availableSlots() && context.hasOperationsLeft(); slot++) {
-            var what = getConfig().getKey(getStartingSlot(schedulingMode, slot));
+        if (blockEntity == null) {
+            return false;
+        }
 
-            if (!(what instanceof AEItemKey item)) {
-                continue;
+        var doneWork = new AtomicBoolean(false);
+
+        blockEntity.getCapability(ForgeCapabilities.ITEM_HANDLER).ifPresent(itemHandler -> {
+            var emcStorage = grid.getService(KnowledgeService.class).getStorage();
+            var schedulingMode = getConfigManager().getSetting(Settings.SCHEDULING_MODE);
+            var remaining = getOperationsPerTick();
+            var slot = 0;
+
+            for (slot = 0; slot < availableSlots() && remaining > 0; slot++) {
+                // spotless:off
+                var startingSlot = switch (schedulingMode) {
+                    case RANDOM -> getLevel().getRandom().nextInt(availableSlots());
+                    case ROUNDROBIN -> (nextSlot + slot) % availableSlots();
+                    default -> slot;
+                };
+                // spotless:on
+                var what = getConfig().getKey(startingSlot);
+
+                if (!(what instanceof AEItemKey item)) {
+                    continue;
+                }
+
+                var stack = item.toStack(remaining);
+                var extracted = emcStorage.extractItem(item, remaining, Actionable.SIMULATE, source, true);
+                var remainder = ItemHandlerHelper.insertItem(itemHandler, stack, true);
+                var wasInserted = extracted - remainder.getCount();
+
+                if (wasInserted > 0) {
+                    extracted = emcStorage.extractItem(item, remaining, Actionable.MODULATE, source, true);
+                    remainder = ItemHandlerHelper.insertItem(itemHandler, stack, false);
+                    wasInserted = extracted - remainder.getCount();
+
+                    if (wasInserted < extracted) {
+                        var leftover = extracted - wasInserted;
+                        emcStorage.insertItem(item, leftover, Actionable.MODULATE, source, false);
+
+                        if (leftover > 0) {
+                            LOGGER.error(
+                                    "Storage export: adjacent block unexpectedly refused insert, voided {}x{}",
+                                    leftover,
+                                    item);
+                        }
+                    }
+                }
+
+                if (wasInserted > 0) {
+                    remaining -= Ints.saturatedCast(wasInserted);
+                }
             }
 
-            var amount = getStrategy().transfer(context, item, context.getOperationsRemaining());
+            if (remaining < getOperationsPerTick()) {
+                if (schedulingMode == SchedulingMode.ROUNDROBIN) {
+                    nextSlot = (nextSlot + slot) % availableSlots();
+                }
 
-            if (amount > 0) {
-                context.reduceOperationsRemaining(amount);
+                doneWork.set(true);
             }
-        }
+        });
 
-        if (context.hasDoneWork()) {
-            updateSchedulingMode(schedulingMode, slot);
-        }
-
-        return context.hasDoneWork();
-    }
-
-    private StackExportStrategy getStrategy() {
-        if (strategy == null) {
-            var self = getHost().getBlockEntity();
-            var fromPos = self.getBlockPos().relative(getSide());
-            var fromSide = getSide().getOpposite();
-            strategy = new EMCItemExportStrategy((ServerLevel) getLevel(), fromPos, fromSide);
-        }
-
-        return strategy;
-    }
-
-    private int getStartingSlot(SchedulingMode schedulingMode, int x) {
-        if (schedulingMode == SchedulingMode.RANDOM) {
-            return getLevel().getRandom().nextInt(availableSlots());
-        }
-
-        if (schedulingMode == SchedulingMode.ROUNDROBIN) {
-            return (nextSlot + x) % availableSlots();
-        }
-
-        return x;
-    }
-
-    private void updateSchedulingMode(SchedulingMode schedulingMode, int x) {
-        if (schedulingMode == SchedulingMode.ROUNDROBIN) {
-            nextSlot = (nextSlot + x) % availableSlots();
-        }
+        return doneWork.get();
     }
 
     @Override
diff --git a/src/main/java/gripe/_90/appliede/part/EMCImportBusPart.java b/src/main/java/gripe/_90/appliede/part/EMCImportBusPart.java
index 33e07eb..6b7e8c3 100644
--- a/src/main/java/gripe/_90/appliede/part/EMCImportBusPart.java
+++ b/src/main/java/gripe/_90/appliede/part/EMCImportBusPart.java
@@ -1,10 +1,14 @@
 package gripe._90.appliede.part;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.google.common.primitives.Ints;
+
 import net.minecraft.resources.ResourceLocation;
-import net.minecraft.server.level.ServerLevel;
 import net.minecraft.world.inventory.MenuType;
+import net.minecraftforge.common.capabilities.ForgeCapabilities;
 
-import appeng.api.behaviors.StackImportStrategy;
+import appeng.api.config.Actionable;
 import appeng.api.networking.IGrid;
 import appeng.api.parts.IPartCollisionHelper;
 import appeng.api.parts.IPartItem;
@@ -14,6 +18,7 @@
 import appeng.core.definitions.AEItems;
 import appeng.core.settings.TickRates;
 import appeng.items.parts.PartModels;
+import appeng.me.storage.ExternalStorageFacade;
 import appeng.menu.implementations.IOBusMenu;
 import appeng.menu.implementations.MenuTypeBuilder;
 import appeng.parts.PartModel;
@@ -21,10 +26,7 @@
 
 import gripe._90.appliede.AppliedE;
 import gripe._90.appliede.me.service.KnowledgeService;
-import gripe._90.appliede.me.strategy.EMCItemImportStrategy;
-import gripe._90.appliede.me.strategy.EMCTransferContext;
 
-@SuppressWarnings("UnstableApiUsage")
 public class EMCImportBusPart extends IOBusPart {
     public static final MenuType<IOBusMenu> MENU =
             MenuTypeBuilder.create(IOBusMenu::new, EMCImportBusPart.class).build("emc_import_bus");
@@ -41,8 +43,6 @@ public class EMCImportBusPart extends IOBusPart {
     private static final PartModel MODELS_HAS_CHANNEL =
             new PartModel(MODEL_BASE, AppEng.makeId("part/import_bus_has_channel"));
 
-    private StackImportStrategy importStrategy;
-
     public EMCImportBusPart(IPartItem<?> partItem) {
         super(TickRates.ImportBus, AEItemKey.filter(), partItem);
     }
@@ -54,19 +54,47 @@ protected MenuType<?> getMenuType() {
 
     @Override
     protected boolean doBusWork(IGrid grid) {
-        if (importStrategy == null) {
-            var self = getHost().getBlockEntity();
-            var fromPos = self.getBlockPos().relative(getSide());
-            var fromSide = getSide().getOpposite();
-            importStrategy = new EMCItemImportStrategy((ServerLevel) getLevel(), fromPos, fromSide);
+        var adjacentPos = getHost().getBlockEntity().getBlockPos().relative(getSide());
+        var blockEntity = getLevel().getBlockEntity(adjacentPos);
+
+        if (blockEntity == null) {
+            return false;
         }
 
-        var emc = grid.getService(KnowledgeService.class).getStorage();
-        var context = new EMCTransferContext(emc, source, getFilter(), getOperationsPerTick());
-        context.setInverted(isUpgradedWith(AEItems.INVERTER_CARD));
-        context.setCanLearn(isUpgradedWith(AppliedE.LEARNING_CARD.get()));
-        importStrategy.transfer(context);
-        return context.hasDoneWork();
+        var doneWork = new AtomicBoolean(false);
+
+        blockEntity.getCapability(ForgeCapabilities.ITEM_HANDLER).ifPresent(itemHandler -> {
+            var emcStorage = grid.getService(KnowledgeService.class).getStorage();
+            var adjacentStorage = ExternalStorageFacade.of(itemHandler);
+            var remaining = getOperationsPerTick();
+
+            for (var slot = 0; slot < itemHandler.getSlots() && remaining > 0; slot++) {
+                var item = AEItemKey.of(itemHandler.getStackInSlot(slot));
+
+                if (item == null) {
+                    continue;
+                }
+
+                if (!getFilter().isEmpty() && getFilter().isListed(item) == isUpgradedWith(AEItems.INVERTER_CARD)) {
+                    continue;
+                }
+
+                var amount = adjacentStorage.extract(item, remaining, Actionable.SIMULATE, source);
+
+                if (amount > 0) {
+                    var mayLearn = isUpgradedWith(AppliedE.LEARNING_CARD.get());
+                    amount = emcStorage.insertItem(item, amount, Actionable.MODULATE, source, mayLearn);
+                    adjacentStorage.extract(item, amount, Actionable.MODULATE, source);
+                    remaining -= Ints.saturatedCast(amount);
+                }
+            }
+
+            if (remaining < getOperationsPerTick()) {
+                doneWork.set(true);
+            }
+        });
+
+        return doneWork.get();
     }
 
     @Override