Repository: mockbukkit/mockbukkit
Issue: Player#isPermissionSet(String) returns false when PermissionAttachment set to false

```java
Player permissible = server.addPlayer();
permissible.addAttachment(
      plugin,
      "test.perm",
      false,
);
permissible.isPermissionSet("test.perm"); // returns false but it should be true
permissible.permissionValue("test.perm"); // returns TriState.NOT_SET but is should be TriState.FALSE
```

Maybe permission check logic has a bug?

Changed files:
src/main/java/be/seeseemelk/mockbukkit/entity/EntityMock.java, src/test/java/be/seeseemelk/mockbukkit/entity/EntityMockTest.java

diff --git a/src/main/java/be/seeseemelk/mockbukkit/entity/EntityMock.java b/src/main/java/be/seeseemelk/mockbukkit/entity/EntityMock.java
index 282e9cc0..9c68830b 100644
--- a/src/main/java/be/seeseemelk/mockbukkit/entity/EntityMock.java
+++ b/src/main/java/be/seeseemelk/mockbukkit/entity/EntityMock.java
@@ -33,10 +33,10 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
 import org.bukkit.event.vehicle.VehicleEnterEvent;
 import org.bukkit.event.vehicle.VehicleExitEvent;
 import org.bukkit.metadata.MetadataValue;
+import org.bukkit.permissions.PermissibleBase;
 import org.bukkit.permissions.Permission;
 import org.bukkit.permissions.PermissionAttachment;
 import org.bukkit.permissions.PermissionAttachmentInfo;
-import org.bukkit.permissions.PermissionRemovedExecutor;
 import org.bukkit.persistence.PersistentDataContainer;
 import org.bukkit.plugin.Plugin;
 import org.bukkit.util.BoundingBox;
@@ -50,8 +50,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Locale;
-import java.util.Map;
 import java.util.Queue;
 import java.util.Set;
 import java.util.UUID;
@@ -80,7 +78,7 @@ public abstract class EntityMock extends Entity.Spigot implements Entity, Messag
 	private boolean invulnerable;
 	private boolean glowingFlag = false;
 	private final Queue<Component> messages = new LinkedTransferQueue<>();
-	private final Set<PermissionAttachment> permissionAttachments = new HashSet<>();
+	private final PermissibleBase perms;
 	private @NotNull Vector velocity = new Vector(0, 0, 0);
 	private float fallDistance;
 	private int fireTicks = -20;
@@ -96,6 +94,8 @@ public abstract class EntityMock extends Entity.Spigot implements Entity, Messag
 		this.server = server;
 		this.uuid = uuid;
 
+		this.perms = new PermissibleBase(this);
+
 		if (!Bukkit.getWorlds().isEmpty())
 			location = Bukkit.getWorlds().get(0).getSpawnLocation();
 		else
@@ -426,115 +426,67 @@ public abstract class EntityMock extends Entity.Spigot implements Entity, Messag
 	@Override
 	public boolean isPermissionSet(@NotNull String name)
 	{
-		Preconditions.checkNotNull(name, "Name cannot be null");
-		return permissionAttachments.stream()
-				.map(PermissionAttachment::getPermissions)
-				.anyMatch(permissions -> permissions.containsKey(name) && permissions.get(name));
+		return this.perms.isPermissionSet(name);
 	}
 
 	@Override
 	public boolean isPermissionSet(@NotNull Permission perm)
 	{
-		Preconditions.checkNotNull(perm, "Permission cannot be null");
-		return isPermissionSet(perm.getName().toLowerCase(Locale.ENGLISH));
+		return this.perms.isPermissionSet(perm);
 	}
 
 	@Override
 	public boolean hasPermission(@NotNull String name)
 	{
-		Preconditions.checkNotNull(name, "Name cannot be null");
-		if (isPermissionSet(name))
-		{
-			return true;
-		}
-
-		Permission perm = server.getPluginManager().getPermission(name);
-		return perm != null ? hasPermission(perm) : Permission.DEFAULT_PERMISSION.getValue(isOp());
+		return this.perms.hasPermission(name);
 	}
 
 	@Override
 	public boolean hasPermission(@NotNull Permission perm)
 	{
-		Preconditions.checkNotNull(perm, "Permission cannot be null");
-		return isPermissionSet(perm) || perm.getDefault().getValue(isOp());
+		return this.perms.hasPermission(perm);
 	}
 
 	@Override
 	public @NotNull PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value)
 	{
-		Preconditions.checkNotNull(plugin, "Plugin cannot be null");
-		Preconditions.checkNotNull(name, "Name cannot be null");
-		PermissionAttachment attachment = addAttachment(plugin);
-		attachment.setPermission(name, value);
-		return attachment;
+		return this.perms.addAttachment(plugin, name, value);
 	}
 
 	@Override
 	public @NotNull PermissionAttachment addAttachment(@NotNull Plugin plugin)
 	{
-		Preconditions.checkNotNull(plugin, "Plugin cannot be null");
-		PermissionAttachment attachment = new PermissionAttachment(plugin, this);
-		permissionAttachments.add(attachment);
-		return attachment;
+		return this.perms.addAttachment(plugin);
 	}
 
 	@Override
 	public PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String name, boolean value, int ticks)
 	{
-		// TODO Auto-generated constructor stub
-		throw new UnimplementedOperationException();
+		return this.perms.addAttachment(plugin, name, value, ticks);
 	}
 
 	@Override
 	public PermissionAttachment addAttachment(@NotNull Plugin plugin, int ticks)
 	{
-		// TODO Auto-generated constructor stub
-		throw new UnimplementedOperationException();
+		return this.perms.addAttachment(plugin, ticks);
 	}
 
 	@Override
 	public void removeAttachment(@NotNull PermissionAttachment attachment)
 	{
-		Preconditions.checkNotNull(attachment, "Attachment cannot be null");
-
-		if (permissionAttachments.contains(attachment))
-		{
-			permissionAttachments.remove(attachment);
-			PermissionRemovedExecutor ex = attachment.getRemovalCallback();
-
-			if (ex != null)
-			{
-				ex.attachmentRemoved(attachment);
-			}
-
-			recalculatePermissions();
-		}
-		else
-		{
-			throw new IllegalArgumentException("Given attachment is not part of Permissible object " + this);
-		}
+		this.perms.removeAttachment(attachment);
 	}
 
 	@Override
 	public void recalculatePermissions()
 	{
-
+		this.perms.recalculatePermissions();
 	}
 
 	@Override
 	public @NotNull Set<PermissionAttachmentInfo> getEffectivePermissions()
 	{
-		HashSet<PermissionAttachmentInfo> permissionAttachmentInfos = new HashSet<>();
-
-		for (PermissionAttachment permissionAttachment : permissionAttachments)
-		{
-			for (Map.Entry<String, Boolean> entry : permissionAttachment.getPermissions().entrySet())
-			{
-				permissionAttachmentInfos.add(new PermissionAttachmentInfo(this, entry.getKey(), permissionAttachment, entry.getValue()));
-			}
-		}
-
-		return permissionAttachmentInfos;
+		return this.perms.getEffectivePermissions();
 	}
 
 	@Override
diff --git a/src/test/java/be/seeseemelk/mockbukkit/entity/EntityMockTest.java b/src/test/java/be/seeseemelk/mockbukkit/entity/EntityMockTest.java
index 5fb41446..897637f6 100644
--- a/src/test/java/be/seeseemelk/mockbukkit/entity/EntityMockTest.java
+++ b/src/test/java/be/seeseemelk/mockbukkit/entity/EntityMockTest.java
@@ -392,89 +392,103 @@ class EntityMockTest
 	}
 
 	@Test
-	void hasPermission_NotAddedNotDefault_DoesNotHavePermission()
+	void addAttachment_True_Has()
 	{
-		Permission permission = new Permission("mockbukkit.perm", PermissionDefault.FALSE);
-		server.getPluginManager().addPermission(permission);
-		assertFalse(entity.hasPermission("mockbukkit.perm"));
+		entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", true);
+		assertTrue(entity.hasPermission("test.permission"));
 	}
 
 	@Test
-	void hasPermission_NotAddedButDefault_DoesPermission()
+	void addAttachment_False_DoesntHave()
 	{
-		MockPlugin plugin = MockBukkit.createMockPlugin();
-		Permission permission = new Permission("mockbukkit.perm", PermissionDefault.TRUE);
-		server.getPluginManager().addPermission(permission);
-		entity.addAttachment(plugin, "mockbukkit.perm", true);
-		assertTrue(entity.hasPermission("mockbukkit.perm"));
+		entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", false);
+		assertFalse(entity.hasPermission("test.permission"));
 	}
 
 	@Test
-	void addAttachment_PermissionObject_PermissionAdded()
+	void addAttachment_RemovedAfterTicks()
 	{
-		MockPlugin plugin = MockBukkit.createMockPlugin();
-		Permission permission = new Permission("mockbukkit.perm", PermissionDefault.FALSE);
-		server.getPluginManager().addPermission(permission);
-		PermissionAttachment attachment = entity.addAttachment(plugin);
-		attachment.setPermission(permission, true);
-		assertTrue(entity.hasPermission("mockbukkit.perm"));
+		entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", true, 10);
+		assertTrue(entity.isPermissionSet("test.permission"));
+		server.getScheduler().performTicks(9);
+		assertTrue(entity.isPermissionSet("test.permission"));
+		server.getScheduler().performTicks(10);
+		assertFalse(entity.isPermissionSet("test.permission"));
 	}
 
 	@Test
-	void addAttachment_PermissionName_PermissionAdded()
+	void removeAttachment_RemovesAttachment()
 	{
-		MockPlugin plugin = MockBukkit.createMockPlugin();
-		Permission permission = new Permission("mockbukkit.perm", PermissionDefault.TRUE);
-		server.getPluginManager().addPermission(permission);
-		PermissionAttachment attachment = entity.addAttachment(plugin);
-		attachment.setPermission(permission.getName(), true);
-		assertTrue(entity.hasPermission("mockbukkit.perm"));
+		PermissionAttachment att = entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", true);
+		assertTrue(entity.hasPermission("test.permission"));
+		entity.removeAttachment(att);
+		assertFalse(entity.hasPermission("test.permission"));
 	}
 
 	@Test
-	void addPermission_String_PermissionAdded()
+	void isPermissionSet_String_IsSet_True()
 	{
-		MockPlugin plugin = MockBukkit.createMockPlugin();
-		Permission permission = new Permission("mockbukkit.perm", PermissionDefault.TRUE);
-		server.getPluginManager().addPermission(permission);
-		PermissionAttachment attachment = entity.addAttachment(plugin);
-		attachment.setPermission(permission.getName(), true);
-		assertTrue(entity.hasPermission("mockbukkit.perm"));
+		entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", true);
+		assertTrue(entity.isPermissionSet("test.permission"));
 	}
 
 	@Test
-	void getEffectivePermissions_GetPermissionsList()
+	void isPermissionSet_String_IsntSet_False()
 	{
-		MockPlugin plugin = MockBukkit.createMockPlugin();
-		entity.addAttachment(plugin, "mockbukkit.perm", true);
-		entity.addAttachment(plugin, "mockbukkit.perm2", true);
-		entity.addAttachment(plugin, "mockbukkit.perm3", false);
+		assertFalse(entity.isPermissionSet("test.permission"));
+	}
 
-		Set<PermissionAttachmentInfo> effectivePermissions = entity.getEffectivePermissions();
-		assertEquals(3, effectivePermissions.size());
+	@Test
+	void isPermissionSet_Permission_IsSet_True()
+	{
+		entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", true);
+		assertTrue(entity.isPermissionSet(new Permission("test.permission")));
+	}
 
-		Set<String> permissions = effectivePermissions.stream().map(PermissionAttachmentInfo::getPermission).collect(Collectors.toSet());
-		assertTrue(permissions.contains("mockbukkit.perm"));
-		assertTrue(permissions.contains("mockbukkit.perm2"));
-		assertTrue(permissions.contains("mockbukkit.perm3"));
+	@Test
+	void isPermissionSet_Permission_IsntSet_False()
+	{
+		assertFalse(entity.isPermissionSet(new Permission("test.permission")));
+	}
 
-		Optional<PermissionAttachmentInfo> first = effectivePermissions.stream().filter(permissionAttachmentInfo -> permissionAttachmentInfo.getPermission().equals("mockbukkit.perm3")).findFirst();
-		assertTrue(first.isPresent());
-		assertFalse(first.get().getValue());
+	@Test
+	void hasPermission_String_SetTrue_True()
+	{
+		entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", true);
+		assertTrue(entity.hasPermission("test.permission"));
 	}
 
 	@Test
-	void removeAttachment_RemovesPermission()
+	void hasPermission_String_SetFalse_True()
 	{
-		MockPlugin plugin = MockBukkit.createMockPlugin();
-		Permission permission = new Permission("mockbukkit.perm");
-		server.getPluginManager().addPermission(permission);
-		PermissionAttachment attachment = entity.addAttachment(plugin);
-		attachment.setPermission(permission.getName(), true);
-		assertTrue(entity.hasPermission("mockbukkit.perm"));
-
-		entity.removeAttachment(attachment);
-		assertFalse(entity.hasPermission("mockbukkit.perm"));
+		entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", false);
+		assertFalse(entity.hasPermission("test.permission"));
+	}
+
+	@Test
+	void hasPermission_String_NotSet_True()
+	{
+		assertFalse(entity.hasPermission("test.permission"));
+	}
+
+	@Test
+	void hasPermission_Permission_SetTrue_True()
+	{
+		entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", true);
+		assertTrue(entity.hasPermission(new Permission("test.permission")));
+	}
+
+	@Test
+	void hasPermission_Permission_SetFalse_True()
+	{
+		entity.addAttachment(MockBukkit.createMockPlugin(), "test.permission", false);
+		assertFalse(entity.hasPermission(new Permission("test.permission")));
+	}
+
+	@Test
+	void hasPermission_Permission_NotSet_True()
+	{
+		assertTrue(entity.hasPermission(new Permission("test.permission", PermissionDefault.TRUE)));
 	}
 
 	@Test