@Override
  public synchronized Collection<StateHolder> selectAll(long timeout, TimeUnit timeUnit)
      throws InterruptedException {
    Timer timer = new Timer(timeout, timeUnit).start();
    List<StateHolder> result = new ArrayList<StateHolder>();
    List<Object> inState = new ArrayList<Object>();

    while (!timer.time()) {
      if (watchedObjects.isEmpty())
        throw new IllegalArgumentException("register some objects to wait its states");
      for (Map.Entry<Object, List<State>> en : watchedObjects.entrySet()) {
        for (State state : en.getValue()) {
          if (state.checkState(en.getKey())) {
            result.add(new StateHolder(state, en.getKey()));
            if (!inState.contains(en.getKey())) inState.add(en.getKey());
          }
        }
      }
      if (inState.containsAll(watchedObjects.keySet())) return result;
      else result.clear();
      if (timer.left() == 0) this.wait();
      else this.wait(timer.left());
    }
    return null;
  }
 @Override
 public synchronized StateHolder selectFirst(long timeout, TimeUnit timeUnit)
     throws InterruptedException {
   for (int i = 0; i < 2; i++) {
     if (watchedObjects.isEmpty())
       throw new IllegalArgumentException("register some objects to wait its states");
     for (Map.Entry<Object, List<State>> en : watchedObjects.entrySet()) {
       for (State state : en.getValue()) {
         if (state.checkState(en.getKey())) return new StateHolder(state, en.getKey());
       }
     }
     if (i == 0)
       if (timeout == 0) this.wait();
       else this.wait(TimeUnit.MILLISECONDS.convert(timeout, timeUnit));
   }
   return null;
 }
  @Override
  public <T> void register(State<T> state, T object) {
    List<State> states = watchedObjects.get(object);
    if (states == null) states = new ArrayList<State>();
    states.add(state);

    watchedObjects.put(object, states);

    List<EventHandler> handlers = eventHandlers.get(object);
    if (handlers == null) handlers = new ArrayList<EventHandler>();

    EventProcessor processor = this.processor;
    EventFilter filter = state.getTrigger();
    if (registerListenerOnObject && object instanceof EventProcessor)
      processor = (EventProcessor) object;
    else filter = new ProducerEventFilter(object).andFilterBy(filter);
    processor.addListener(new SelectorListener(), filter);
  }