QueryOptions getQueryOptions(@Nullable UUID uuid, @Nullable String world) {
        ContextSet context;

        Player player = Optional.ofNullable(uuid).flatMap(u -> this.plugin.getBootstrap().getPlayer(u)).orElse(null);
        if (player != null) {
            context = this.plugin.getContextManager().getContext(player);
        } else {
            context = this.plugin.getContextManager().getStaticContext();
        }

        String playerWorld = player == null ? null : player.getWorld().getName();

        // if world is null, we want to do a lookup in the players current context
        // if world is not null, we want to do a lookup in that specific world
        if (world != null && !world.isEmpty() && !world.equalsIgnoreCase(playerWorld)) {
            MutableContextSet mutContext = context.mutableCopy();
            context = mutContext;

            // remove already accumulated worlds
            mutContext.removeAll(DefaultContextKeys.WORLD_KEY);
            // add the vault world
            mutContext.add(DefaultContextKeys.WORLD_KEY, world.toLowerCase(Locale.ROOT));
        }

        // if we're using a special vault server
        if (useVaultServer()) {
            MutableContextSet mutContext = context instanceof MutableContextSet ? (MutableContextSet) context : context.mutableCopy();
            context = mutContext;

            // remove the normal server context from the set
            mutContext.remove(DefaultContextKeys.SERVER_KEY, getServer());

            // add the vault specific server
            if (!getVaultServer().equals("global")) {
                mutContext.add(DefaultContextKeys.SERVER_KEY, getVaultServer());
            }
        }

        boolean op = false;
        if (player != null) {
            op = player.isOp();
        } else if (uuid != null && UniqueIdType.determineType(uuid, this.plugin).getType().equals("npc")) {
            op = this.plugin.getConfiguration().get(ConfigKeys.VAULT_NPC_OP_STATUS);
        }

        QueryOptions.Builder builder = QueryOptionsImpl.DEFAULT_CONTEXTUAL.toBuilder();
        builder.context(context);
        builder.flag(Flag.INCLUDE_NODES_WITHOUT_SERVER_CONTEXT, isIncludeGlobal());
        if (op) {
            builder.option(BukkitContextManager.OP_OPTION, true);
        }
        return builder.build();
    }
An implementation of the Vault {@link Permission} API using LuckPerms.

LuckPerms is a multithreaded permissions plugin, and some actions require considerable
time to execute. (database queries, re-population of caches, etc) In these cases, the
operations required to make the edit apply will be processed immediately, but the process
of saving the change to the plugin storage will happen in the background.

Methods that have to query data from the database will throw exceptions when called
from the main thread. Users of the Vault API expect these methods to be "main thread friendly",
which they simply cannot be, as LP utilises databases for data storage. Server admins
willing to take the risk of lagging their server can disable these exceptions in the config file.
bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/LuckPermsVaultPermission.java