@Override
    public boolean check(UserContext user, Session source) {
      if (!permissionSession.check(user, source)) return false;

      // Is there a mapping to show?
      if (EventDateMapping.hasMapping(source.getUniqueId())) return true;

      // Is there a mapping to add?
      if (user.getCurrentAuthority().hasRight(Right.EventDateMappingEdit)
          && permissionEventDateMappingEdit.check(user, source)) return true;

      return false;
    }
    @Override
    public boolean check(UserContext user, Department source) {
      if (!permissionDepartment.check(user, source)) return false;

      if (!source.isAllowEvents()) return false;

      int nrRooms =
          ((Number)
                  DepartmentDAO.getInstance()
                      .getSession()
                      .createQuery(
                          "select count(r) from Room r "
                              + "where r.eventDepartment.uniqueId=:deptId")
                      .setLong("deptId", source.getUniqueId())
                      .setCacheable(true)
                      .uniqueResult())
              .intValue();

      if (nrRooms > 0) return true;

      int nrLocations =
          ((Number)
                  DepartmentDAO.getInstance()
                      .getSession()
                      .createQuery(
                          "select count(r) from NonUniversityLocation r "
                              + "where r.eventDepartment.uniqueId=:deptId")
                      .setLong("deptId", source.getUniqueId())
                      .setCacheable(true)
                      .uniqueResult())
              .intValue();

      return nrLocations > 0;
    }
    @Override
    public boolean check(UserContext user, Session source) {
      if (!permissionSession.check(user, source)) return false;

      return source.getStatusType() == null
          || !source.getStatusType().isActive()
          || source.getStatusType().isTestSession();
    }
    @Override
    public boolean check(UserContext user, TimetableManager source) {
      for (Department d : source.getDepartments()) {
        if (d.getSessionId().equals(user.getCurrentAcademicSessionId())) {
          return permissionSession.check(user, d.getSession());
        }
      }

      return true;
    }
    @Override
    public boolean check(UserContext user, InstructionalOffering source) {
      if (permissionOfferingLockNeeded.check(user, source)) return false;

      if (source.isNotOffered()) return false;

      if (permissionDepartment.check(
          user,
          source.getDepartment(),
          DepartmentStatusType.Status.OwnerEdit,
          DepartmentStatusType.Status.ManagerEdit)) return true;

      return false;
    }
    @Override
    public boolean check(UserContext user, Session source) {
      if (!permissionSession.check(user, source)) return false;

      int nrCommitted =
          ((Number)
                  SessionDAO.getInstance()
                      .getSession()
                      .createQuery(
                          "select count(s) from Solution s where s.owner.session.uniqueId = :sessionId and s.commited = true")
                      .setLong("sessionId", source.getUniqueId())
                      .setCacheable(true)
                      .uniqueResult())
              .intValue();

      return nrCommitted == 0;
    }
    @Override
    public boolean check(UserContext user, Department source) {
      if (!permissionDepartment.check(user, source)) return false;

      if (source.getSolverGroup() != null) return false;

      int nrOffered =
          ((Number)
                  DepartmentDAO.getInstance()
                      .getSession()
                      .createQuery(
                          "select count(io) from CourseOffering co inner join co.instructionalOffering io "
                              + "where co.subjectArea.department.uniqueId=:deptId and io.notOffered = 0")
                      .setLong("deptId", source.getUniqueId())
                      .setCacheable(true)
                      .uniqueResult())
              .intValue();

      return nrOffered == 0;
    }
    @Override
    public boolean check(UserContext user, Department source) {
      if (!permissionDepartmentEdit.check(user, source)) return false;

      if (source.isExternalManager()) {
        int nrExtManaged =
            ((Number)
                    DepartmentDAO.getInstance()
                        .getSession()
                        .createQuery(
                            "select count(c) from Class_ c where c.managingDept.uniqueId=:deptId")
                        .setLong("deptId", source.getUniqueId())
                        .setCacheable(true)
                        .uniqueResult())
                .intValue();

        return nrExtManaged == 0;
      } else {
        return source.getSubjectAreas().isEmpty();
      }
    }
    @Override
    public boolean check(UserContext user, Department source) {
      if (!permissionDepartment.check(user, source)) return false;

      return source.isAllowEvents() && !Roles.findAllInstructorRoles().isEmpty();
    }
 @Override
 public boolean check(UserContext user, SubjectArea source) {
   return permissionSession.check(user, source.getSession());
 }
  @Override
  public void onKeyPressedEvent(KeyPressedEvent event) {
    if (event.getScreenType() != ScreenType.GAME_SCREEN) {
      return;
    }
    SpoutPlayer player = event.getPlayer();

    PlayerOptions po = PlayerOptions.getPlayer(player);
    String msg = "";

    if (Utils.isValidModifier(event.getKey())) {
      PlayerOptions.addPressed(player.getName(), event.getKey());
      return;
    }

    ChooseMode mode = PlayerOptions.getMode(player);

    boolean valid = Utils.isValidKey(player, event.getKey());
    if (!valid) {
      switch (mode) {
        case SET:
        case GSET:
          player.sendMessage(ChatColor.RED + "That key combination is not valid.");
      }
      return;
    }

    LinkedHashSet<Keyboard> allPressed = PlayerOptions.getPressed(player.getName());
    allPressed.add(event.getKey());

    if (mode == ChooseMode.NONE) {
      if (!Permission.check(player, "SpoutKeyCommands.use")) {
        return;
      }

      PlayerCmd pc = PlayerCmd.get(player, allPressed);
      GlobalCmd gc = GlobalCmd.get(allPressed);
      if (pc == null && gc == null) {
        return;
      }

      String perf = po.getPreferred();

      if (perf.equalsIgnoreCase("global") && gc != null || pc == null) {
        player.performCommand(gc.getCommand());
      } else if (perf.equalsIgnoreCase("personal") && pc != null || pc != null) {
        player.performCommand(pc.getCommand());
      }

      return;
    }

    String cmd = PlayerOptions.getCmd(player);

    PluginManager pm = Bukkit.getServer().getPluginManager();
    String pluginName = SpoutKeyCommands.getInstance().getDescription().getName();

    PlayerCmd pc = null;
    GlobalCmd gc = null;

    switch (mode) {
      case SET:
        if (cmd.equals("")) {
          return;
        }
        msg =
            ChatColor.DARK_AQUA
                + "Command set to: "
                + ChatColor.GREEN
                + Utils.getKeyString(allPressed);

        pc = PlayerCmd.get(player, allPressed);
        if (pc != null) {
          if (!pluginName.equals(pc.getPlugin())) {
            Plugin p = pm.getPlugin(pc.getPlugin());
            if (p != null && p.isEnabled()) {
              msg = ChatColor.RED + "That key is already set by " + pc.getPlugin();
              break;
            }
          }

          pc.setCommand(cmd);
          pc.setPlugin(pluginName);
          SpoutKeyCommands.getInstance().getDatabase().update(pc);
          break;
        }

        pc = new PlayerCmd(allPressed, cmd, player, SpoutKeyCommands.getInstance());
        SpoutKeyCommands.getInstance().getDatabase().save(pc);
        break;

      case GSET:
        if (cmd.equals("")) {
          return;
        }
        msg =
            ChatColor.DARK_AQUA
                + "Global command set to: "
                + ChatColor.GREEN
                + Utils.getKeyString(allPressed);

        gc = GlobalCmd.get(allPressed);
        if (gc != null) {
          if (!pluginName.equals(gc.getPlugin())) {
            Plugin p = pm.getPlugin(gc.getPlugin());
            if (p != null && p.isEnabled()) {
              msg = ChatColor.RED + "That key is already set by " + gc.getPlugin();
              break;
            }
          }

          gc.setCommand(cmd);
          gc.setPlugin(pluginName);
          SpoutKeyCommands.getInstance().getDatabase().update(gc);
          break;
        }

        gc = new GlobalCmd(allPressed, cmd, SpoutKeyCommands.getInstance());
        SpoutKeyCommands.getInstance().getDatabase().save(gc);
        break;

      case UNSET:
        pc = PlayerCmd.get(player, allPressed);
        if (pc == null) {
          msg = ChatColor.RED + "No command on this combination";
          break;
        }

        if (!pluginName.equals(pc.getPlugin())) {
          Plugin p = pm.getPlugin(pc.getPlugin());
          if (p != null && p.isEnabled()) {
            msg = ChatColor.RED + "That key is set by " + pc.getPlugin();
            break;
          }
        }

        SpoutKeyCommands.getInstance().getDatabase().delete(pc);
        msg =
            ChatColor.DARK_AQUA
                + "Command unset from: "
                + ChatColor.GREEN
                + Utils.getKeyString(allPressed);
        break;

      case GUNSET:
        gc = GlobalCmd.get(allPressed);
        if (gc == null) {
          msg = ChatColor.RED + "No global command on this combination";
          break;
        }

        if (!pluginName.equals(gc.getPlugin())) {
          Plugin p = pm.getPlugin(gc.getPlugin());
          if (p != null && p.isEnabled()) {
            msg = ChatColor.RED + "That key is already set by " + gc.getPlugin();
            break;
          }
        }

        SpoutKeyCommands.getInstance().getDatabase().delete(gc);
        msg =
            ChatColor.DARK_AQUA
                + "Global command unset from: "
                + ChatColor.GREEN
                + Utils.getKeyString(allPressed);
        break;
    }

    player.sendMessage(msg);
  }