// Path: src/main/java/org/cyclops/integratedtunnels/api/world/IBlockPlaceHandler.java
// public interface IBlockPlaceHandler {
// 
//     /**
//      * If this can handle the given item placement as block.
//      * @param itemStack The item.
//      * @param world The world.
//      * @param pos The position.
//      * @param side The side that this item is being placed at.
//      * @param hitX The X position that is being targeted.
//      * @param hitY The Y position that is being targeted.
//      * @param hitZ The Z position that is being targeted.
//      * @param player The placing player.
//      * @return If this can handle the given item placement as block.
//      */
//     public boolean shouldApply(ItemStack itemStack, World world, BlockPos pos, Direction side, float hitX, float hitY, float hitZ, PlayerEntity player);
// 
//     /**
//      * Place the given item as block.
//      * @param itemStack The item.
//      * @param world The world.
//      * @param pos The position.
//      * @param side The side that this item is being placed at.
//      * @param hitX The X position that is being targeted.
//      * @param hitY The Y position that is being targeted.
//      * @param hitZ The Z position that is being targeted.
//      * @param player The placing player.
//      */
//     public void placeBlock(ItemStack itemStack, World world, BlockPos pos, Direction side, float hitX, float hitY, float hitZ, PlayerEntity player);
// 
// }
// 
// Path: src/main/java/org/cyclops/integratedtunnels/api/world/IBlockPlaceHandlerRegistry.java
// public interface IBlockPlaceHandlerRegistry extends IRegistry {
// 
//     /**
//      * Add an item placement breaking handler.
//      * Multiple handlers can exist for an item.
//      * @param item An item.
//      * @param placeAction A handler.
//      * @return The registered handler.
//      */
//     public IBlockPlaceHandler register(Item item, IBlockPlaceHandler placeAction);
// 
//     /**
//      * @return All registered block breaking handlers.
//      */
//     public Collection<IBlockPlaceHandler> getHandlers();
// 
//     /**
//      * @param item An item.
//      * @return All registered block placement handlers for the given item.
//      */
//     public Collection<IBlockPlaceHandler> getHandlers(Item item);
// 
//     /**
//      * Get the first possible block breaking handler for the given item.
//      * @param itemStack The item.
//      * @param world The world.
//      * @param pos The position.
//      * @param side The side that this item is being placed at.
//      * @param hitX The X position that is being targeted.
//      * @param hitY The Y position that is being targeted.
//      * @param hitZ The Z position that is being targeted.
//      * @param player The placing player.
//      * @return A block placement handler or null.
//      */
//     @Nullable
//     public IBlockPlaceHandler getHandler(ItemStack itemStack, World world, BlockPos pos, Direction side,
//                                          float hitX, float hitY, float hitZ, PlayerEntity player);
// 
// }


import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.cyclops.integratedtunnels.api.world.IBlockPlaceHandler;
import org.cyclops.integratedtunnels.api.world.IBlockPlaceHandlerRegistry;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
     */
    public static BlockBreakPlaceRegistry getInstance() {
        return INSTANCE;
    }

    @Override
    public IBlockPlaceHandler register(Item item, IBlockPlaceHandler placeAction) {
        handlers.put(item, placeAction);
        return placeAction;
    }

    @Override
    public Collection<IBlockPlaceHandler> getHandlers() {
        return Collections.unmodifiableCollection(handlers.values());
    }

    @Override
    public Collection<IBlockPlaceHandler> getHandlers(Item item) {
        return Collections.unmodifiableCollection(handlers.get(item));
    }

    @Nullable
    @Override
    public IBlockPlaceHandler getHandler(ItemStack itemStack, World world, BlockPos pos, Direction side,
                                         float hitX, float hitY, float hitZ, PlayerEntity player) {
        for (IBlockPlaceHandler placeHandler : getHandlers(itemStack.getItem())) {
            if (placeHandler.shouldApply(itemStack, world, pos, side, hitX, hitY, hitZ, player)) {
                return placeHandler;
            }
        }
// Path: src/main/java/org/cyclops/integratedtunnels/api/world/IBlockPlaceHandler.java
// public interface IBlockPlaceHandler {
// 
//     /**
//      * If this can handle the given item placement as block.
//      * @param itemStack The item.
//      * @param world The world.
//      * @param pos The position.
//      * @param side The side that this item is being placed at.
//      * @param hitX The X position that is being targeted.
//      * @param hitY The Y position that is being targeted.
//      * @param hitZ The Z position that is being targeted.
//      * @param player The placing player.
//      * @return If this can handle the given item placement as block.
//      */
//     public boolean shouldApply(ItemStack itemStack, World world, BlockPos pos, Direction side, float hitX, float hitY, float hitZ, PlayerEntity player);
// 
//     /**
//      * Place the given item as block.
//      * @param itemStack The item.
//      * @param world The world.
//      * @param pos The position.
//      * @param side The side that this item is being placed at.
//      * @param hitX The X position that is being targeted.
//      * @param hitY The Y position that is being targeted.
//      * @param hitZ The Z position that is being targeted.
//      * @param player The placing player.
//      */
//     public void placeBlock(ItemStack itemStack, World world, BlockPos pos, Direction side, float hitX, float hitY, float hitZ, PlayerEntity player);
// 
// }
// 
// Path: src/main/java/org/cyclops/integratedtunnels/api/world/IBlockPlaceHandlerRegistry.java
// public interface IBlockPlaceHandlerRegistry extends IRegistry {
// 
//     /**
//      * Add an item placement breaking handler.
//      * Multiple handlers can exist for an item.
//      * @param item An item.
//      * @param placeAction A handler.
//      * @return The registered handler.
//      */
//     public IBlockPlaceHandler register(Item item, IBlockPlaceHandler placeAction);
// 
//     /**
//      * @return All registered block breaking handlers.
//      */
//     public Collection<IBlockPlaceHandler> getHandlers();
// 
//     /**
//      * @param item An item.
//      * @return All registered block placement handlers for the given item.
//      */
//     public Collection<IBlockPlaceHandler> getHandlers(Item item);
// 
//     /**
//      * Get the first possible block breaking handler for the given item.
//      * @param itemStack The item.
//      * @param world The world.
//      * @param pos The position.
//      * @param side The side that this item is being placed at.
//      * @param hitX The X position that is being targeted.
//      * @param hitY The Y position that is being targeted.
//      * @param hitZ The Z position that is being targeted.
//      * @param player The placing player.
//      * @return A block placement handler or null.
//      */
//     @Nullable
//     public IBlockPlaceHandler getHandler(ItemStack itemStack, World world, BlockPos pos, Direction side,
//                                          float hitX, float hitY, float hitZ, PlayerEntity player);
// 
// }


// Path: src/main/java/org/cyclops/integratedtunnels/core/world/BlockBreakPlaceRegistry.java
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.cyclops.integratedtunnels.api.world.IBlockPlaceHandler;
import org.cyclops.integratedtunnels.api.world.IBlockPlaceHandlerRegistry;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;

     */
    public static BlockBreakPlaceRegistry getInstance() {
        return INSTANCE;
    }

    @Override
    public IBlockPlaceHandler register(Item item, IBlockPlaceHandler placeAction) {
        handlers.put(item, placeAction);
        return placeAction;
    }

    @Override
    public Collection<IBlockPlaceHandler> getHandlers() {
        return Collections.unmodifiableCollection(handlers.values());
    }

    @Override
    public Collection<IBlockPlaceHandler> getHandlers(Item item) {
        return Collections.unmodifiableCollection(handlers.get(item));
    }

    @Nullable
    @Override
    public IBlockPlaceHandler getHandler(ItemStack itemStack, World world, BlockPos pos, Direction side,
                                         float hitX, float hitY, float hitZ, PlayerEntity player) {
        for (IBlockPlaceHandler placeHandler : getHandlers(itemStack.getItem())) {
            if (placeHandler.shouldApply(itemStack, world, pos, side, hitX, hitY, hitZ, player)) {
                return placeHandler;
            }
        }
        return null;