diff --git a/src/main/java/net/knarcraft/stargate/Gate.java b/src/main/java/net/knarcraft/stargate/Gate.java
index 30b4812..4a41ae5 100644
--- a/src/main/java/net/knarcraft/stargate/Gate.java
+++ b/src/main/java/net/knarcraft/stargate/Gate.java
@@ -7,7 +7,6 @@ import org.bukkit.block.Block;
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileWriter;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -400,7 +399,7 @@ public class Gate {
             return null;
         }
 
-        if (!Tag.BUTTONS.isTagged(gate.button)) {
+        if (!Tag.BUTTONS.isTagged(gate.button) && !MaterialHelper.isWallCoral(gate.button)) {
             Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - Gate button must be a type of button.");
             return null;
         }
@@ -435,28 +434,39 @@ public class Gate {
         return def;
     }
 
+    /**
+     * Loads all gates inside the given folder
+     * @param gateFolder 
The folder containing the gates
+     */
     public static void loadGates(String gateFolder) {
-        File dir = new File(gateFolder);
+        File directory = new File(gateFolder);
         File[] files;
 
-        if (dir.exists()) {
-            files = dir.listFiles(new StargateFilenameFilter());
+        if (directory.exists()) {
+            files = directory.listFiles((file) -> file.isFile() && file.getName().endsWith(".gate"));
         } else {
             files = new File[0];
         }
 
         if (files == null || files.length == 0) {
-            if (dir.mkdir()) {
+            //The gates folder was not found. Assume this is the first run
+            if (directory.mkdir()) {
                 populateDefaults(gateFolder);
             }
         } else {
             for (File file : files) {
                 Gate gate = loadGate(file);
-                if (gate != null) registerGate(gate);
+                if (gate != null) {
+                    registerGate(gate);
+                }
             }
         }
     }
 
+    /**
+     * Writes the default gate specification to the given folder
+     * @param gateFolder The folder containing gate config files
+     */
     public static void populateDefaults(String gateFolder) {
         Character[][] layout = new Character[][]{
                 {' ', 'X', 'X', ' '},
@@ -485,32 +495,46 @@ public class Gate {
         Gate[] result = new Gate[0];
         ArrayList lookup = controlBlocks.get(type);
 
-        if (lookup != null) result = lookup.toArray(result);
+        if (lookup != null) {
+            result = lookup.toArray(result);
+        }
 
         return result;
     }
 
+    /**
+     * Gets a portal by its name (filename before .gate)
+     * @param name The name of the gate to get
+     * @return The gate with the given name
+     */
     public static Gate getGateByName(String name) {
         return gates.get(name);
     }
 
+    /**
+     * Gets the number of loaded gate configurations
+     * @return The number of loaded gate configurations
+     */
     public static int getGateCount() {
         return gates.size();
     }
 
+    /**
+     * Checks whether the given material is used for the frame of any portals
+     * @param type The material type to check
+     * @return True if the material is used for the frame of at least one portal
+     */
     public static boolean isGateBlock(Material type) {
         return frameBlocks.contains(type);
     }
 
-    static class StargateFilenameFilter implements FilenameFilter {
-        public boolean accept(File dir, String name) {
-            return name.endsWith(".gate");
-        }
-    }
-
+    /**
+     * Clears all loaded gates
+     */
     public static void clearGates() {
         gates.clear();
         controlBlocks.clear();
         frameBlocks.clear();
     }
+
 }
diff --git a/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java b/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java
new file mode 100644
index 0000000..8360047
--- /dev/null
+++ b/src/main/java/net/knarcraft/stargate/PlayerEventsListener.java
@@ -0,0 +1,303 @@
+package net.knarcraft.stargate;
+
+import org.bukkit.GameMode;
+import org.bukkit.Tag;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.data.type.WallSign;
+import org.bukkit.entity.Player;
+import org.bukkit.event.Event;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerMoveEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+public class PlayerEventsListener implements Listener {
+
+    private static long eventTime;
+    private static PlayerInteractEvent previousEvent;
+
+    @EventHandler
+    public void onPlayerJoin(PlayerJoinEvent event) {
+        if (!Stargate.enableBungee) {
+            return;
+        }
+
+        Player player = event.getPlayer();
+        String destination = Stargate.bungeeQueue.remove(player.getName().toLowerCase());
+        if (destination == null) {
+            return;
+        }
+
+        Portal portal = Portal.getBungeeGate(destination);
+        if (portal == null) {
+            Stargate.debug("PlayerJoin", "Error fetching destination portal: " + destination);
+            return;
+        }
+        portal.teleport(player, portal, null);
+    }
+
+    @EventHandler
+    public void onPlayerTeleport(PlayerTeleportEvent event) {
+        // cancel portal and endgateway teleportation if it's from a stargate entrance
+        PlayerTeleportEvent.TeleportCause cause = event.getCause();
+        if (!event.isCancelled()
+                && (cause == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL
+                || cause == PlayerTeleportEvent.TeleportCause.END_GATEWAY && World.Environment.THE_END == event.getFrom().getWorld().getEnvironment())
+                && Portal.getByAdjacentEntrance(event.getFrom()) != null) {
+            event.setCancelled(true);
+        }
+    }
+
+    @EventHandler
+    public void onPlayerMove(PlayerMoveEvent event) {
+        if (event.isCancelled()) return;
+
+        // Check to see if the player actually moved
+        if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockY() == event.getTo().getBlockY() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) {
+            return;
+        }
+
+        Player player = event.getPlayer();
+        Portal portal = Portal.getByEntrance(event.getTo());
+        // No portal or not open
+        if (portal == null || !portal.isOpen()) return;
+
+        // Not open for this player
+        if (!portal.isOpenFor(player)) {
+            Stargate.sendMessage(player, Stargate.getString("denyMsg"));
+            portal.teleport(player, portal, event);
+            return;
+        }
+
+        Portal destination = portal.getDestination(player);
+        if (!portal.isBungee() && destination == null) return;
+
+        boolean deny = false;
+        // Check if player has access to this server for Bungee gates
+        if (portal.isBungee()) {
+            if (!Stargate.canAccessServer(player, portal.getNetwork())) {
+                deny = true;
+            }
+        } else {
+            // Check if player has access to this network
+            if (!Stargate.canAccessNetwork(player, portal.getNetwork())) {
+                deny = true;
+            }
+
+            // Check if player has access to destination world
+            if (!Stargate.canAccessWorld(player, destination.getWorld().getName())) {
+                deny = true;
+            }
+        }
+
+        if (!Stargate.canAccessPortal(player, portal, deny)) {
+            Stargate.sendMessage(player, Stargate.getString("denyMsg"));
+            portal.teleport(player, portal, event);
+            portal.close(false);
+            return;
+        }
+
+        int cost = Stargate.getUseCost(player, portal, destination);
+        if (cost > 0) {
+            boolean success;
+            if (portal.getGate().getToOwner()) {
+                success = portal.getOwnerUUID() != null && Stargate.chargePlayer(player, portal.getOwnerUUID(), cost);
+            } else {
+                success = Stargate.chargePlayer(player, cost);
+            }
+            if (!success) {
+                // Insufficient Funds
+                Stargate.sendMessage(player, Stargate.getString("inFunds"));
+                portal.close(false);
+                return;
+            }
+            String deductMsg = Stargate.getString("ecoDeduct");
+            deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()});
+            Stargate.sendMessage(player, deductMsg, false);
+            if (portal.getGate().getToOwner() && portal.getOwnerUUID() != null) {
+                Player p;
+                if (portal.getOwnerUUID() != null) {
+                    p = Stargate.server.getPlayer(portal.getOwnerUUID());
+                } else {
+                    p = Stargate.server.getPlayer(portal.getOwnerName());
+                }
+                if (p != null) {
+                    String obtainedMsg = Stargate.getString("ecoObtain");
+                    obtainedMsg = Stargate.replaceVars(obtainedMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()});
+                    Stargate.sendMessage(p, obtainedMsg, false);
+                }
+            }
+        }
+
+        Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false);
+
+        // BungeeCord Support
+        if (portal.isBungee()) {
+            if (!Stargate.enableBungee) {
+                player.sendMessage(Stargate.getString("bungeeDisabled"));
+                portal.close(false);
+                return;
+            }
+
+            // Teleport the player back to this gate, for sanity's sake
+            portal.teleport(player, portal, event);
+
+            // Send the SGBungee packet first, it will be queued by BC if required
+            try {
+                // Build the message, format is #@#
+                String msg = event.getPlayer().getName() + "#@#" + portal.getDestinationName();
+                // Build the message data, sent over the SGBungee bungeecord channel
+                ByteArrayOutputStream bao = new ByteArrayOutputStream();
+                DataOutputStream msgData = new DataOutputStream(bao);
+                msgData.writeUTF("Forward");
+                msgData.writeUTF(portal.getNetwork());    // Server
+                msgData.writeUTF("SGBungee");            // Channel
+                msgData.writeShort(msg.length());    // Data Length
+                msgData.writeBytes(msg);            // Data
+                player.sendPluginMessage(Stargate.stargate, "BungeeCord", bao.toByteArray());
+            } catch (IOException ex) {
+                Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet");
+                ex.printStackTrace();
+                return;
+            }
+
+            // Connect player to new server
+            try {
+                ByteArrayOutputStream bao = new ByteArrayOutputStream();
+                DataOutputStream msgData = new DataOutputStream(bao);
+                msgData.writeUTF("Connect");
+                msgData.writeUTF(portal.getNetwork());
+
+                player.sendPluginMessage(Stargate.stargate, "BungeeCord", bao.toByteArray());
+                bao.reset();
+            } catch (IOException ex) {
+                Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet");
+                ex.printStackTrace();
+                return;
+            }
+
+            // Close portal if required (Should never be)
+            portal.close(false);
+            return;
+        }
+
+        destination.teleport(player, portal, event);
+        portal.close(false);
+    }
+
+    @EventHandler
+    public void onPlayerInteract(PlayerInteractEvent event) {
+        Player player = event.getPlayer();
+        Block block = event.getClickedBlock();
+
+        if (block == null) {
+            return;
+        }
+
+        // Right click
+        if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
+            if (block.getBlockData() instanceof WallSign) {
+                Portal portal = Portal.getByBlock(block);
+                if (portal == null) {
+                    return;
+                }
+                // Cancel item use
+                event.setUseItemInHand(Event.Result.DENY);
+                event.setUseInteractedBlock(Event.Result.DENY);
+
+                boolean deny = false;
+                if (!Stargate.canAccessNetwork(player, portal.getNetwork())) {
+                    deny = true;
+                }
+
+                if (!Stargate.canAccessPortal(player, portal, deny)) {
+                    Stargate.sendMessage(player, Stargate.getString("denyMsg"));
+                    return;
+                }
+
+                if ((!portal.isOpen()) && (!portal.isFixed())) {
+                    portal.cycleDestination(player);
+                }
+                return;
+            }
+
+            // Implement right-click to toggle a stargate, gets around spawn protection problem.
+            if (Tag.BUTTONS.isTagged(block.getType()) || MaterialHelper.isWallCoral(block.getType())) {
+
+                if (MaterialHelper.isWallCoral(block.getType())) {
+                    if (previousEvent != null &&
+                            event.getPlayer() == previousEvent.getPlayer() && eventTime + 10 > System.currentTimeMillis()) {
+                        previousEvent = null;
+                        eventTime = 0;
+                        return;
+                    }
+                    previousEvent = event;
+                    eventTime = System.currentTimeMillis();
+                }
+
+                Portal portal = Portal.getByBlock(block);
+                if (portal == null) {
+                    return;
+                }
+
+                // Cancel item use
+                event.setUseItemInHand(Event.Result.DENY);
+                event.setUseInteractedBlock(Event.Result.DENY);
+
+                boolean deny = false;
+                if (!Stargate.canAccessNetwork(player, portal.getNetwork())) {
+                    deny = true;
+                }
+
+                if (!Stargate.canAccessPortal(player, portal, deny)) {
+                    Stargate.sendMessage(player, Stargate.getString("denyMsg"));
+                    return;
+                }
+
+                Stargate.openPortal(player, portal);
+                if (portal.isOpenFor(player)) {
+                    event.setUseInteractedBlock(Event.Result.ALLOW);
+                }
+            }
+            return;
+        }
+
+        // Left click
+        if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
+            // Check if we're scrolling a sign
+            if (block.getBlockData() instanceof WallSign) {
+                Portal portal = Portal.getByBlock(block);
+                if (portal == null) return;
+
+                event.setUseInteractedBlock(Event.Result.DENY);
+                // Only cancel event in creative mode
+                if (player.getGameMode().equals(GameMode.CREATIVE)) {
+                    event.setCancelled(true);
+                }
+
+                boolean deny = false;
+                if (!Stargate.canAccessNetwork(player, portal.getNetwork())) {
+                    deny = true;
+                }
+
+                if (!Stargate.canAccessPortal(player, portal, deny)) {
+                    Stargate.sendMessage(player, Stargate.getString("denyMsg"));
+                    return;
+                }
+
+                if ((!portal.isOpen()) && (!portal.isFixed())) {
+                    portal.cycleDestination(player, -1);
+                }
+            }
+        }
+    }
+
+}
diff --git a/src/main/java/net/knarcraft/stargate/Portal.java b/src/main/java/net/knarcraft/stargate/Portal.java
index 52b996e..c6f665d 100644
--- a/src/main/java/net/knarcraft/stargate/Portal.java
+++ b/src/main/java/net/knarcraft/stargate/Portal.java
@@ -911,7 +911,9 @@ public class Portal {
             return null;
         }
 
-        if (Gate.getGatesByControlBlock(idParent).length == 0) return null;
+        if (Gate.getGatesByControlBlock(idParent).length == 0) {
+            return null;
+        }
 
         if (Portal.getByBlock(idParent) != null) {
             Stargate.debug("createPortal", "idParent belongs to existing gate");
@@ -924,6 +926,7 @@ public class Portal {
         String destName = filterName(event.getLine(1));
         String network = filterName(event.getLine(2));
         String options = filterName(event.getLine(3)).toLowerCase();
+
         boolean hidden = (options.indexOf('h') != -1);
         boolean alwaysOn = (options.indexOf('a') != -1);
         boolean priv = (options.indexOf('p') != -1);
@@ -935,14 +938,30 @@ public class Portal {
         boolean bungee = (options.indexOf('u') != -1);
 
         // Check permissions for options.
-        if (hidden && !Stargate.canOption(player, "hidden")) hidden = false;
-        if (alwaysOn && !Stargate.canOption(player, "alwayson")) alwaysOn = false;
-        if (priv && !Stargate.canOption(player, "private")) priv = false;
-        if (free && !Stargate.canOption(player, "free")) free = false;
-        if (backwards && !Stargate.canOption(player, "backwards")) backwards = false;
-        if (show && !Stargate.canOption(player, "show")) show = false;
-        if (noNetwork && !Stargate.canOption(player, "nonetwork")) noNetwork = false;
-        if (random && !Stargate.canOption(player, "random")) random = false;
+        if (hidden && !Stargate.canOption(player, "hidden")) {
+            hidden = false;
+        }
+        if (alwaysOn && !Stargate.canOption(player, "alwayson")) {
+            alwaysOn = false;
+        }
+        if (priv && !Stargate.canOption(player, "private")) {
+            priv = false;
+        }
+        if (free && !Stargate.canOption(player, "free")) {
+            free = false;
+        }
+        if (backwards && !Stargate.canOption(player, "backwards")) {
+            backwards = false;
+        }
+        if (show && !Stargate.canOption(player, "show")) {
+            show = false;
+        }
+        if (noNetwork && !Stargate.canOption(player, "nonetwork")) {
+            noNetwork = false;
+        }
+        if (random && !Stargate.canOption(player, "random")) {
+            random = false;
+        }
 
         // Can not create a non-fixed always-on gate.
         if (alwaysOn && destName.length() == 0) {
@@ -995,28 +1014,29 @@ public class Portal {
         RelativeBlockVector buttonVector = null;
 
         for (Gate possibility : possibleGates) {
-            if ((gate == null) && (buttonVector == null)) {
-                RelativeBlockVector[] vectors = possibility.getControls();
-                RelativeBlockVector otherControl = null;
+            if (gate != null || buttonVector != null) {
+                break;
+            }
+            RelativeBlockVector[] vectors = possibility.getControls();
+            RelativeBlockVector otherControl = null;
 
-                for (RelativeBlockVector vector : vectors) {
-                    BlockLocation tl = parent.modRelative(-vector.getRight(), -vector.getDepth(), -vector.getDistance(), modX, 1, modZ);
+            for (RelativeBlockVector vector : vectors) {
+                BlockLocation tl = parent.modRelative(-vector.getRight(), -vector.getDepth(), -vector.getDistance(), modX, 1, modZ);
 
-                    if (gate == null) {
-                        if (possibility.matches(tl, modX, modZ, true)) {
-                            gate = possibility;
-                            topleft = tl;
+                if (gate == null) {
+                    if (possibility.matches(tl, modX, modZ, true)) {
+                        gate = possibility;
+                        topleft = tl;
 
-                            if (otherControl != null) {
-                                buttonVector = otherControl;
-                            }
+                        if (otherControl != null) {
+                            buttonVector = otherControl;
                         }
-                    } else if (otherControl != null) {
-                        buttonVector = vector;
                     }
-
-                    otherControl = vector;
+                } else if (otherControl != null) {
+                    buttonVector = vector;
                 }
+
+                otherControl = vector;
             }
         }
 
diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java
index 441c24d..68c98ca 100644
--- a/src/main/java/net/knarcraft/stargate/Stargate.java
+++ b/src/main/java/net/knarcraft/stargate/Stargate.java
@@ -4,7 +4,6 @@ import net.knarcraft.stargate.event.StargateAccessEvent;
 import net.knarcraft.stargate.event.StargateDestroyEvent;
 import org.bukkit.Bukkit;
 import org.bukkit.ChatColor;
-import org.bukkit.GameMode;
 import org.bukkit.Material;
 import org.bukkit.Server;
 import org.bukkit.Tag;
@@ -20,11 +19,9 @@ import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.entity.Entity;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Vehicle;
-import org.bukkit.event.Event.Result;
 import org.bukkit.event.EventHandler;
 import org.bukkit.event.EventPriority;
 import org.bukkit.event.Listener;
-import org.bukkit.event.block.Action;
 import org.bukkit.event.block.BlockBreakEvent;
 import org.bukkit.event.block.BlockFromToEvent;
 import org.bukkit.event.block.BlockPhysicsEvent;
@@ -32,10 +29,6 @@ import org.bukkit.event.block.BlockPistonExtendEvent;
 import org.bukkit.event.block.BlockPistonRetractEvent;
 import org.bukkit.event.block.SignChangeEvent;
 import org.bukkit.event.entity.EntityExplodeEvent;
-import org.bukkit.event.player.PlayerInteractEvent;
-import org.bukkit.event.player.PlayerJoinEvent;
-import org.bukkit.event.player.PlayerMoveEvent;
-import org.bukkit.event.player.PlayerTeleportEvent;
 import org.bukkit.event.server.PluginDisableEvent;
 import org.bukkit.event.server.PluginEnableEvent;
 import org.bukkit.event.vehicle.VehicleMoveEvent;
@@ -47,10 +40,7 @@ import org.bukkit.plugin.PluginManager;
 import org.bukkit.plugin.java.JavaPlugin;
 import org.bukkit.plugin.java.JavaPluginLoader;
 
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
 import java.io.File;
-import java.io.IOException;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -170,7 +160,7 @@ public class Stargate extends JavaPlugin {
         log.info(pdfFile.getName() + " v." + pdfFile.getVersion() + " is enabled.");
 
         // Register events before loading gates to stop weird things happening.
-        pm.registerEvents(new pListener(), this);
+        pm.registerEvents(new PlayerEventsListener(), this);
         pm.registerEvents(new bListener(), this);
 
         pm.registerEvents(new vListener(), this);
@@ -759,273 +749,25 @@ public class Stargate extends JavaPlugin {
         }
     }
 
-    private class pListener implements Listener {
-        @EventHandler
-        public void onPlayerJoin(PlayerJoinEvent event) {
-            if (!enableBungee) return;
 
-            Player player = event.getPlayer();
-            String destination = bungeeQueue.remove(player.getName().toLowerCase());
-            if (destination == null) return;
-
-            Portal portal = Portal.getBungeeGate(destination);
-            if (portal == null) {
-                Stargate.debug("PlayerJoin", "Error fetching destination portal: " + destination);
-                return;
-            }
-            portal.teleport(player, portal, null);
-        }
-
-        @EventHandler
-        public void onPlayerTeleport(PlayerTeleportEvent event) {
-            // cancel portal and endgateway teleportation if it's from a stargate entrance
-            PlayerTeleportEvent.TeleportCause cause = event.getCause();
-            if (!event.isCancelled()
-                    && (cause == PlayerTeleportEvent.TeleportCause.NETHER_PORTAL
-                    || cause == PlayerTeleportEvent.TeleportCause.END_GATEWAY && World.Environment.THE_END == event.getFrom().getWorld().getEnvironment())
-                    && Portal.getByAdjacentEntrance(event.getFrom()) != null) {
-                event.setCancelled(true);
-            }
-        }
-
-        @EventHandler
-        public void onPlayerMove(PlayerMoveEvent event) {
-            if (event.isCancelled()) return;
-
-            // Check to see if the player actually moved
-            if (event.getFrom().getBlockX() == event.getTo().getBlockX() && event.getFrom().getBlockY() == event.getTo().getBlockY() && event.getFrom().getBlockZ() == event.getTo().getBlockZ()) {
-                return;
-            }
-
-            Player player = event.getPlayer();
-            Portal portal = Portal.getByEntrance(event.getTo());
-            // No portal or not open
-            if (portal == null || !portal.isOpen()) return;
-
-            // Not open for this player
-            if (!portal.isOpenFor(player)) {
-                Stargate.sendMessage(player, Stargate.getString("denyMsg"));
-                portal.teleport(player, portal, event);
-                return;
-            }
-
-            Portal destination = portal.getDestination(player);
-            if (!portal.isBungee() && destination == null) return;
-
-            boolean deny = false;
-            // Check if player has access to this server for Bungee gates
-            if (portal.isBungee()) {
-                if (!canAccessServer(player, portal.getNetwork())) {
-                    deny = true;
-                }
-            } else {
-                // Check if player has access to this network
-                if (!canAccessNetwork(player, portal.getNetwork())) {
-                    deny = true;
-                }
-
-                // Check if player has access to destination world
-                if (!canAccessWorld(player, destination.getWorld().getName())) {
-                    deny = true;
-                }
-            }
-
-            if (!canAccessPortal(player, portal, deny)) {
-                Stargate.sendMessage(player, Stargate.getString("denyMsg"));
-                portal.teleport(player, portal, event);
-                portal.close(false);
-                return;
-            }
-
-            int cost = Stargate.getUseCost(player, portal, destination);
-            if (cost > 0) {
-                boolean success;
-                if (portal.getGate().getToOwner()) {
-                    success = portal.getOwnerUUID() != null && Stargate.chargePlayer(player, portal.getOwnerUUID(), cost);
-                } else {
-                    success = Stargate.chargePlayer(player, cost);
-                }
-                if (!success) {
-                    // Insufficient Funds
-                    Stargate.sendMessage(player, Stargate.getString("inFunds"));
-                    portal.close(false);
-                    return;
-                }
-                String deductMsg = Stargate.getString("ecoDeduct");
-                deductMsg = Stargate.replaceVars(deductMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()});
-                sendMessage(player, deductMsg, false);
-                if (portal.getGate().getToOwner() && portal.getOwnerUUID() != null) {
-                    Player p;
-                    if (portal.getOwnerUUID() != null) {
-                        p = server.getPlayer(portal.getOwnerUUID());
-                    } else {
-                        p = server.getPlayer(portal.getOwnerName());
-                    }
-                    if (p != null) {
-                        String obtainedMsg = Stargate.getString("ecoObtain");
-                        obtainedMsg = Stargate.replaceVars(obtainedMsg, new String[]{"%cost%", "%portal%"}, new String[]{EconomyHandler.format(cost), portal.getName()});
-                        Stargate.sendMessage(p, obtainedMsg, false);
-                    }
-                }
-            }
-
-            Stargate.sendMessage(player, Stargate.getString("teleportMsg"), false);
-
-            // BungeeCord Support
-            if (portal.isBungee()) {
-                if (!enableBungee) {
-                    player.sendMessage(Stargate.getString("bungeeDisabled"));
-                    portal.close(false);
-                    return;
-                }
-
-                // Teleport the player back to this gate, for sanity's sake
-                portal.teleport(player, portal, event);
-
-                // Send the SGBungee packet first, it will be queued by BC if required
-                try {
-                    // Build the message, format is #@#
-                    String msg = event.getPlayer().getName() + "#@#" + portal.getDestinationName();
-                    // Build the message data, sent over the SGBungee bungeecord channel
-                    ByteArrayOutputStream bao = new ByteArrayOutputStream();
-                    DataOutputStream msgData = new DataOutputStream(bao);
-                    msgData.writeUTF("Forward");
-                    msgData.writeUTF(portal.getNetwork());    // Server
-                    msgData.writeUTF("SGBungee");            // Channel
-                    msgData.writeShort(msg.length());    // Data Length
-                    msgData.writeBytes(msg);            // Data
-                    player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray());
-                } catch (IOException ex) {
-                    Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord teleport packet");
-                    ex.printStackTrace();
-                    return;
-                }
-
-                // Connect player to new server
-                try {
-                    ByteArrayOutputStream bao = new ByteArrayOutputStream();
-                    DataOutputStream msgData = new DataOutputStream(bao);
-                    msgData.writeUTF("Connect");
-                    msgData.writeUTF(portal.getNetwork());
-
-                    player.sendPluginMessage(stargate, "BungeeCord", bao.toByteArray());
-                    bao.reset();
-                } catch (IOException ex) {
-                    Stargate.log.severe(Stargate.getString("prefix") + "Error sending BungeeCord connect packet");
-                    ex.printStackTrace();
-                    return;
-                }
-
-                // Close portal if required (Should never be)
-                portal.close(false);
-                return;
-            }
-
-            destination.teleport(player, portal, event);
-            portal.close(false);
-        }
-
-        @EventHandler
-        public void onPlayerInteract(PlayerInteractEvent event) {
-            Player player = event.getPlayer();
-            Block block = event.getClickedBlock();
-
-            if (block == null) return;
-
-            // Right click
-            if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
-                if (block.getBlockData() instanceof WallSign) {
-                    Portal portal = Portal.getByBlock(block);
-                    if (portal == null) return;
-                    // Cancel item use
-                    event.setUseItemInHand(Result.DENY);
-                    event.setUseInteractedBlock(Result.DENY);
-
-                    boolean deny = false;
-                    if (!Stargate.canAccessNetwork(player, portal.getNetwork())) {
-                        deny = true;
-                    }
-
-                    if (!Stargate.canAccessPortal(player, portal, deny)) {
-                        Stargate.sendMessage(player, Stargate.getString("denyMsg"));
-                        return;
-                    }
-
-                    if ((!portal.isOpen()) && (!portal.isFixed())) {
-                        portal.cycleDestination(player);
-                    }
-                    return;
-                }
-
-                // Implement right-click to toggle a stargate, gets around spawn protection problem.
-                if (Tag.BUTTONS.isTagged(block.getType())) {
-                    Portal portal = Portal.getByBlock(block);
-                    if (portal == null) return;
-
-                    // Cancel item use
-                    event.setUseItemInHand(Result.DENY);
-                    event.setUseInteractedBlock(Result.DENY);
-
-                    boolean deny = false;
-                    if (!Stargate.canAccessNetwork(player, portal.getNetwork())) {
-                        deny = true;
-                    }
-
-                    if (!Stargate.canAccessPortal(player, portal, deny)) {
-                        Stargate.sendMessage(player, Stargate.getString("denyMsg"));
-                        return;
-                    }
-
-                    openPortal(player, portal);
-                    if (portal.isOpenFor(player)) {
-                        event.setUseInteractedBlock(Result.ALLOW);
-                    }
-                }
-                return;
-            }
-
-            // Left click
-            if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
-                // Check if we're scrolling a sign
-                if (block.getBlockData() instanceof WallSign) {
-                    Portal portal = Portal.getByBlock(block);
-                    if (portal == null) return;
-
-                    event.setUseInteractedBlock(Result.DENY);
-                    // Only cancel event in creative mode
-                    if (player.getGameMode().equals(GameMode.CREATIVE)) {
-                        event.setCancelled(true);
-                    }
-
-                    boolean deny = false;
-                    if (!Stargate.canAccessNetwork(player, portal.getNetwork())) {
-                        deny = true;
-                    }
-
-                    if (!Stargate.canAccessPortal(player, portal, deny)) {
-                        Stargate.sendMessage(player, Stargate.getString("denyMsg"));
-                        return;
-                    }
-
-                    if ((!portal.isOpen()) && (!portal.isFixed())) {
-                        portal.cycleDestination(player, -1);
-                    }
-                }
-            }
-        }
-    }
 
     private class bListener implements Listener {
         @EventHandler
         public void onSignChange(SignChangeEvent event) {
-            if (event.isCancelled()) return;
+            if (event.isCancelled()) {
+                return;
+            }
             Player player = event.getPlayer();
             Block block = event.getBlock();
-            if (!(block.getBlockData() instanceof WallSign)) return;
+            if (!(block.getBlockData() instanceof WallSign)) {
+                return;
+            }
 
             final Portal portal = Portal.createPortal(event, player);
             // Not creating a gate, just placing a sign
-            if (portal == null) return;
+            if (portal == null) {
+                return;
+            }
 
             Stargate.sendMessage(player, Stargate.getString("createMsg"), false);
             Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName());
@@ -1104,7 +846,7 @@ public class Stargate extends JavaPlugin {
             // Handle keeping portal material and buttons around
             if (block.getType() == Material.NETHER_PORTAL) {
                 portal = Portal.getByEntrance(block);
-            } else if (Tag.BUTTONS.isTagged(block.getType())) {
+            } else if (Tag.BUTTONS.isTagged(block.getType()) || MaterialHelper.isWallCoral(block.getType())) {
                 portal = Portal.getByControl(block);
             }
             if (portal != null) event.setCancelled(true);