diff --git a/.classpath b/.classpath
index 5ccc3e3..35410ea 100644
--- a/.classpath
+++ b/.classpath
@@ -3,5 +3,6 @@
 	
 	
 	
+	
 	
 
diff --git a/plugin.yml b/plugin.yml
index cc684d8..6906f27 100644
--- a/plugin.yml
+++ b/plugin.yml
@@ -1,6 +1,7 @@
 name: Craft Inc. Gates
 version: 2.0.1
 description: A plugin to create gates for fast traveling.
+softdepend: [Vault]
 author: tomco,  s1m0ne
 authors: [oloflarsson, locutus, DrAgonmoray, s1m0ne, tomco]
 website: http://www.craftinc.de/craftinc-gates/
diff --git a/pom.xml b/pom.xml
index 631b391..1ebb82f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,6 +19,13 @@
             jar
             compile
         
+        
+            net.milkbowl.vault
+            Vault
+            1.2.23-SNAPSHOT
+            jar
+            compile
+        
     
 
     
@@ -28,7 +35,7 @@
         src
         
             
-                src/resources
+                resources
             
         
     
@@ -38,5 +45,9 @@
             bukkit-repo
             http://repo.bukkit.org/content/groups/public
         
+        
+            vault-repo
+            http://ci.herocraftonline.com/plugin/repository/everything
+        
     
 
diff --git a/resources/plugin.yml b/resources/plugin.yml
new file mode 120000
index 0000000..db3e742
--- /dev/null
+++ b/resources/plugin.yml
@@ -0,0 +1 @@
+../plugin.yml
\ No newline at end of file
diff --git a/src/de/craftinc/gates/Plugin.java b/src/de/craftinc/gates/Plugin.java
index 0030974..38d05ba 100644
--- a/src/de/craftinc/gates/Plugin.java
+++ b/src/de/craftinc/gates/Plugin.java
@@ -10,12 +10,15 @@ import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import net.milkbowl.vault.permission.Permission;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandSender;
 import org.bukkit.configuration.file.FileConfiguration;
 import org.bukkit.configuration.file.YamlConfiguration;
 import org.bukkit.configuration.serialization.ConfigurationSerialization;
 import org.bukkit.plugin.PluginManager;
+import org.bukkit.plugin.RegisteredServiceProvider;
 import org.bukkit.plugin.java.JavaPlugin;
 
 import de.craftinc.gates.commands.*;
@@ -30,9 +33,11 @@ public class Plugin extends JavaPlugin
 	
 	public static final String permissionInfo = "craftincgates.info";
 	public static final String permissionManage = "craftincgates.manage";
-	public static final String permissionAll = "craftincgates.*";
+//	public static final String permissionAll = "craftincgates.*";
 	public static final String permissionUse = "craftincgates.use";
 	
+	public static Permission permission = null;
+	
 	public PluginPlayerListener playerListener = new PluginPlayerListener();
 	public PluginBlockListener blockListener = new PluginBlockListener();
 	public PluginPortalListener portalListener = new PluginPortalListener();
@@ -55,9 +60,25 @@ public class Plugin extends JavaPlugin
 	@Override
 	public void onLoad() 
 	{
+		setupPermissions();
 		ConfigurationSerialization.registerClass(Gate.class);
 	}
 	
+	
+	private void setupPermissions()
+	{
+		if (getServer().getPluginManager().getPlugin("Vault") == null) {
+            return;
+        }
+		
+		RegisteredServiceProvider rsp = getServer().getServicesManager().getRegistration(Permission.class);
+		
+		if (rsp != null)
+		{
+			permission = rsp.getProvider();
+		}
+	}
+	
 
 	@Override
 	public void onDisable() 
diff --git a/src/de/craftinc/gates/commands/BaseCommand.java b/src/de/craftinc/gates/commands/BaseCommand.java
index f3b32ac..582409e 100644
--- a/src/de/craftinc/gates/commands/BaseCommand.java
+++ b/src/de/craftinc/gates/commands/BaseCommand.java
@@ -12,24 +12,26 @@ import de.craftinc.gates.util.TextUtil;
 
 public abstract class BaseCommand 
 {
-	public List aliases;
-	public List requiredParameters;
-	public List optionalParameters;
+	protected List aliases;
+	protected List requiredParameters;
+	protected List optionalParameters;
 	
-	public String helpDescription;
+	protected String helpDescription;
 	
-	public CommandSender sender;
-	public boolean senderMustBePlayer;
-	public boolean hasGateParam;
-	public Player player;
-	public Gate gate;
+	protected List parameters;
+	protected CommandSender sender;
+	protected Player player;
+	protected Gate gate;
 	
-	public List parameters;
+	protected boolean senderMustBePlayer;
+	protected boolean hasGateParam;
 	
-	public String requiredPermission;
+	protected String requiredPermission;
+	protected boolean needsPermissionAtCurrentLocation;
 	
 	
-	public BaseCommand() {
+	public BaseCommand() 
+	{
 		aliases = new ArrayList();
 		requiredParameters = new ArrayList();
 		optionalParameters = new ArrayList();
@@ -43,12 +45,13 @@ public abstract class BaseCommand
 	public List getAliases() {
 		return aliases;
 	}
-		
+	
+	
 	public void execute(CommandSender sender, List parameters) {
 		this.sender = sender;
 		this.parameters = parameters;
 		
-		if ( ! validateCall()) {
+		if (!this.validateCall()) {
 			return;
 		}
 		
@@ -56,79 +59,146 @@ public abstract class BaseCommand
 			this.player = (Player)sender;
 		}
 		
-		perform();
+		this.perform();
 	}
 	
-	public void perform() {
-		
-	}
 	
-	public void sendMessage(String message) {
+	abstract protected void perform();
+	
+	
+	protected void sendMessage(String message) {
 		sender.sendMessage(message);
 	}
 	
-	public void sendMessage(List messages) {
+	
+	protected void sendMessage(List messages) {
 		for(String message : messages) {
 			this.sendMessage(message);
 		}
 	}
 	
-	public boolean validateCall() 
+	
+	protected boolean validateCall() 
 	{
-		// validate player		
-		if ( this.senderMustBePlayer && ! (sender instanceof Player)) 
+		boolean allParamtertersThere = parameters.size() < requiredParameters.size();
+		boolean senderIsPlayer = this.sender instanceof Player;
+		boolean parameterIsGate = this.parameters.size() > 0 ? this.getGateForParamater(this.parameters.get(0)) : false;
+		boolean senderHasPermission;
+		
+		try {
+			senderHasPermission = this.hasPermission();
+		} 
+		catch (Exception e) { // the gate paramter is missing or incorrect!
+			senderHasPermission = parameterIsGate ? false : true; // only display the lack of permission message if there is a gate
+																  // this should prevent giving permission to the user if there is
+																  // a bug inside the permission validation code.
+		}
+		
+
+		if(!senderHasPermission) 
+		{
+			sendMessage("You lack the permissions to " + this.helpDescription.toLowerCase() + ".");
+			return false;
+		}
+		
+			
+		if (this.senderMustBePlayer && !senderIsPlayer) 
 		{
 			sendMessage("This command can only be used by ingame players.");
 			return false;
 		}
 		
-		// validate permission
-		if( !hasPermission(sender)) 
+		if (this.hasGateParam && !parameterIsGate) 
 		{
-			sendMessage("You lack the permissions to "+this.helpDescription.toLowerCase()+".");
+			sendMessage("There exists no gate with id " + this.parameters.get(0));
 			return false;
 		}
-		
-		// valide parameter count
-		if (parameters.size() < requiredParameters.size()) 
+	
+		if (allParamtertersThere) 
 		{
-			sendMessage("Usage: "+this.getUseageTemplate(true));
+			sendMessage("Usage: " + this.getUseageTemplate(true));
 			return false;
 		}
 		
-		// validate gate parameter
-		if (this.hasGateParam) 
-		{
-			String id = parameters.get(0);
-			
-			if ( ! Gate.exists(id)) 
-			{
-				sendMessage("There exists no gate with id "+id);
-				return false;
-			}
-			gate = Gate.get(id);
-		}
-		
 		return true;
 	}
 	
-	public boolean hasPermission(CommandSender sender) 
+	
+	protected boolean getGateForParamater(String param)
 	{
-		if (sender.hasPermission(Plugin.permissionAll)) {
+		if (!Gate.exists(param))
+		{
+			return false;
+		}
+		else
+		{
+			gate = Gate.get(param);
 			return true;
 		}
-		
-		if (sender.hasPermission(requiredPermission)) {
-			return true;
-		}
-		
-		return false; 
 	}
 	
+	
+	
+	protected boolean hasPermission() throws Exception
+	{		
+		if (Plugin.permission == null) // fallback Ð use the standard bukkit permission system
+		{
+			return this.sender.hasPermission(this.requiredPermission);
+		}
+		
+		
+		if (this.requiredPermission.equals(Plugin.permissionInfo))
+		{
+			return Plugin.permission.has(this.player.getWorld(), this.player.getName(), this.requiredPermission);
+		}
+		
+		
+		if (this.requiredPermission.equals(Plugin.permissionUse) )
+		{
+			return this.hasPermissionAtGateLocationAndExit();
+		}
+			
+		
+		if (this.requiredPermission.equals(Plugin.permissionManage))
+		{
+			if (this.needsPermissionAtCurrentLocation && this.hasGateParam)
+			{
+				boolean hasPersmissionAtCurrentLocation = Plugin.permission.has(this.player.getWorld(), this.player.getName(), this.requiredPermission);
+				return hasPersmissionAtCurrentLocation && this.hasPermissionAtGateLocationAndExit();
+			}
+			else if (this.needsPermissionAtCurrentLocation)
+			{
+				return Plugin.permission.has(this.player.getWorld(), this.player.getName(), this.requiredPermission);
+			}
+			else
+			{
+				return this.hasPermissionAtGateLocationAndExit();
+			}
+		}
+			
+		
+		return false;
+	}
+	
+	
+	protected boolean hasPermissionAtGateLocationAndExit() throws Exception
+	{
+		if (this.gate == null) // make sure we don't run into a nullpointer exception
+		{
+			throw new Exception("Cannot check permissons with no gate provided!");
+		}
+		
+		boolean permAtLocation = Plugin.permission.has(this.gate.getLocation().getWorld(), player.getName(), this.requiredPermission);
+		boolean permAtExit = Plugin.permission.has(this.gate.getExit().getWorld(), player.getName(), this.requiredPermission);
+		
+		return permAtLocation && permAtExit;
+	}
+	
+	
 	// -------------------------------------------- //
 	// Help and usage description
 	// -------------------------------------------- //
-	public String getUsageTemplate(boolean withColor, boolean withDescription) {
+	protected String getUsageTemplate(boolean withColor, boolean withDescription) {
 		String ret = "";
 		
 //		if (withColor) {
@@ -159,11 +229,11 @@ public abstract class BaseCommand
 		return ret;
 	}
 	
-	public String getUseageTemplate(boolean withColor) {
+	protected String getUseageTemplate(boolean withColor) {
 		return getUsageTemplate(withColor, false);
 	}
 	
-	public String getUseageTemplate() {
+	protected String getUseageTemplate() {
 		return getUseageTemplate(true);
 	}
 }
diff --git a/src/de/craftinc/gates/commands/CommandClose.java b/src/de/craftinc/gates/commands/CommandClose.java
index 8c1c3f4..dab8f59 100644
--- a/src/de/craftinc/gates/commands/CommandClose.java
+++ b/src/de/craftinc/gates/commands/CommandClose.java
@@ -14,6 +14,8 @@ public class CommandClose extends BaseCommand
 		helpDescription = "Closes a gate to prevent players from using it.";
 		
 		requiredPermission = Plugin.permissionManage;
+		
+		needsPermissionAtCurrentLocation = false;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandCreate.java b/src/de/craftinc/gates/commands/CommandCreate.java
index af331b1..13c4243 100644
--- a/src/de/craftinc/gates/commands/CommandCreate.java
+++ b/src/de/craftinc/gates/commands/CommandCreate.java
@@ -21,6 +21,8 @@ public class CommandCreate extends BaseLocationCommand
 		helpDescription = "Create a gate at your current location.";
 		
 		requiredPermission = Plugin.permissionManage;
+		
+		needsPermissionAtCurrentLocation = true;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandDelete.java b/src/de/craftinc/gates/commands/CommandDelete.java
index b01a78a..23f0a07 100644
--- a/src/de/craftinc/gates/commands/CommandDelete.java
+++ b/src/de/craftinc/gates/commands/CommandDelete.java
@@ -19,6 +19,8 @@ public class CommandDelete extends BaseCommand
 		helpDescription = "Removes the gate from the game.";
 		
 		requiredPermission = Plugin.permissionManage;
+		
+		needsPermissionAtCurrentLocation = false;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandHelp.java b/src/de/craftinc/gates/commands/CommandHelp.java
index 759f97c..4b0a9c6 100644
--- a/src/de/craftinc/gates/commands/CommandHelp.java
+++ b/src/de/craftinc/gates/commands/CommandHelp.java
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 
 import org.bukkit.command.CommandSender;
 
+import de.craftinc.gates.Gate;
 import de.craftinc.gates.util.TextUtil;
 
 public class CommandHelp extends BaseCommand 
@@ -19,10 +20,12 @@ public class CommandHelp extends BaseCommand
 		hasGateParam = false;
 		
 		helpDescription = "Prints a list of all availible commands.";
+		
+		needsPermissionAtCurrentLocation = false;
 	}
 	
-	@Override
-	public boolean hasPermission(CommandSender sender) 
+
+	public boolean hasPermission(CommandSender sender, Gate gate) 
 	{
 		return true;
 	}
diff --git a/src/de/craftinc/gates/commands/CommandInfo.java b/src/de/craftinc/gates/commands/CommandInfo.java
index f37b0e3..0a2d964 100644
--- a/src/de/craftinc/gates/commands/CommandInfo.java
+++ b/src/de/craftinc/gates/commands/CommandInfo.java
@@ -17,6 +17,8 @@ public class CommandInfo extends BaseCommand
 		helpDescription = "Prints detailed informations about a certain gate.";
 		
 		requiredPermission = Plugin.permissionInfo;
+		
+		needsPermissionAtCurrentLocation = false;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandList.java b/src/de/craftinc/gates/commands/CommandList.java
index 68c805d..26b9a27 100644
--- a/src/de/craftinc/gates/commands/CommandList.java
+++ b/src/de/craftinc/gates/commands/CommandList.java
@@ -25,6 +25,8 @@ public class CommandList extends BaseCommand
 		helpDescription = "Prints a list of all availible gates.";
 		
 		requiredPermission = Plugin.permissionInfo;
+		
+		needsPermissionAtCurrentLocation = false;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandOpen.java b/src/de/craftinc/gates/commands/CommandOpen.java
index 97a3046..3d1ecf5 100644
--- a/src/de/craftinc/gates/commands/CommandOpen.java
+++ b/src/de/craftinc/gates/commands/CommandOpen.java
@@ -15,6 +15,8 @@ public class CommandOpen extends BaseCommand
 		helpDescription = "Open a gate so players can use it.";
 		
 		requiredPermission = Plugin.permissionManage;
+		
+		needsPermissionAtCurrentLocation = false;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandRename.java b/src/de/craftinc/gates/commands/CommandRename.java
index 4149c7e..0d5f487 100644
--- a/src/de/craftinc/gates/commands/CommandRename.java
+++ b/src/de/craftinc/gates/commands/CommandRename.java
@@ -21,6 +21,8 @@ public class CommandRename extends BaseCommand
 		helpDescription = "Changes the id of a gate.";
 		
 		requiredPermission = Plugin.permissionManage;
+		
+		needsPermissionAtCurrentLocation = false;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandSetExit.java b/src/de/craftinc/gates/commands/CommandSetExit.java
index 2b73541..0abe583 100644
--- a/src/de/craftinc/gates/commands/CommandSetExit.java
+++ b/src/de/craftinc/gates/commands/CommandSetExit.java
@@ -16,6 +16,8 @@ public class CommandSetExit extends BaseCommand
 		helpDescription = "Changes the location where the gate will teleport players to your current location.";
 		
 		requiredPermission = Plugin.permissionManage;
+		
+		needsPermissionAtCurrentLocation = true;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandSetHidden.java b/src/de/craftinc/gates/commands/CommandSetHidden.java
index 8cca0e9..174f030 100644
--- a/src/de/craftinc/gates/commands/CommandSetHidden.java
+++ b/src/de/craftinc/gates/commands/CommandSetHidden.java
@@ -15,6 +15,8 @@ public class CommandSetHidden extends BaseCommand
 		helpDescription = "Makes a gate NOT consist of gate blocks while open.";
 		
 		requiredPermission = Plugin.permissionManage;
+		
+		needsPermissionAtCurrentLocation = false;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandSetLocation.java b/src/de/craftinc/gates/commands/CommandSetLocation.java
index 397770a..341c308 100644
--- a/src/de/craftinc/gates/commands/CommandSetLocation.java
+++ b/src/de/craftinc/gates/commands/CommandSetLocation.java
@@ -19,6 +19,8 @@ public class CommandSetLocation extends BaseLocationCommand
 		helpDescription = "Set the entrance of the gate to your current location.";
 		
 		requiredPermission = Plugin.permissionManage;
+		
+		needsPermissionAtCurrentLocation = true;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/commands/CommandSetVisible.java b/src/de/craftinc/gates/commands/CommandSetVisible.java
index d1e7777..02e230b 100644
--- a/src/de/craftinc/gates/commands/CommandSetVisible.java
+++ b/src/de/craftinc/gates/commands/CommandSetVisible.java
@@ -16,6 +16,8 @@ public class CommandSetVisible extends BaseCommand
 		helpDescription = "Make that gate visible";
 		
 		requiredPermission = Plugin.permissionManage;
+		
+		needsPermissionAtCurrentLocation = false;
 	}
 	
 	
diff --git a/src/de/craftinc/gates/listeners/BaseLocationListener.java b/src/de/craftinc/gates/listeners/BaseLocationListener.java
index a58811b..a60299c 100644
--- a/src/de/craftinc/gates/listeners/BaseLocationListener.java
+++ b/src/de/craftinc/gates/listeners/BaseLocationListener.java
@@ -57,8 +57,6 @@ public abstract class BaseLocationListener
 		Block blockTo = e.getFrom().getBlock();
 		Block blockToUp = blockTo.getRelative(BlockFace.UP);
 		
-		System.out.println(blockTo.getLocation().getWorld().getName());
-		
 		
 		for (Gate g : Gate.getAll()) {
 			// Check if the location matches
diff --git a/src/de/craftinc/gates/listeners/PluginPlayerListener.java b/src/de/craftinc/gates/listeners/PluginPlayerListener.java
index 233bf70..430918c 100644
--- a/src/de/craftinc/gates/listeners/PluginPlayerListener.java
+++ b/src/de/craftinc/gates/listeners/PluginPlayerListener.java
@@ -25,10 +25,6 @@ public class PluginPlayerListener extends BaseLocationListener implements Listen
 			return;
 		}
 		
-		// Check for permission
-		if (!hasPermission(event.getPlayer())) {
-			return;
-		}
 		
 		// Find the gate at the current location.
 		Gate gateAtLocation = getValidGateAtPlayerLocation(event);
@@ -38,6 +34,11 @@ public class PluginPlayerListener extends BaseLocationListener implements Listen
 			return;
 		}
 		
+		// Check for permission
+		if (!hasPermission(event.getPlayer(), gateAtLocation)) {
+			return;
+		}
+		
 		// Teleport the player
 		checkChunkLoad(gateAtLocation.getLocation().getBlock());
 		
@@ -72,7 +73,17 @@ public class PluginPlayerListener extends BaseLocationListener implements Listen
 	}
 	
 	
-	protected boolean hasPermission(Player player) {
-        return player.hasPermission(Plugin.permissionUse) || player.hasPermission(Plugin.permissionAll);
+	protected boolean hasPermission(Player player, Gate gate) 
+	{
+		if (Plugin.permission == null) // fallback Ð use the standard bukkit permission system
+		{
+			return player.hasPermission(Plugin.permissionUse);
+		}
+		else {
+			boolean permAtLocation = Plugin.permission.has(gate.getLocation().getWorld(), player.getName(), Plugin.permissionUse);
+			boolean permAtExit = Plugin.permission.has(gate.getExit().getWorld(), player.getName(), Plugin.permissionUse);
+			
+			return permAtLocation && permAtExit;
+		}
     }
 }