public <T extends Event> T callEvent(T event) {
    HandlerList handlers = event.getHandlers();
    ListenerRegistration[] listeners = handlers.getRegisteredListeners();

    if (listeners != null) {
      for (ListenerRegistration listener : listeners) {
        try {
          if (!event.isCancelled() || listener.getOrder().ignoresCancelled()) {
            listener.getExecutor().execute(event);
          }
        } catch (Throwable ex) {
          Spout.getEngine()
              .getLogger()
              .log(
                  Level.SEVERE,
                  "Could not pass event "
                      + event.getEventName()
                      + " to "
                      + listener.getOwner().getClass().getName(),
                  ex);
        }
      }
      event.setHasBeenCalled(true);
    }
    return event;
  }
  /**
   * Registers the given event handler.
   *
   * @param handler The {@link EventHandler} to register.
   */
  protected synchronized void register(final EventHandler handler) {
    assert handler != null : "Handler cannot be null!";

    SimpleEventManager.LOGGER.debug("Registering event handler " + handler);

    final Object obj = handler.getListenerObject();
    final Method method = handler.getListenerMethod();
    final Class<?> clazz = method.getDeclaringClass();

    if (!method.isAnnotationPresent(EventListener.class)) {
      SimpleEventManager.LOGGER.debug("Skipping event handler " + handler);

      return;
    }

    SimpleEventManager.LOGGER.debug("Processing event handler " + handler);

    assert obj != null || Modifier.isStatic(method.getModifiers())
        : "Method \""
            + method.getName()
            + "\" in class \""
            + clazz.getName()
            + "\" cannot be non-static if obj is null!";
    assert method.getParameterTypes().length == 1
            && method.getParameterTypes()[0].equals(EventContext.class)
        : "The "
            + "arguments of the method \""
            + method.getName()
            + "\" in class \""
            + clazz.getName()
            + "\" are wrong! The first (and only) argument should have the type \""
            + EventContext.class.getName()
            + "\"!";

    final Class<? extends AbstractEvent> eventClass =
        method.getAnnotation(EventListener.class).value();

    final HandlerList handlers;
    try {
      final Field handlersField = eventClass.getDeclaredField("HANDLERS");

      final boolean handlersFieldAccessible = handlersField.isAccessible();
      handlersField.setAccessible(true);

      handlers = (HandlerList) handlersField.get(obj);

      handlersField.setAccessible(handlersFieldAccessible);
    } catch (final IllegalArgumentException cause) {
      throw new EventException(
          "An error occurred whilest retriving handler list from class \""
              + clazz.getName()
              + "\"!",
          cause);
    } catch (final SecurityException cause) {
      throw new EventException(
          "An error occurred whilest retriving handler list from class \""
              + clazz.getName()
              + "\"!",
          cause);
    } catch (final IllegalAccessException cause) {
      throw new EventException(
          "An error occurred whilest retriving handler list from class \""
              + clazz.getName()
              + "\"!",
          cause);
    } catch (final NoSuchFieldException cause) {
      throw new EventException(
          "An error occurred whilest retriving handler list from class \""
              + clazz.getName()
              + "\"!",
          cause);
    }

    handlers.add(new SimpleEventHandler(obj, method));

    SimpleEventManager.LOGGER.debug("Registration of event handler finished");
  }