CPD Results

The following document contains the results of PMD's CPD 4.2.5.

Duplications

FileLine
cz/cuni/amis/pogamut/base/component/bus/ComponentBus.java275
cz/cuni/amis/pogamut/base/component/lifecyclebus/LifecycleBus.java302
		if (log.isLoggable(Level.INFO)) log.info(component + " registered under id " + component.getComponentId().getToken());
	}
	
	@Override
	public IComponent getComponent(IToken name) {
		return componentsByToken.get(name);
	}
	
	//
	//
	// EVENTS LISTENER
	// 
	//
	
	@Override
	public void addEventListener(Class<?> event, IComponentEventListener<?> listener) {
		NullCheck.check(event, "event");
		NullCheck.check(listener, "listener");
		eventListeners.get(event).add(listener);
	}
	
	@Override
	public void addEventListener(Class<?> event, Class<?> component, IComponentEventListener<?> listener) {
		NullCheck.check(event, "event");
		NullCheck.check(component, "comopnent");
		NullCheck.check(listener, "listener");
		componentEventListeners.get(component).get(event).add(listener);
	}

	@Override
	public void addEventListener(Class<?> event, IToken componentName, IComponentEventListener<?> listener) {
		NullCheck.check(event, "event");
		NullCheck.check(componentName, "componentName");
		NullCheck.check(listener, "listener");
		componentNameEventListeners.get(componentName).get(event).add(listener);
	}
	
	@Override
	public void addEventListener(Class<?> event, IComponent component, IComponentEventListener<?> listener) {
		NullCheck.check(component, "component");
		addEventListener(event, component.getComponentId(), listener);
	}
	
	@Override
	public boolean isListening(Class<?> event, IComponentEventListener<?> listener) {
		NullCheck.check(event, "event");
		NullCheck.check(listener, "listener");
		if (!eventListeners.containsKey(event)) return false;
		return eventListeners.get(event).contains(listener);
	}
	
	@Override
	public boolean isListening(Class<?> event, Class<?> component, IComponentEventListener<?> listener) {
		NullCheck.check(event, "event");
		NullCheck.check(component, "component");
		NullCheck.check(listener, "listener");
		if (!componentEventListeners.containsKey(component)) return false;
		Map<Class, Set<IComponentEventListener>> listeners = componentEventListeners.get(component);
		if (!listeners.containsKey(event)) return false;
		return listeners.get(event).contains(listener);
	}

	@Override
	public boolean isListening(Class<?> event, IToken componentId, IComponentEventListener<?> listener) {
		NullCheck.check(event, "event");
		NullCheck.check(componentId, "componentId");
		NullCheck.check(listener, "listener");
		if (!componentNameEventListeners.containsKey(componentId)) return false;
		Map<Class, Set<IComponentEventListener>> listeners = componentNameEventListeners.get(componentId);
		if (!listeners.containsKey(event)) return false;
		return listeners.get(event).contains(listener);
	}
	
	@Override
	public boolean isListening(Class<?> event, IComponent component, IComponentEventListener<?> listener) {
		NullCheck.check(component, "component");
		return isListening(event, component.getComponentId(), listener);
	}

	@Override
	public void removeEventListener(Class<?> event, IComponentEventListener<?> listener) {
		NullCheck.check(event, "event");
		NullCheck.check(listener, "listener");
		if (!eventListeners.containsKey(event)) return;
		eventListeners.get(event).remove(listener);
	}

	@Override
	public void removeEventListener(Class<?> event, Class<?> component,	IComponentEventListener<?> listener) {
		NullCheck.check(event, "event");
		NullCheck.check(component, "component");
		NullCheck.check(listener, "listener");
		if (!componentEventListeners.containsKey(component)) return;
		Map<Class, Set<IComponentEventListener>> listeners = componentEventListeners.get(component);
		if (!listeners.containsKey(event)) return;
		listeners.get(event).remove(listener);
	}

	@Override
	public void removeEventListener(Class<?> event, IToken componentId, IComponentEventListener<?> listener) {
		NullCheck.check(event, "event");
		NullCheck.check(componentId, "componentId");
		NullCheck.check(listener, "listener");
		if (!componentNameEventListeners.containsKey(componentId)) return;
		Map<Class, Set<IComponentEventListener>> listeners = componentNameEventListeners.get(componentId);
		if (!listeners.containsKey(event)) return;
		listeners.get(event).remove(listener);
	}
	
	@Override
	public void removeEventListener(Class<?> event, IComponent component, IComponentEventListener<?> listener) {
		NullCheck.check(component, "component");
		removeEventListener(event, component.getComponentId(), listener);
	}
	
	//
	//
	// EVENT PROCESSING
	//
	//
		
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * <p><p>
	 * Notifies only if isRunning().
	 * 
	 * @param event
	 */
	private void notifyListenersA(IComponentEvent event) {
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		for (Class eventClass : eventClasses) {
			if (!eventListeners.containsKey(eventClass)) continue;
			for (IComponentEventListener listener : eventListeners.get(eventClass)) {
				if (!isRunning()) return;
				listener.notify(event);
			}
		}
	}

	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * <p><p>
	 * Notifies only if isRunning().
	 * 
	 * @param event
	 */
	private void notifyListenersB(IComponentEvent event) {
		Collection<Class> componentClasses = ClassUtils.getSubclasses(event.getSource().getClass());
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		for (Class componentClass : componentClasses) {
			if (!componentEventListeners.containsKey(componentClass)) continue;
			Map<Class, Set<IComponentEventListener>> listeners = componentEventListeners.get(componentClass);
			for (Class eventClass : eventClasses) {
				if (!listeners.containsKey(eventClass)) continue;
				for (IComponentEventListener listener : listeners.get(eventClass)) {
					if (!isRunning()) return;
					listener.notify(event);
				}
			}
		}
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * <p><p>
	 * Notifies only if isRunning().
	 * 
	 * @param event
	 */
	private void notifyListenersC(IComponentEvent event) {
		if (!componentNameEventListeners.containsKey(event.getSource().getComponentId())) return;
		Map<Class, Set<IComponentEventListener>> listeners = componentNameEventListeners.get(event.getSource().getComponentId());
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		for (Class eventClass : eventClasses) {
			if (!listeners.containsKey(eventClass)) continue;
			for (IComponentEventListener listener : listeners.get(eventClass)) {
				if (!isRunning()) return;
				listener.notify(event);
			}
		}
	}

	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * <p><p>
	 * Notification is done safe-way ... every listener is notified even if an exception happens in one of them.
	 * <p><p>
	 * Notifies also if is not running (used for propagation of {@link IFatalErrorEvent}.
	 * 
	 * @param event
	 */
	private void notifyListenersA_Safe(IComponentEvent event) {
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		for (Class eventClass : eventClasses) {
			if (!eventListeners.containsKey(eventClass)) continue;
			for (IComponentEventListener listener : eventListeners.get(eventClass)) {
				try {
					listener.notify(event);
				} catch (Exception e) {
					if (log.isLoggable(Level.WARNING)) log.warning(ExceptionToString.process("Exception happened during notification of event " + event + " on listener " + listener + ".", e));
				}
			}
		}
	}

	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * <p><p>
	 * Notification is done safe-way ... every listener is notified even if an exception happens in one of them.
	 * <p><p>
	 * Notifies also if is not running (used for propagation of {@link IFatalErrorEvent}.
	 * 
	 * @param event
	 */
	private void notifyListenersB_Safe(IComponentEvent event) {
		Collection<Class> componentClasses = ClassUtils.getSubclasses(event.getSource().getClass());
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		for (Class componentClass : componentClasses) {
			if (!componentEventListeners.containsKey(componentClass)) continue;
			Map<Class, Set<IComponentEventListener>> listeners = componentEventListeners.get(componentClass);
			for (Class eventClass : eventClasses) {
				if (!listeners.containsKey(eventClass)) continue;
				for (IComponentEventListener listener : listeners.get(eventClass)) {
					try {
						listener.notify(event);
					} catch (Exception e) {
						if (log.isLoggable(Level.WARNING)) log.warning(ExceptionToString.process("Exception happened during notification of event " + event + " on listener " + listener + ".", e));
					}
				}
			}
		}
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * <p><p>
	 * Notification is done safe-way ... every listener is notified even if an exception happens in one of them.
	 * <p><p>
	 * Notifies also if is not running (used for propagation of {@link IFatalErrorEvent}.
	 * 
	 * @param event
	 */
	private void notifyListenersC_Safe(IComponentEvent event) {
		if (!componentNameEventListeners.containsKey(event.getSource().getComponentId())) return;
		Map<Class, Set<IComponentEventListener>> listeners = componentNameEventListeners.get(event.getSource().getComponentId());
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		for (Class eventClass : eventClasses) {
			if (!listeners.containsKey(eventClass)) continue;
			for (IComponentEventListener listener : listeners.get(eventClass)) {
				try {
					listener.notify(event);
				} catch (Exception e) {
					if (log.isLoggable(Level.WARNING)) log.warning(ExceptionToString.process("Exception happened during notification of event " + event + " on listener " + listener + ".", e));
				}
			}
		}
	}
	
	/**
	 * Process new IWorldEvent - DO NOT CALL SEPARATELY - must be called only from raiseEvent(),
	 * that forbids recursion of its calls.
	 * <p><p>
	 * Contains the sequence in which the listeners are informed about the event.
	 * @param event
	 */
	private void innerRaiseEvent(IComponentEvent event) {		
		if (event instanceof IFatalErrorEvent) {
			if (log.isLoggable(Level.SEVERE)) log.severe("Fatal error happenned - component bus is stopping." + Const.NEW_LINE + ((IFatalErrorEvent)event).getSummary());
			queue.clear();
			running = false;
			notifyListenersA_Safe(event);
			notifyListenersB_Safe(event);
			notifyListenersC_Safe(event);
			return;
		} else {
			if (log.isLoggable(Level.FINE)) log.fine("Notifying " + event);
		}
		if (!isRunning()) return;
		notifyListenersA(event);
		if (!isRunning()) return;
		notifyListenersB(event);
		if (!isRunning()) return;
		notifyListenersC(event);
	}
	
	/**
	 * Process new IWorldEvent - DO NOT CALL SEPARATELY - must be called only from raiseEvent(),
	 * that forbids recursion of its calls.
	 * <p><p>
	 * Contains the sequence in which the listeners are informed about the event.
	 * <p><p>
	 * Notification is done safe-way ... every listener is notified even if an exception happens in one of them.
	 * 
	 * @param event
	 */
	private void innerRaiseEvent_Safe(IComponentEvent event) {
		if (event instanceof IFatalErrorEvent) {
			if (log.isLoggable(Level.SEVERE)) log.severe("Fatal error happenned - component bus is stopping." + Const.NEW_LINE + ((IFatalErrorEvent)event).getSummary());
			queue.clear();
			running = false;
		} else {
			if (log.isLoggable(Level.FINE)) log.fine("Notifying (safe) " + event);
		}
		notifyListenersA_Safe(event);
		notifyListenersB_Safe(event);
		notifyListenersC_Safe(event);
	}
	
	@Override
	public synchronized boolean event(IComponentEvent event) throws ComponentBusNotRunningException, ComponentBusErrorException, FatalErrorPropagatingEventException {
		// method is synchronized - only one thread inside at given time
		
		NullCheck.check(event, "event");
		if (event instanceof IResetEvent) throw new IllegalArgumentException("you can't broadcast reset event this way, use reset() instead");
			
		if (!isRunning()) {			
FileLine
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractLocalWorldView.java753
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractSharedWorldView.java576
	}
	
	/////////////
	//LISTENERS//
	////////////
	
	@Override
	public void addEventListener(Class<?> event, IWorldEventListener<?> listener) {
		eventListeners.add(event, listener);
	}
	
	@Override
	public void addObjectListener(Class<?> objectClass, IWorldObjectEventListener<?, ?> listener) {
		objectsListeners.add(objectClass, listener);
	}

	@Override
	public void addObjectListener(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?,?> listener) {
		ListenersMap<Class> listeners = objectEventListeners.get(eventClass);
		listeners.add(objectClass, listener);
	}
	
	@Override
	public void addObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener) {
		specificObjectListeners.add(objectId, listener);
	}
	
	@Override
	public void addObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
		ListenersMap<Class> listeners = specificObjectEventListeners.get(objectId);
		listeners.add(eventClass, listener);
	}
	
	@Override
	public boolean isListening(Class<?> eventClass, IWorldEventListener<?> listener) {
		return eventListeners.isListening(eventClass, listener);
	}
	
	@Override
	public boolean isListening(Class<?> objectClass, IWorldObjectEventListener<?, ?> listener) {
		return objectsListeners.isListening(listener);
	}


	@Override
	public boolean isListening(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
		if (objectEventListeners.containsKey(objectClass)) { // be careful not to create unnecessary ListenersMap
			return objectEventListeners.get(eventClass).isListening(objectClass, listener);
		} else {
			return false;
		}
	}

	@Override
	public boolean isListening(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener) {
		return specificObjectListeners.isListening(objectId, listener);
	}

	@Override
	public boolean isListening(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
		if (specificObjectEventListeners.containsKey(objectId)) { // be careful not to create unnecessary ListenersMap
			return specificObjectEventListeners.get(objectId).isListening(eventClass, listener);
		} else {
			return false;
		}
		
	}
	
	@Override
	public boolean isListening(IWorldEventListener<?> listener) {
		if (eventListeners.isListening(listener) ||
			specificObjectListeners.isListening(listener)) {
			return true;
		}
		synchronized(objectEventListeners) {
			for (ListenersMap<Class> listeners : objectEventListeners.values()) {
				if (listeners.isListening(listener)) return true;
			}
		}
		synchronized(specificObjectEventListeners) {
			for (ListenersMap<Class> listeners : specificObjectEventListeners.values()) {
				if (listeners.isListening(listener)) return true;
			}
		}
		return false;
	}

	@Override
	public void removeEventListener(Class<?> eventClass, IWorldEventListener<?> listener) {
		eventListeners.remove(eventClass, listener);
	}

	@Override
	public void removeObjectListener(Class<?> objectClass,	IWorldObjectEventListener<?, ?> listener) {
		objectsListeners.remove(objectClass, listener);
	}
	
	@Override
	public void removeObjectListener(Class<?> objectClass, Class<?> eventClass,	IWorldObjectEventListener<?, ?> listener) {
		if (objectEventListeners.containsKey(eventClass)) { // be careful not to create unnecessary ListenersMap
			objectEventListeners.get(eventClass).remove(objectClass, listener);
		}
	}

	@Override
	public void removeObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener) {
		specificObjectListeners.remove(objectId, listener);
	}

	@Override
	public void removeObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
		if (specificObjectEventListeners.containsKey(objectId)) { // be careful not to create unnecessary ListenersMap
			specificObjectEventListeners.get(objectId).remove(eventClass, listener);
		}
	}
	
		
	@Override
	public void removeListener(IWorldEventListener<?> listener) {
		eventListeners.remove(listener);
		synchronized(objectEventListeners) {
			for (ListenersMap<Class> listeners : objectEventListeners.values()) {
				listeners.remove(listener);
			}
		}
		specificObjectListeners.remove(listener);
		specificObjectEventListeners.remove(listener);
	}

	// EVENT PROCESSING
	
	
	/**
	 * Process new IWorldEvent - notify all the listeners about it. Forbids recursion.
	 * <p><p>
	 * Use in the descendants to process new IWorldChangeEvent.
	 * <p><p>
	 * Does not catch any exceptions!
	 * <p><p>
	 * Synchronized!
	 * 
	 * @param event
	 */
	protected synchronized void raiseEvent(IWorldEvent event) {
		// method is synchronized - only one thread inside at given time
		
		// is this method recursively called? 
		if (raiseEventProcessing) {
			// yes it is -> that means the previous event has not been
			// processed! ... store this event and allows the previous one
			// to be fully processed (e.g. postpone raising this event)
			raiseEventsList.add(event);
			return;
		} else {
			// no it is not ... so raise the flag that we're inside the method
			raiseEventProcessing = true;
		}
		// process event
				
		innerRaiseEvent(event);
		
		// check the events list size, do we have more events to process?
		while(raiseEventsList.size() != 0) {
			// yes we do -> do it!
			innerRaiseEvent(raiseEventsList.poll());			
		}
		// all events has been processed, drop the flag that we're inside the method
		raiseEventProcessing = false;			
	}
		
	//
	//
	// EVENT PROCESSING
	//
	//
		
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelAListeners(IWorldEvent event) {
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		notifier.setEvent(event);
		for (Class eventClass : eventClasses) {
			eventListeners.notify(eventClass, notifier);
		}
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelBListeners(IWorldObjectEvent event) {
		IWorldObject object = event.getObject();
		Collection<Class> objectClasses = ClassUtils.getSubclasses(object.getClass());
		notifier.setEvent(event);
		for (Class objectClass : objectClasses) {
			objectsListeners.notify(objectClass, notifier);
		}
	}

	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelCListeners(IWorldObjectEvent event) {
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		Collection<Class> objectClasses = ClassUtils.getSubclasses(event.getObject().getClass());
		notifier.setEvent(event);
		for (Class eventClass : eventClasses) {
			ListenersMap<Class> listeners = objectEventListeners.get(eventClass);
			if (listeners == null) continue;
			if (!listeners.hasListeners()) continue;
			for (Class objectClass : objectClasses) {
				listeners.notify(objectClass, notifier);			
			}
		}
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelDListeners(IWorldObjectEvent event) {
		notifier.setEvent(event);
		specificObjectListeners.notify(event.getId(), notifier);
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelEListeners(IWorldObjectEvent event) {
		notifier.setEvent(event);
		WorldObjectId objectId = event.getId();
		ListenersMap<Class> listeners = specificObjectEventListeners.get(objectId);
		if (listeners.hasListeners()) {
			Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
			notifier.setEvent(event);
			for (Class eventClass : eventClasses) {
				listeners.notify(eventClass, notifier);			
			}
		}
	}
	
	/**
	 * Process new IWorldEvent - DO NOT CALL SEPARATELY - must be called only from raiseEvent(),
	 * that forbids recursion of its calls.
	 * <p><p>
	 * Contains the sequence in which the listeners are informed about the event.
	 * @param event
	 */
	private void innerRaiseEvent(IWorldEvent event) {
		if (log.isLoggable(Level.FINEST)) log.finest("notifying " + event);
		notifyLevelAListeners(event);		
		if (event instanceof IWorldObjectEvent) {
			// now we may notify other listeners as well
			IWorldObjectEvent objectEvent = (IWorldObjectEvent)event;
			notifyLevelBListeners(objectEvent);
			notifyLevelCListeners(objectEvent);
			notifyLevelDListeners(objectEvent);
			notifyLevelEListeners(objectEvent);
		}
	}
FileLine
cz/cuni/amis/pogamut/base/communication/worldview/impl/AbstractWorldView.java391
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractLocalWorldView.java753
	}

	
	/////////////
	//LISTENERS//
	////////////
	
	@Override
	public void addEventListener(Class<?> event, IWorldEventListener<?> listener) {
		eventListeners.add(event, listener);
	}
	
	@Override
	public void addObjectListener(Class<?> objectClass, IWorldObjectEventListener<?, ?> listener) {
		objectsListeners.add(objectClass, listener);
	}

	@Override
	public void addObjectListener(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?,?> listener) {
		ListenersMap<Class> listeners = objectEventListeners.get(eventClass);
		listeners.add(objectClass, listener);
	}
	
	@Override
	public void addObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener) {
		specificObjectListeners.add(objectId, listener);
	}
	
	@Override
	public void addObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
		ListenersMap<Class> listeners = specificObjectEventListeners.get(objectId);
		listeners.add(eventClass, listener);
	}
	
	@Override
	public boolean isListening(Class<?> eventClass, IWorldEventListener<?> listener) {
		return eventListeners.isListening(eventClass, listener);
	}
	
	@Override
	public boolean isListening(Class<?> objectClass, IWorldObjectEventListener<?, ?> listener) {
		return objectsListeners.isListening(listener);
	}


	@Override
	public boolean isListening(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
		if (objectEventListeners.containsKey(objectClass)) { // be careful not to create unnecessary ListenersMap
			return objectEventListeners.get(eventClass).isListening(objectClass, listener);
		} else {
			return false;
		}
	}

	@Override
	public boolean isListening(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener) {
		return specificObjectListeners.isListening(objectId, listener);
	}

	@Override
	public boolean isListening(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
		if (specificObjectEventListeners.containsKey(objectId)) { // be careful not to create unnecessary ListenersMap
			return specificObjectEventListeners.get(objectId).isListening(eventClass, listener);
		} else {
			return false;
		}
		
	}
	
	@Override
	public boolean isListening(IWorldEventListener<?> listener) {
		if (eventListeners.isListening(listener) ||
			specificObjectListeners.isListening(listener)) {
			return true;
		}
		synchronized(objectEventListeners) {
			for (ListenersMap<Class> listeners : objectEventListeners.values()) {
				if (listeners.isListening(listener)) return true;
			}
		}
		synchronized(specificObjectEventListeners) {
			for (ListenersMap<Class> listeners : specificObjectEventListeners.values()) {
				if (listeners.isListening(listener)) return true;
			}
		}
		return false;
	}

	@Override
	public void removeEventListener(Class<?> eventClass, IWorldEventListener<?> listener) {
		eventListeners.remove(eventClass, listener);
	}

	@Override
	public void removeObjectListener(Class<?> objectClass,	IWorldObjectEventListener<?, ?> listener) {
		objectsListeners.remove(objectClass, listener);
	}
	
	@Override
	public void removeObjectListener(Class<?> objectClass, Class<?> eventClass,	IWorldObjectEventListener<?, ?> listener) {
		if (objectEventListeners.containsKey(eventClass)) { // be careful not to create unnecessary ListenersMap
			objectEventListeners.get(eventClass).remove(objectClass, listener);
		}
	}

	@Override
	public void removeObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener) {
		specificObjectListeners.remove(objectId, listener);
	}

	@Override
	public void removeObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener) {
		if (specificObjectEventListeners.containsKey(objectId)) { // be careful not to create unnecessary ListenersMap
			specificObjectEventListeners.get(objectId).remove(eventClass, listener);
		}
	}
	
		
	@Override
	public void removeListener(IWorldEventListener<?> listener) {
		eventListeners.remove(listener);
		synchronized(objectEventListeners) {
			for (ListenersMap<Class> listeners : objectEventListeners.values()) {
				listeners.remove(listener);
			}
		}
		specificObjectListeners.remove(listener);
		specificObjectEventListeners.remove(listener);
	}
FileLine
cz/cuni/amis/pogamut/base/communication/worldview/impl/AbstractWorldView.java608
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractLocalWorldView.java881
	}

	// EVENT PROCESSING
	
	
	/**
	 * Process new IWorldEvent - notify all the listeners about it. Forbids recursion.
	 * <p><p>
	 * Use in the descendants to process new IWorldChangeEvent.
	 * <p><p>
	 * Does not catch any exceptions!
	 * <p><p>
	 * Synchronized!
	 * 
	 * @param event
	 */
	protected synchronized void raiseEvent(IWorldEvent event) {
		// method is synchronized - only one thread inside at given time
		
		// is this method recursively called? 
		if (raiseEventProcessing) {
			// yes it is -> that means the previous event has not been
			// processed! ... store this event and allows the previous one
			// to be fully processed (e.g. postpone raising this event)
			raiseEventsList.add(event);
			return;
		} else {
			// no it is not ... so raise the flag that we're inside the method
			raiseEventProcessing = true;
		}
		// process event
				
		innerRaiseEvent(event);
		
		// check the events list size, do we have more events to process?
		while(raiseEventsList.size() != 0) {
			// yes we do -> do it!
			innerRaiseEvent(raiseEventsList.poll());			
		}
		// all events has been processed, drop the flag that we're inside the method
		raiseEventProcessing = false;			
	}
		
	//
	//
	// EVENT PROCESSING
	//
	//
		
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelAListeners(IWorldEvent event) {
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		notifier.setEvent(event);
		for (Class eventClass : eventClasses) {
			eventListeners.notify(eventClass, notifier);
		}
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelBListeners(IWorldObjectEvent event) {
		IWorldObject object = event.getObject();
		Collection<Class> objectClasses = ClassUtils.getSubclasses(object.getClass());
		notifier.setEvent(event);
		for (Class objectClass : objectClasses) {
			objectsListeners.notify(objectClass, notifier);
		}
	}

	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelCListeners(IWorldObjectEvent event) {
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		Collection<Class> objectClasses = ClassUtils.getSubclasses(event.getObject().getClass());
		notifier.setEvent(event);
		for (Class eventClass : eventClasses) {
			ListenersMap<Class> listeners = objectEventListeners.get(eventClass);
			if (listeners == null) continue;
			if (!listeners.hasListeners()) continue;
			for (Class objectClass : objectClasses) {
				listeners.notify(objectClass, notifier);			
			}
		}
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelDListeners(IWorldObjectEvent event) {
		notifier.setEvent(event);
		specificObjectListeners.notify(event.getId(), notifier);
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelEListeners(IWorldObjectEvent event) {
		notifier.setEvent(event);
		WorldObjectId objectId = event.getId();
		ListenersMap<Class> listeners = specificObjectEventListeners.get(objectId);
		if (listeners.hasListeners()) {
			Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
			notifier.setEvent(event);
			for (Class eventClass : eventClasses) {
				listeners.notify(eventClass, notifier);			
			}
		}
	}
	
	/**
	 * Process new IWorldEvent - DO NOT CALL SEPARATELY - must be called only from raiseEvent(),
	 * that forbids recursion of its calls.
	 * <p><p>
	 * Contains the sequence in which the listeners are informed about the event.
	 * @param event
	 */
	private void innerRaiseEvent(IWorldEvent event) {
		if (log.isLoggable(Level.FINEST)) log.finest("notifying " + event);
		notifyLevelAListeners(event);		
		if (event instanceof IWorldObjectEvent) {
			// now we may notify other listeners as well
			IWorldObjectEvent objectEvent = (IWorldObjectEvent)event;
			notifyLevelBListeners(objectEvent);
			notifyLevelCListeners(objectEvent);
			notifyLevelDListeners(objectEvent);
			notifyLevelEListeners(objectEvent);
		}
	}

	@Override
	public ILifecycleBus getEventBus() {
FileLine
cz/cuni/amis/pogamut/base/communication/worldview/impl/AbstractWorldView.java608
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractSharedWorldView.java703
	}

	// EVENT PROCESSING
	
	
	/**
	 * Process new IWorldEvent - notify all the listeners about it. Forbids recursion.
	 * <p><p>
	 * Use in the descendants to process new IWorldChangeEvent.
	 * <p><p>
	 * Does not catch any exceptions!
	 * <p><p>
	 * Synchronized!
	 * 
	 * @param event
	 */
	protected synchronized void raiseEvent(IWorldEvent event) {
		// method is synchronized - only one thread inside at given time
		
		// is this method recursively called? 
		if (raiseEventProcessing) {
			// yes it is -> that means the previous event has not been
			// processed! ... store this event and allows the previous one
			// to be fully processed (e.g. postpone raising this event)
			raiseEventsList.add(event);
			return;
		} else {
			// no it is not ... so raise the flag that we're inside the method
			raiseEventProcessing = true;
		}
		// process event
				
		innerRaiseEvent(event);
		
		// check the events list size, do we have more events to process?
		while(raiseEventsList.size() != 0) {
			// yes we do -> do it!
			innerRaiseEvent(raiseEventsList.poll());			
		}
		// all events has been processed, drop the flag that we're inside the method
		raiseEventProcessing = false;			
	}
		
	//
	//
	// EVENT PROCESSING
	//
	//
		
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelAListeners(IWorldEvent event) {
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		notifier.setEvent(event);
		for (Class eventClass : eventClasses) {
			eventListeners.notify(eventClass, notifier);
		}
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelBListeners(IWorldObjectEvent event) {
		IWorldObject object = event.getObject();
		Collection<Class> objectClasses = ClassUtils.getSubclasses(object.getClass());
		notifier.setEvent(event);
		for (Class objectClass : objectClasses) {
			objectsListeners.notify(objectClass, notifier);
		}
	}

	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelCListeners(IWorldObjectEvent event) {
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		Collection<Class> objectClasses = ClassUtils.getSubclasses(event.getObject().getClass());
		notifier.setEvent(event);
		for (Class eventClass : eventClasses) {
			ListenersMap<Class> listeners = objectEventListeners.get(eventClass);
			if (listeners == null) continue;
			if (!listeners.hasListeners()) continue;
			for (Class objectClass : objectClasses) {
				listeners.notify(objectClass, notifier);			
			}
		}
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelDListeners(IWorldObjectEvent event) {
		notifier.setEvent(event);
		specificObjectListeners.notify(event.getId(), notifier);
	}
	
	/**
	 * Helper method used ONLY FROM innerRaiseEvent. DO NOT USE OUTSIDE THAT METHOD!
	 * @param event
	 */
	private void notifyLevelEListeners(IWorldObjectEvent event) {
		notifier.setEvent(event);
		WorldObjectId objectId = event.getId();
		ListenersMap<Class> listeners = specificObjectEventListeners.get(objectId);
		if (listeners.hasListeners()) {
			Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
			notifier.setEvent(event);
			for (Class eventClass : eventClasses) {
				listeners.notify(eventClass, notifier);			
			}
		}
	}
	
	/**
	 * Process new IWorldEvent - DO NOT CALL SEPARATELY - must be called only from raiseEvent(),
	 * that forbids recursion of its calls.
	 * <p><p>
	 * Contains the sequence in which the listeners are informed about the event.
	 * @param event
	 */
	private void innerRaiseEvent(IWorldEvent event) {
		if (log.isLoggable(Level.FINEST)) log.finest("notifying " + event);
		notifyLevelAListeners(event);		
		if (event instanceof IWorldObjectEvent) {
			// now we may notify other listeners as well
			IWorldObjectEvent objectEvent = (IWorldObjectEvent)event;
			notifyLevelBListeners(objectEvent);
			notifyLevelCListeners(objectEvent);
			notifyLevelDListeners(objectEvent);
			notifyLevelEListeners(objectEvent);
		}
	}
FileLine
cz/cuni/amis/pogamut/base/component/bus/ComponentBus.java58
cz/cuni/amis/pogamut/base/component/lifecyclebus/LifecycleBus.java91
	public static final IToken COMPONENT_ID = Tokens.get("LifecycleBus");
	
	private Map<IToken, IComponent> componentsByToken = new ConcurrentHashMap<IToken, IComponent>();

	private Map<Class, Set<IComponent>> componentsByClass = new LazyMap<Class, Set<IComponent>>(new ConcurrentHashMap<Class, Set<IComponent>>()) {

		@Override
		protected Set<IComponent> create(Class key) {
			return new ConcurrentHashSet<IComponent>();
		}
		
	};

	private Map<Class, Set<IComponentEventListener>> eventListeners = new LazyMap<Class, Set<IComponentEventListener>>(new ConcurrentHashMap<Class, Set<IComponentEventListener>>()) {

		@Override
		protected Set<IComponentEventListener> create(Class key) {
			return new ConcurrentLinkedHashSet<IComponentEventListener>();
		}
				
	};
	
	private Map<Class, Map<Class, Set<IComponentEventListener>>> componentEventListeners = new LazyMap<Class, Map<Class, Set<IComponentEventListener>>>(new ConcurrentHashMap<Class, Map<Class, Set<IComponentEventListener>>>()) {

		@Override
		protected Map<Class, Set<IComponentEventListener>> create(Class key) {
			return new LazyMap<Class, Set<IComponentEventListener>>(new ConcurrentHashMap<Class, Set<IComponentEventListener>>()) {

				@Override
				protected Set<IComponentEventListener> create(Class key) {
					return new ConcurrentLinkedHashSet<IComponentEventListener>();
				}
				
			};
		}
		
	};
	
	private Map<IToken, Map<Class, Set<IComponentEventListener>>> componentNameEventListeners = new LazyMap<IToken, Map<Class, Set<IComponentEventListener>>>() {

		@Override
		protected Map<Class, Set<IComponentEventListener>> create(IToken key) {
			return new LazyMap<Class, Set<IComponentEventListener>>(new ConcurrentHashMap<Class, Set<IComponentEventListener>>()) {

				@Override
				protected Set<IComponentEventListener> create(Class key) {
					return new ConcurrentLinkedHashSet<IComponentEventListener>();
				}
				
			};
		}
		
	};
	
	/**
	 * Whether the bus is running. Dropped after IFatalError event.
	 */
	private boolean running = true;
		
	/**
	 * List of events we have to process.
	 * <p><p>
	 * It is managed only by raiseEvent() method - DO NOT MODIFY OUTSIDE IT!
	 */
	private Queue<IComponentEvent> queue = new ConcurrentLinkedQueue();

	/**
	 * Flag that is telling us whether there is an event being processed or not.
	 * <p><p>
	 * It is managed only by raiseEvent() method - DO NOT MODIFY IT FROM OUTSIDE THAT METHOD!
	 */
	private boolean queueProcessing = false;
	
	/**
	 * Used by processQueue() for the sync.
	 */
	private Object queueProcessingMutex = new Object();
FileLine
cz/cuni/amis/pogamut/base/component/bus/ComponentBus.java218
cz/cuni/amis/pogamut/base/component/lifecyclebus/LifecycleBus.java244
		if (components.size() > 0) throw new MoreComponentsForClassException(cls, components, this);
		return components.iterator().next();
	}

	@Override
	public <T> Set<T> getComponents(Class<T> cls) {
		return (Set<T>) Collections.unmodifiableSet(componentsByClass.get(cls));
	}
	
	@Override
	public void register(IComponent component) throws ComponentIdClashException {
		synchronized(componentsByToken) {
			NullCheck.check(component.getComponentId(), "component's id is null ("+ component + ")");
			if (componentsByToken.get(component.getComponentId()) != null) {
				if (componentsByToken.get(component.getComponentId()) == component) {
					return;
				} else {
					ComponentIdClashException e = new ComponentIdClashException(component.getComponentId(), log, this);
					try {
						event(new FatalErrorEvent(this, e));
					} catch (Exception e1) {
					}
					throw e;
				}
			}			
			registerComponent(component);
		}
	}
	
	@Override
	public void remove(IComponent component) {
		synchronized(componentsByToken) {
			componentsByToken.remove(component.getComponentId());
			Collection<Class> componentClasses = ClassUtils.getSubclasses(component.getClass());
			for (Class cls : componentClasses) {
				componentsByClass.get(cls).remove(component);
			}
			if (log.isLoggable(Level.INFO)) log.info(component + " of the id " + component.getComponentId().getToken() + " removed from the bus.");
		}
	}
	
	/**
	 * Called whenever new component is being registered.
	 * <p><p>
	 * Method assumes it is "synchronized" by caller.
	 * <p><p>
	 * This method also assumes there is no component-id clash with existing components! Checks
	 * has been done already inside register() method.
	 * 
	 * @param component
	 */
	private void registerComponent(IComponent component) {
		componentsByToken.put(component.getComponentId(), component);
		Collection<Class> componentClasses = ClassUtils.getSubclasses(component.getClass());
		for (Class cls : componentClasses) {
			componentsByClass.get(cls).add(component);
		}
FileLine
cz/cuni/amis/pogamut/base/communication/worldview/IWorldView.java89
cz/cuni/amis/pogamut/multi/communication/worldview/ILocalWorldView.java142
	TimeKey getCurrentTimeKey();
	
	//=========//
	//LISTENERS//
	//=========//
	
	/**
	 * Adds listener to a specific event (Level A listeners). Note that the event listener must be able
	 * to handle events of the class 'event'.
	 * <p><p>
	 * It is the most general type of listener-registration allowing you to sniff any type of events.
	 * <p><p>
	 * Events passed to the listener are filtered only according to the 'event' class.
	 * <p><p>
	 * <b>WARNING:</b> even though the method does not require templated class and listener, you must be sure
	 * that 'listener' can accept 'eventClass'.
	 *
	 * @param eventClass which event types you want to receive
	 * @param listener where you want to handle these events
	 */
	public void addEventListener(Class<?> eventClass, IWorldEventListener<?> listener);
	
	/**
	 * Adds listener to all events that happens on any object of the 'objectClass' (Level B listeners).
	 * <p><p>
	 * Events passed to the listener are filtered according to the 'objectClass'.
	 * <p><p>
	 * <b>WARNING:</b> even though the method does not require templated classes and listener, you must be sure
	 * that 'listener' accepts all events (IWorldObjectEvent) for objects of 'objectClass'.
	 *
	 * @param objectClass which object class you want to listen at
	 * @param eventClass which event class you want to receive
	 * @param listener where you want to handle these events
	 */
	public void addObjectListener(Class<?> objectClass, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Adds listener to a specified 'event' that occurs on the specific 'objectClass' (Level C listeners).
	 * <p><p>
	 * Events passed to the listener are filtered according to the 'event' and 'objectClass' of the object the event happened upon.
	 * <p><p>
	 * <b>WARNING:</b> even though the method does not require templated classes and listener, you must be sure
	 * that 'listener' accepts 'eventClass' for objects of 'objectClass'.
	 *
	 * <p>
	 * eventClass can be any implementor of {@link IWorldObjectEvent}. E.g.
	 * {@link WorldObjectAppearedEvent}, {@link WorldObjectDestroyedEvent}, {@link WorldObjectDisappearedEvent},
	 * {@link WorldObjectFirstEncounteredEvent} or {@link WorldObjectUpdatedEvent}.
	 * </p>
	 *
	 * @param objectClass which object class you want to listen at
	 * @param eventClass which event class you want to receive
	 * @param listener where you want to handle these events
	 */
	public void addObjectListener(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?,?> listener);

	/**
	 * Adds listener to all events that happens on object with specific 'objectId' (Level D listeners).
	 * <p><p>
	 * Events passed to the listener are filtered according to the 'objectId' of the object.
	 * <p><p>
	 * <b>WARNING:</b> you must ensure that 'listener' can accept the event raised on object of specified 'objectId'.
	 *
	 * @param objectId which object you want to listen at
	 * @param listener where you want to handle events
	 */
	public void addObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Adds listener to a specified 'event' that occurs on the specific object with 'objectId' (Level E listeners).
	 * <p><p>
	 * Events passed to the listener are filtered according to the 'event' and 'objectId' of the object.
	 * <p><p>
	 * <b>WARNING:</b> even though the method does not require templated classes and listener, you must be sure
	 * that 'listener' accepts 'eventClass' for objects of specified 'objectId'.
	 *
	 * @param objectId which object you want to listen at
	 * @param eventClass which event classes you want to receive
	 * @param listener where you want to handle these events
	 */
	public void addObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Removes listener from a specific event (Level A listeners).
	 *
	 * @param eventClass which events class you want to remove the listener from
	 * @param listener you want to remove
	 */
	public void removeEventListener(Class<?> eventClass, IWorldEventListener<?> listener);

	/**
	 * Removes listener from specific 'objectClass' listening for specified 'event' (Level B listeners).
	 *
	 * @param objectClass class of objects you want the listener to remove from
	 * @param eventClass which events class you want to remove the listener from
	 * @param listener you want to remove
	 */
	public void removeObjectListener(Class<?> objectClass, IWorldObjectEventListener<?,?> listener);
	
	/**
	 * Removes listener from specific 'objectClass' listening for specified 'event' (Level C listeners).
	 *
	 * @param objectClass class of objects you want the listener to remove from
	 * @param eventClass which events class you want to remove the listener from
	 * @param listener you want to remove
	 */
	public void removeObjectListener(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?,?> listener);


	/**
	 * Removes listener from objects with specified 'objectId' (Level D Listeners).
	 *
	 * @param objectId id of object you want the listener to remove from
	 * @param listener you want to remove
	 */
	public void removeObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Removes listener to a specified 'event' that occurs on the specific object with 'objectId' (Level E listeners).
	 *
	 * @param objectId id of object you want the listener to remove from
	 * @param eventClass event class you want to stop receiving in the listener
	 * @param listener you want to remove
	 */
	public void removeObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Removes listener from every listeners category (from every listener level).
	 * <p><p>
	 * <b>WARNING:</b> Can be time consuming! (Iterating through all levels of listeners.)
	 *
	 * @param listener you want to remove from all listener levels
	 */
	public void removeListener(IWorldEventListener<?> listener);

	/**
	 * Tests whether the 'listener' is listening to a specific event (Level A listeners).
	 *
	 * @param eventClass which events you want to receive
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(Class<?> eventClass, IWorldEventListener<?> listener);

	/**
	 * Tests whether the 'listener' is listening at specified 'objectClass' (Level B listeners).
	 *
	 * @param objectClass where the listener is tested
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(Class<?> objectClass, IWorldObjectEventListener<?,?> listener);	
	
	/**
	 * Tests whether the 'listener' is listening at specified 'objectClass' for specified 'event' (Level C listeners).
	 *
	 * @param objectClass where the listener is tested
	 * @param eventClass where the listener is tested
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?,?> listener);


	/**
	 * Tests whether the 'listener' is listening at specified 'objectId' (Level D Listeners).
	 *
	 * @param objectId where the listener is tested
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Tests whether the 'listener' is listening to a specified 'event' that occurs on the specific object with 'objectId' (Level E listeners).
	 *
	 * @param objectId where the listener is tested
	 * @param eventClass what class is tested
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Checks whether this listener is hooked to the world view (at any listener level).
	 * <p><p>
	 * <b>WARNING:</b> Can be time consuming! (Iterating through all levels of listeners.)
	 *
	 * @param listener
	 * @return
	 */
	public boolean isListening(IWorldEventListener<?> listener);
FileLine
cz/cuni/amis/pogamut/base/communication/worldview/IWorldView.java89
cz/cuni/amis/pogamut/multi/communication/worldview/ISharedWorldView.java35
	public void registerLocalWorldView( ILocalWorldView localWV, ILifecycleBus bus);
	
	// ======
	// EVENTS
	// ======

	
	//TODO think about adding 1 listener level (specific agent)
	
	/**
	 * Adds listener to a specific event (Level A listeners). Note that the event listener must be able
	 * to handle events of the class 'event'.
	 * <p><p>
	 * It is the most general type of listener-registration allowing you to sniff any type of events.
	 * <p><p>
	 * Events passed to the listener are filtered only according to the 'event' class.
	 * <p><p>
	 * <b>WARNING:</b> even though the method does not require templated class and listener, you must be sure
	 * that 'listener' can accept 'eventClass'.
	 *
	 * @param eventClass which event types you want to receive
	 * @param listener where you want to handle these events
	 */
	public void addEventListener(Class<?> eventClass, IWorldEventListener<?> listener);
	
	/**
	 * Adds listener to all events that happens on any object of the 'objectClass' (Level B listeners).
	 * <p><p>
	 * Events passed to the listener are filtered according to the 'objectClass'.
	 * <p><p>
	 * <b>WARNING:</b> even though the method does not require templated classes and listener, you must be sure
	 * that 'listener' accepts all events (IWorldObjectEvent) for objects of 'objectClass'.
	 *
	 * @param objectClass which object class you want to listen at
	 * @param eventClass which event class you want to receive
	 * @param listener where you want to handle these events
	 */
	public void addObjectListener(Class<?> objectClass, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Adds listener to a specified 'event' that occurs on the specific 'objectClass' (Level C listeners).
	 * <p><p>
	 * Events passed to the listener are filtered according to the 'event' and 'objectClass' of the object the event happened upon.
	 * <p><p>
	 * <b>WARNING:</b> even though the method does not require templated classes and listener, you must be sure
	 * that 'listener' accepts 'eventClass' for objects of 'objectClass'.
	 *
	 * <p>
	 * eventClass can be any implementor of {@link IWorldObjectEvent}. E.g.
	 * {@link WorldObjectAppearedEvent}, {@link WorldObjectDestroyedEvent}, {@link WorldObjectDisappearedEvent},
	 * {@link WorldObjectFirstEncounteredEvent} or {@link WorldObjectUpdatedEvent}.
	 * </p>
	 *
	 * @param objectClass which object class you want to listen at
	 * @param eventClass which event class you want to receive
	 * @param listener where you want to handle these events
	 */
	public void addObjectListener(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?,?> listener);

	/**
	 * Adds listener to all events that happens on object with specific 'objectId' (Level D listeners).
	 * <p><p>
	 * Events passed to the listener are filtered according to the 'objectId' of the object.
	 * <p><p>
	 * <b>WARNING:</b> you must ensure that 'listener' can accept the event raised on object of specified 'objectId'.
	 *
	 * @param objectId which object you want to listen at
	 * @param listener where you want to handle events
	 */
	public void addObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Adds listener to a specified 'event' that occurs on the specific object with 'objectId' (Level E listeners).
	 * <p><p>
	 * Events passed to the listener are filtered according to the 'event' and 'objectId' of the object.
	 * <p><p>
	 * <b>WARNING:</b> even though the method does not require templated classes and listener, you must be sure
	 * that 'listener' accepts 'eventClass' for objects of specified 'objectId'.
	 *
	 * @param objectId which object you want to listen at
	 * @param eventClass which event classes you want to receive
	 * @param listener where you want to handle these events
	 */
	public void addObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Removes listener from a specific event (Level A listeners).
	 *
	 * @param eventClass which events class you want to remove the listener from
	 * @param listener you want to remove
	 */
	public void removeEventListener(Class<?> eventClass, IWorldEventListener<?> listener);

	/**
	 * Removes listener from specific 'objectClass' listening for specified 'event' (Level B listeners).
	 *
	 * @param objectClass class of objects you want the listener to remove from
	 * @param eventClass which events class you want to remove the listener from
	 * @param listener you want to remove
	 */
	public void removeObjectListener(Class<?> objectClass, IWorldObjectEventListener<?,?> listener);
	
	/**
	 * Removes listener from specific 'objectClass' listening for specified 'event' (Level C listeners).
	 *
	 * @param objectClass class of objects you want the listener to remove from
	 * @param eventClass which events class you want to remove the listener from
	 * @param listener you want to remove
	 */
	public void removeObjectListener(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?,?> listener);


	/**
	 * Removes listener from objects with specified 'objectId' (Level D Listeners).
	 *
	 * @param objectId id of object you want the listener to remove from
	 * @param listener you want to remove
	 */
	public void removeObjectListener(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Removes listener to a specified 'event' that occurs on the specific object with 'objectId' (Level E listeners).
	 *
	 * @param objectId id of object you want the listener to remove from
	 * @param eventClass event class you want to stop receiving in the listener
	 * @param listener you want to remove
	 */
	public void removeObjectListener(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Removes listener from every listeners category (from every listener level).
	 * <p><p>
	 * <b>WARNING:</b> Can be time consuming! (Iterating through all levels of listeners.)
	 *
	 * @param listener you want to remove from all listener levels
	 */
	public void removeListener(IWorldEventListener<?> listener);

	/**
	 * Tests whether the 'listener' is listening to a specific event (Level A listeners).
	 *
	 * @param eventClass which events you want to receive
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(Class<?> eventClass, IWorldEventListener<?> listener);

	/**
	 * Tests whether the 'listener' is listening at specified 'objectClass' (Level B listeners).
	 *
	 * @param objectClass where the listener is tested
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(Class<?> objectClass, IWorldObjectEventListener<?,?> listener);	
	
	/**
	 * Tests whether the 'listener' is listening at specified 'objectClass' for specified 'event' (Level C listeners).
	 *
	 * @param objectClass where the listener is tested
	 * @param eventClass where the listener is tested
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(Class<?> objectClass, Class<?> eventClass, IWorldObjectEventListener<?,?> listener);


	/**
	 * Tests whether the 'listener' is listening at specified 'objectId' (Level D Listeners).
	 *
	 * @param objectId where the listener is tested
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(WorldObjectId objectId, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Tests whether the 'listener' is listening to a specified 'event' that occurs on the specific object with 'objectId' (Level E listeners).
	 *
	 * @param objectId where the listener is tested
	 * @param eventClass what class is tested
	 * @param listener that is tested
	 * @return whether the listener is listening
	 */
	public boolean isListening(WorldObjectId objectId, Class<?> eventClass, IWorldObjectEventListener<?, ?> listener);

	/**
	 * Checks whether this listener is hooked to the world view (at any listener level).
	 * <p><p>
	 * <b>WARNING:</b> Can be time consuming! (Iterating through all levels of listeners.)
	 *
	 * @param listener
	 * @return
	 */
	public boolean isListening(IWorldEventListener<?> listener);
FileLine
cz/cuni/amis/pogamut/multi/communication/worldview/impl/EventDrivenLocalWorldView.java63
cz/cuni/amis/pogamut/multi/communication/worldview/impl/EventDrivenLocalWorldView.java134
    	if (isPaused()) {
    		throw new ComponentPausedException(controller.getState().getFlag(), this);
    	}
    	if (!isRunning()) {
    		throw new ComponentNotRunningException(controller.getState().getFlag(), this);
    	}
    	
    	if (!( event instanceof ILocalWorldObjectUpdatedEvent))
        {
    		if ( event instanceof ICompositeWorldObjectUpdatedEvent)
    		{
    			IWorldChangeEvent partEvent = ((ICompositeWorldObjectUpdatedEvent)event).getSharedEvent();
    			if (partEvent != null) //shared part
    			{
    				log.finest("Notyfying sharedWV " + event.toString() + ")");
    				sharedWorldView.notify(partEvent);	
    			}
    			partEvent = ((ICompositeWorldObjectUpdatedEvent)event).getStaticEvent();
				if ( partEvent != null) //static part
				{
					log.finest("Notyfying sharedWV " + event.toString() + ")");
					sharedWorldView.notify(partEvent);
					
				}
    		}
        	//shared or static event will not modify LocalObjects, no need to process it beyond notifying sharedWorldView
    		else if ( (event instanceof ISharedWorldObjectUpdatedEvent) || (event instanceof IStaticWorldObjectUpdatedEvent) )
        	{
    			log.finest("Notyfying sharedWV " + event.toString() + ")");
    			sharedWorldView.notify(event);
        		return;
        	}
        }    	
    	
        // process event
        // is this method recursively called?
        if (receiveEventProcessing) {
            // yes it is -> that means the previous event has not been
            // processed! ... store this event and allows the previous one
            // to be fully processed (e.g. postpone raising this event)
            notifyEventsList.add(event);
            
            return;
        } else {
            // no it is not ... so raise the flag that we're inside the method
            receiveEventProcessing = true;
        }
       
        try {
	        innerNotify(event);
	        // check the events list size, do we have more events to process?
	        while (notifyEventsList.size() != 0) {
	            // yes -> do it!
	            innerNotify(notifyEventsList.poll());
	        }
        } finally {
        // all events has been processed, drop the flag that we're inside the method
        	receiveEventProcessing = false;
        }
    }
    
        
    
    /**
     * Catches exceptions. If exception is caught, it calls {@link ComponentController}.fatalError() and this.kill(). 
     */
    @Override
FileLine
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java531
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java566
			if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] processing localStartPaused(" + agentId + ")");
			switch(getState().getFlag()) {
			case INSTANTIATED:
			case STOPPED:
			case RESETED:
				if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] must start-paused!");
				startPaused();
				break;			
			case RUNNING:
			case PAUSED:
				// nothing to do
				break;				
			case STARTING:
			case STARTING_PAUSED:
			case PAUSING:
			case RESUMING:
			case STOPPING:
			case KILLING:
			case RESETTING:
				// can't happen ...
				throw new ComponentCantStartException(id(component) + "[" + getState().getFlag() + "] STATE INVALID AT THIS POINT!", this);				
			case KILLED:
				if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] must start-paused! But is in killed state, must be reset()ed first in order to start-paused!");
				reset();       // reset the component first
				if (notInState(ComponentState.RESETED)) throw new PogamutException(id(component) + "[" + getState().getFlag() + "] reset has failed, could not resolve the state change.", this);
				startPaused(); // start the component
				break;
			}
			if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] calling componentControlHelper.localStartPaused(" + agentId + ")");
FileLine
cz/cuni/amis/pogamut/base/utils/guice/AgentScope.java26
cz/cuni/amis/pogamut/base/utils/guice/AgentTeamScope.java17
public class AgentTeamScope implements IAgentScope {
	
	public static class SingletonProvider<T> implements Provider<T> {
		
		private Provider<T> creator;
		
		private T singleton = null;
		
		public SingletonProvider(Provider<T> creator) {
			this.creator = creator;
		}

		@Override
		public T get() {
			if (singleton != null) {
				return singleton;
			}
			singleton = creator.get();
			return singleton;
		}
		
		public void clear() {
			singleton = null;
		}
		
	}
	
	@SuppressWarnings("unchecked")
	private Map<Key, Provider> providers = new HashMap<Key, Provider>(); 

	@SuppressWarnings("unchecked")
	@Override
	public <T> Provider scope(Key<T> key, Provider<T> creator) {
		synchronized(providers) {
			Provider p = providers.get(key);
			if (p != null) { 
				return p;
			}
			SingletonProvider<T> provider = new SingletonProvider<T>(creator);
			providers.put(key, provider);
			return provider;
		}
	}
	
	@SuppressWarnings("unchecked")
	public void clearScope() {
		synchronized(providers) {
			for (Provider provider : providers.values()) {
				((SingletonProvider)provider).clear();
			}
		}
	}

}
FileLine
cz/cuni/amis/pogamut/base/communication/worldview/impl/AbstractWorldView.java131
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractLocalWorldView.java137
	private ListenerNotifier notifier = new ListenerNotifier();

	
	/**
	 * Level A Listeners
	 * <p><p>
	 * Map of the event listeners, key is the event class where the listener is hooked to.
	 */
	private ListenersMap<Class> eventListeners = new ListenersMap<Class>();
	
	/**
	 * Level B Listeners
	 * <p><p>
	 * Map of the object class to the object listeners.
	 */
	private ListenersMap<Class> objectsListeners = new ListenersMap<Class>();
	
	/**
	 * Level C listeners
	 * <p><p>
	 * Map of event listeners on some object class.
	 * <p><p>
	 * First key is eventClass, second key is objectClass.
	 */
	private Map<Class, ListenersMap<Class>> objectEventListeners = 
		Collections.synchronizedMap(
			new LazyMap<Class, ListenersMap<Class>>(){

				@Override
				protected ListenersMap<Class> create(Class key) {
					ListenersMap<Class> listeners = new ListenersMap<Class>();
					listeners.setLog(log, "LevelC-" + key.getSimpleName());
					return listeners;
				}
			}
		);
		
	/**
	 * Level D Listeners
	 * <p><p>
	 * Listeners listening on all events on a specific object.
	 */
	private ListenersMap<WorldObjectId> specificObjectListeners = new ListenersMap<WorldObjectId>();
	
	/**
	 * Level E Listeners
	 * <p><p>
	 * Listeners listening for some specific event on some specific object.
	 * <p><p>
	 * Map of (IWorldObjectId, class of IWorldEvent or desc.).  
	 */
	private Map<WorldObjectId, ListenersMap<Class>> specificObjectEventListeners = 
		Collections.synchronizedMap(
			new LazyMap<WorldObjectId, ListenersMap<Class>>() {

				@Override
				protected ListenersMap<Class> create(WorldObjectId key) {
					ListenersMap<Class> listeners = new ListenersMap<Class>();
					listeners.setLog(log, "LevelE-" + key.getStringId());
					return listeners;
				}
			}
		);
		
	    
	/**
	 * Flag that is telling us whether there is an event being processed or not.
	 * <p><p>
	 * It is managed only by raiseEvent() method - DO NOT MODIFY OUTSIDE IT!
	 */
	private boolean raiseEventProcessing = false;
	
	/**
	 * List of events we have to process.
	 * <p><p>
	 * It is managed only by raiseEvent() method - DO NOT MODIFY THIS OUTSIDE THAT METHOD!
	 */
	private Queue<IWorldEvent> raiseEventsList = new ConcurrentLinkedQueue<IWorldEvent>();
		
	protected LogCategory log;

	protected ILifecycleBus eventBus;
FileLine
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java680
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java718
			if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] processing localResume(" + agentId + ")");
			switch(getState().getFlag()) {
			case INSTANTIATED:
			case STOPPED:
			case RESETED:
				if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] must start!");
				start();
				break;			
			case RUNNING:
				// nothing to do
				break;
			case PAUSED:
				if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] must resume!");
				resume();
				break;				
			case STARTING:
			case STARTING_PAUSED:
			case PAUSING:
			case RESUMING:
			case STOPPING:
			case KILLING:
			case RESETTING:
				// can't happen ...
				throw new ComponentCantResumeException(id(component) + "[" + getState().getFlag() + "] STATE INVALID AT THIS POINT!", this);				
			case KILLED:
				if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] must start! But is in killed state, must be reset()ed first in order to evaluate the state!");
FileLine
cz/cuni/amis/pogamut/base/agent/utils/runner/impl/AgentRunner.java550
cz/cuni/amis/pogamut/base/agent/utils/runner/impl/MultipleAgentRunner.java514
		}
    	
    }
    
    /**
     * Kills a single agent instance, called during clean up when start/pause/resume of the agent fails.
     * @param agent
     */
    protected void killAgent(AGENT agent) {
    	if (agent == null) return;
    	synchronized(mutex) {
    		if (main) {
    			agent.getState().removeListener(listener);
    		}
    		if (!(agent.getState().getFlag() instanceof IAgentStateDown)) {
        		if (log != null && log.isLoggable(Level.WARNING)) log.warning("Killing agent with id '" + agent.getComponentId().getToken() + "'");
        		try {
        			agent.kill();
        		} catch (Exception e) {    			
        		}
        	}
    	}    	
    }
	
    /**
     * Custom hook called before all the agents are going to be instantiated.
     */
    protected void preInitHook() throws PogamutException {    	
    }

    /**
     * Custom hook called after the agent is instantiated  and before
     * the {@link IAgent#start()} is called.
     * @param agent
     */
    protected void preStartHook(AGENT agent) throws PogamutException {
    }
    
    /**
     * Custom hook called after the agent is instantiated and
     * started with {@link IAgent#start()}.
     * @param agent
     * @throws PogamutException
     */
    protected void postStartHook(AGENT agent) throws PogamutException {    	
    }
    
    /**
     * Custom hook called only iff {@link MultipleAgentRunner#isPausing()}. 
     * This method is called after all the agents have been instantiated by the {@link MultipleAgentRunner#factory}
     * and resumed with {@link IAgent#resume()}.
     * @param agents
     */
    protected void preResumeHook(List<AGENT> agents) {
    }
    
    /**
     * Custom hook called after all the agents have been instantiated by the {@link MultipleAgentRunner#factory}
     * and started with {@link IAgent#start()}.
     * @param agents
     */
    protected void postStartedHook(List<AGENT> agents) {
    }

}
FileLine
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java758
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java793
			getComponentControl().localStop(agentId);
			switch(getState().getFlag()) {
			case INSTANTIATED:
			case STOPPED:
			case RESETED:
				// nothing to do
				break;			
			case RUNNING:
			case PAUSED:
				if (getStateCount(ComponentState.STARTING, ComponentState.STARTING_PAUSED, ComponentState.RUNNING, ComponentState.PAUSING, ComponentState.PAUSED, ComponentState.RESUMING, ComponentState.STOPPING) == 0) {
					if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] there are no more running/paused/...  local component states, must stop!");
					// there is not a single agent that would need to utilize the component
					stop();
				}
				break;				
			case STARTING:
			case STARTING_PAUSED:
			case PAUSING:
			case RESUMING:
			case STOPPING:
			case KILLING:
			case RESETTING:
				// can't happen ...
				throw new ComponentCantStartException(id(component) + "[" + getState().getFlag() + "] STATE INVALID AT THIS POINT!", this);				
			case KILLED:
				// nothing to do
				break;
			}
		}	
	}

	protected void localKill(IAgentId agentId) {		
FileLine
cz/cuni/amis/pogamut/base/component/bus/ComponentBus.java184
cz/cuni/amis/pogamut/base/component/lifecyclebus/LifecycleBus.java211
				if (log.isLoggable(Level.WARNING)) log.warning(LifecycleBus.COMPONENT_ID.getToken() + " is still running, broadcasting fatal error to stop all components.");
				event(new FatalErrorEvent<IComponent>(this, "Resetting."));
			}
			if (log.isLoggable(Level.WARNING)) log.warning("Broadcasting reset event.");
			resetBus();
			innerRaiseEvent(new ResetEvent(this));
		} catch (Exception e) {
			if (e instanceof ComponentBusErrorException) {
				innerRaiseEvent(new FatalErrorEvent(this, "Reset failed.", e.getCause()));
				throw new ResetFailedException(e.getCause(), log, this);
			} else {
				innerRaiseEvent(new FatalErrorEvent(this, "Reset failed.", e));
				throw new ResetFailedException(e, log, this);
			}
		}
		if (log.isLoggable(Level.WARNING)) log.warning("Reseted, bus is running again.");
	} 
	
	private void resetBus() {
		running = true;
		queue.clear();
		queueProcessing = false;
FileLine
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractLocalWorldView.java108
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractSharedWorldView.java294
	private static class ListenerNotifier<T> implements Listeners.ListenerNotifier<IListener> {

		/**
		 * Event that is being processed.
		 */
		private T event = null;
		
		@Override
		public T getEvent() {
			return event;
		}
		
		public void setEvent(T event) {
			this.event = event;			
		}

		/**
		 * Method that is used to notify the listener.
		 */
		@Override
		public void notify(IListener listener) {
			listener.notify(event);
		}
		
	}
	
	/**
	 * Notifier object - preallocated, this will raise events on the listeners.
	 */
	private ListenerNotifier notifier = new ListenerNotifier();

	
	/**
	 * Level A Listeners
	 * <p><p>
	 * Map of the event listeners, key is the event class where the listener is hooked to.
	 */
	private ListenersMap<Class> eventListeners = new ListenersMap<Class>();
	
	/**
	 * Level B Listeners
	 * <p><p>
	 * Map of the object class to the object listeners.
	 */
	private ListenersMap<Class> objectsListeners = new ListenersMap<Class>();
	
	/**
	 * Level C listeners
	 * <p><p>
	 * Map of event listeners on some object class.
	 * <p><p>
	 * First key is eventClass, second key is objectClass.
	 */
	private Map<Class, ListenersMap<Class>> objectEventListeners = 
		Collections.synchronizedMap(
			new LazyMap<Class, ListenersMap<Class>>(){

				@Override
				protected ListenersMap<Class> create(Class key) {
FileLine
cz/cuni/amis/pogamut/base3d/worldview/object/Location.java706
cz/cuni/amis/pogamut/base3d/worldview/object/Velocity.java589
	public Velocity(double x, double y, double z) {
		this.x = x;
		this.y = y;
		this.z = z;
	}
	
	private int computeHashCode() {
		final int prime = 31;
		int result = 1;
		long temp;
		temp = Double.doubleToLongBits(x);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(y);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		temp = Double.doubleToLongBits(z);
		result = prime * result + (int) (temp ^ (temp >>> 32));
		return result;
	}


	/**
	 * Creates velocity with specified planar coordinates. Sets z to zero.
	 * 
	 * @param x
	 *            X coordinate.
	 * @param y
	 *            Y coordinate.
	 */
	public Velocity(double x, double y) {
FileLine
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java614
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java655
				break;
			case PAUSED:
				// nothing to do
				break;				
			case STARTING:
			case STARTING_PAUSED:
			case PAUSING:
			case RESUMING:
			case STOPPING:
			case KILLING:
			case RESETTING:
				// can't happen ...
				throw new ComponentCantPauseException(id(component) + "[" + getState().getFlag() + "] STATE INVALID AT THIS POINT!", this);				
			case KILLED:
				if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] must start-paused! But is in killed state, must be reset()ed first in order to start-paused!");
				reset();       // reset the component first
				if (notInState(ComponentState.RESETED)) throw new PogamutException(id(component) + "[" + getState().getFlag() + "] reset has failed, could not resolve the state change.", this);
				startPaused(); // start the component
				break;
			}			
		}	
	}

	protected void localPreResume(IAgentId agentId) {		
FileLine
cz/cuni/amis/pogamut/base/component/bus/ComponentBus.java655
cz/cuni/amis/pogamut/base/component/lifecyclebus/LifecycleBus.java685
		}
		
		if (!queueProcessing) {
			// the method is not being called in the context of another event, redirect
			event(event);
			return;
		}
		 
		// process event - we're in transactional mode == immediately propagate the event
		innerRaiseEvent(event);
	}
	
	/**
	 * Must be synchronized beforehand!
	 */
	private void processQueue() throws FatalErrorPropagatingEventException, ComponentBusErrorException {
		// save the 'queueProcessing' state (whether we should drop the queue processing flag or not at the end of this method)
		boolean dropQueueProcessing = !queueProcessing;
		queueProcessing = true;
		IComponentEvent event = null;
		while(queue.size() != 0) {
			// yes we do -> do it!
			try {
			event = queue.poll();
			} catch (Exception e) {
				ComponentBusErrorException e1 = new ComponentBusErrorException("Can't poll next event.", e, this);
				innerRaiseEvent_Safe(
					new ComponentBusErrorEvent(this, e)
				);
				throw e1;
			}
			try {
				innerRaiseEvent(event);
			} catch (FatalErrorPropagatingEventException e1) {
				throw e1;
			} catch (ComponentBusErrorException e2) {
				throw e2;
			} catch (Exception e3) {
				innerRaiseEvent_Safe(
					new FatalErrorPropagatingEvent<LifecycleBus>(this, "Exception happened during the event propagation.", e3, event)
FileLine
cz/cuni/amis/pogamut/base/component/bus/ComponentBus.java157
cz/cuni/amis/pogamut/base/component/lifecyclebus/LifecycleBus.java184
		return "LifecycleBus[" + agentId.getToken() + ", running=" + running + ", queue length=" + (this.queue == null ? "null" : this.queue.size()) + "]";
	}
	
	@Override
	public IComponentBus getEventBus() {
		return this;
	}
	
	@Override
	public IToken getComponentId() {
		return COMPONENT_ID;
	}
	
	public Logger getLog() {
		return log;
	}
	
	@Override
	public boolean isRunning() {
		return running;
	}
	
	@Override
	public synchronized void reset() throws ResetFailedException {
		if (log.isLoggable(Level.WARNING)) log.warning("reset() called.");
		try {
			if (running) {
				if (log.isLoggable(Level.WARNING)) log.warning(LifecycleBus.COMPONENT_ID.getToken() + " is still running, broadcasting fatal error to stop all components.");
FileLine
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractLocalWorldView.java299
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractSharedWorldView.java490
			sharedWorldObjects.clear();
		}
		synchronized(raiseEventsList) {	
			raiseEventsList.clear();
		}
	}
	
	/**
	 * Starts the world view. 
	 * <p><p>
	 * If you override this method, do not forget to call super.start().
	 */
	protected void start() {
		cleanUp();
	}
	
	/**
	 * Pre-pauses the world view.
	 * <p><p>
	 * If you override this method, do not forget to call super.preStop().
	 */
	protected void prePause() {
	}
	
	/**
	 * Pauses the world view. 
	 * <p><p>
	 * If you override this method, do not forget to call super.start().
	 */
	protected void pause() {
	}
	
	/**
	 * Resumes the world view. 
	 * <p><p>
	 * If you override this method, do not forget to call super.start().
	 */
	protected void resume() {
	}
	
	/**
	 * Pre-stops the world view.
	 * <p><p>
	 * If you override this method, do not forget to call super.preStop().
	 */
	protected void preStop() {
	}
	
	/**
	 * Stops the world view.
	 * <p><p>
	 * If you override this method, do not forget to call super.stop().
	 */
	protected void stop() {
		cleanUp();
	}
	
	/**
	 * Kills the world view.
	 * <p><p>
	 * If you override this method, do not forget to call super.stop().
	 */
	protected void kill() {
		cleanUp();
	}

	/**
	 * Resets the world view so it is start()able again.
	 * <p><p>
	 * If you override this method, do not forget to call super.reset().
	 */
	protected void reset() {
		cleanUp();
	}
	
	protected boolean isRunning() {
		return controller.isRunning();
	}
	
	protected boolean isPaused() {
		return controller.isPaused();
	}
	
	@Override
	public Token getComponentId() {
		return COMPONENT_ID;
	}
FileLine
cz/cuni/amis/pogamut/base/utils/math/DistanceUtils.java411
cz/cuni/amis/pogamut/base/utils/math/DistanceUtils.java463
        	int i = 0;
        	for (; i < best.size(); ++i) {
        		Tuple2<T, Double> candidate = best.get(i);
        		if (betterRelation.isBetterRelation(target, location, distance, candidate.getFirst(), candidate.getSecond())) {
        			break;
        		}
        	}
        	if (i < nthBest) {
        		if (i < best.size()) {
        			best.add(i, new Tuple2<T, Double>(location, distance));
        		} else {
        			best.add(new Tuple2<T, Double>(location, distance));
        		}
        	}        	
        }
FileLine
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java478
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java517
			case KILLED:
				if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] must start! But is in killed state, must be reset()ed first in order to start!");
				reset(); // first reset the component
				if (notInState(ComponentState.RESETED)) throw new PogamutException(id(component) + "[" + getState().getFlag() + "] reset has failed, could not resolve the state change.", this);
				start(); // start it
				break;
			}
			if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] calling componentControlHelper.localStart(" + agentId + ")");
FileLine
cz/cuni/amis/pogamut/base/component/lifecyclebus/LifecycleBus.java448
cz/cuni/amis/pogamut/base/component/lifecyclebus/LifecycleBus.java516
	private void notifyListenersB_Safe(IComponentEvent event) {
		Collection<Class> componentClasses = ClassUtils.getSubclasses(event.getSource().getClass());
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		for (Class componentClass : componentClasses) {
			if (!componentEventListeners.containsKey(componentClass)) continue;
			Map<Class, Set<IComponentEventListener>> listeners = componentEventListeners.get(componentClass);
			for (Class eventClass : eventClasses) {
				if (!listeners.containsKey(eventClass)) continue;
				for (IComponentEventListener listener : listeners.get(eventClass)) {
FileLine
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java454
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java492
			if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] processing localStart(" + agentId + ")");
			switch(getState().getFlag()) {
			case INSTANTIATED:
			case STOPPED:
			case RESETED:
				if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] must start!");
				start();
				break;			
			case PAUSED:
				if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] must resume!");
				resume();
				break;
			case RUNNING:
FileLine
cz/cuni/amis/pogamut/base/component/bus/ComponentBus.java421
cz/cuni/amis/pogamut/base/component/bus/ComponentBus.java489
	private void notifyListenersB_Safe(IComponentEvent event) {
		Collection<Class> componentClasses = ClassUtils.getSubclasses(event.getSource().getClass());
		Collection<Class> eventClasses = ClassUtils.getSubclasses(event.getClass());
		for (Class componentClass : componentClasses) {
			if (!componentEventListeners.containsKey(componentClass)) continue;
			Map<Class, Set<IComponentEventListener>> listeners = componentEventListeners.get(componentClass);
			for (Class eventClass : eventClasses) {
				if (!listeners.containsKey(eventClass)) continue;
				for (IComponentEventListener listener : listeners.get(eventClass)) {
FileLine
cz/cuni/amis/pogamut/base3d/worldview/object/Location.java51
cz/cuni/amis/pogamut/base3d/worldview/object/Velocity.java32
		PropertyEditorManager.registerEditor(Velocity.class, Velocity.PropertyEditor.class);
	}

	/**
	 * Property editor for Velocity. Accepts same format as Location.
	 */
	public static class PropertyEditor extends PropertyEditorSupport {

		@Override
		public String getAsText() {
			if (getValue() != null) {
				return getValue().toString();
			} else {
				return "null";
			}
		}

		@Override
		public void setAsText(String s) {
			if ("null".equals(s.trim())) {
				setValue(null);
			} else {
				double[] d = Location.PropertyEditor.parseNumberArray(s);
				if (d.length != 3) {
					throw new IllegalArgumentException();
				}
				setValue(new Velocity(d));
FileLine
cz/cuni/amis/pogamut/base/utils/jmx/PogamutMBeanServer.java86
cz/cuni/amis/pogamut/base/utils/jmx/PogamutMBeanServer.java139
			Listener2 l = (Listener2)o;
			return SafeEquals.equals(name, l.name) && SafeEquals.equals(listener, l.listener) && SafeEquals.equals(filter, l.filter) && SafeEquals.equals(handback, l.handback);
		}
		
		@Override
		public void unregister() {
			try {
				innerRemoveNotificationListener(name, listener, filter, handback);
			} catch (Exception e) {				
			}
		}
		
		public void register() throws InstanceNotFoundException {
			innerAddNotificationListener(name, listener, filter, handback);
		}
		
		@Override
		public String toString() {
			return "Listener2[name=" + name + ", listener=" + listener + "]";
FileLine
cz/cuni/amis/pogamut/base/utils/jmx/PogamutMBeanServer.java65
cz/cuni/amis/pogamut/base/utils/jmx/PogamutMBeanServer.java118
		public Listener2(ObjectName name, NotificationListener listener, NotificationFilter filter, Object handback) {
			this.name = name;
			this.listener = listener;
			this.filter = filter;
			this.handback = handback;
			HashCode hc = new HashCode();
			hc.add(name);
			hc.add(listener);
			hc.add(filter);
			hc.add(handback);
			this.hashCode = hc.getHash();
		}
		
		@Override
		public int hashCode() {
			return hashCode;
		}
		
		public boolean equals(Object o) {
			if (o == null) return false;
			if (!(o instanceof Listener2)) return false;
FileLine
cz/cuni/amis/pogamut/base/component/bus/ComponentBus.java607
cz/cuni/amis/pogamut/base/component/lifecyclebus/LifecycleBus.java640
		}
		
		// is this method recursively called? 
		if (queueProcessing) {
			// yes it is -> that means the previous event has not been
			// processed! ... store this event and allows the previous one
			// to be fully processed (e.g. postpone raising this event)
			queue.add(event);
			return false;
		}
		
		// check the queue consistency
		if (queue.size() > 0) {
			ComponentBusErrorException e = new ComponentBusErrorException("Previous events has not been fully processed! ComponenBus fatal error.", event, this);
			innerRaiseEvent_Safe(
				new ComponentBusErrorEvent(this, e)
			);
			throw e;
		}
		
		// add the event to the queue
		queue.add(event);
		// start processing the event
		processQueue();		
		
		// event has been processed
		return true;
	}
	
	@Override
	public synchronized void eventTransactional(IComponentEvent event) throws ComponentBusNotRunningException, ComponentBusErrorException, FatalErrorPropagatingEventException {
		// method is synchronized - only one thread inside at given time
		
		NullCheck.check(event, "event");
		if (event instanceof IResetEvent) throw new IllegalArgumentException("you can't broadcast reset event this way, use reset() instead");
		
		if (!isRunning()) {
FileLine
cz/cuni/amis/pogamut/base/communication/worldview/impl/AbstractWorldView.java302
cz/cuni/amis/pogamut/multi/communication/worldview/impl/AbstractSharedWorldView.java502
	protected void start() {
		cleanUp();
	}
	
	/**
	 * Pre-pauses the world view.
	 * <p><p>
	 * If you override this method, do not forget to call super.preStop().
	 */
	protected void prePause() {
	}
	
	/**
	 * Pauses the world view. 
	 * <p><p>
	 * If you override this method, do not forget to call super.start().
	 */
	protected void pause() {
	}
	
	/**
	 * Resumes the world view. 
	 * <p><p>
	 * If you override this method, do not forget to call super.start().
	 */
	protected void resume() {
	}
	
	/**
	 * Pre-stops the world view.
	 * <p><p>
	 * If you override this method, do not forget to call super.preStop().
	 */
	protected void preStop() {
	}
	
	/**
	 * Stops the world view.
	 * <p><p>
	 * If you override this method, do not forget to call super.stop().
	 */
	protected void stop() {
		cleanUp();
	}
	
	/**
	 * Kills the world view.
	 * <p><p>
	 * If you override this method, do not forget to call super.stop().
	 */
	protected void kill() {
		cleanUp();
	}

	/**
	 * Resets the world view so it is start()able again.
	 * <p><p>
	 * If you override this method, do not forget to call super.reset().
	 */
	protected void reset() {
		cleanUp();
	}
	
	protected boolean isRunning() {
		return controller.isRunning();
	}
	
	protected boolean isPaused() {
		return controller.isPaused();
	}
	
	@Override
	public Token getComponentId() {
		return COMPONENT_ID;
	}
FileLine
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java1028
cz/cuni/amis/pogamut/base/component/controller/SharedComponentController.java1133
						if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] number of running/paused of local component states is 0, must stop!");
						// nobody is actively using the component nor is paused
						stop();
					}
				}				 
			} // else, there are still somebody who wants to use the component, keep it running!
			break;
			
		case PAUSED:
			if (getStateCount(ComponentState.STARTING, ComponentState.RUNNING, ComponentState.RESUMING) == 0) {
				// there is nobody that wants to activelly use the agent
				if (getStateCount(ComponentState.STARTING_PAUSED, ComponentState.PAUSING, ComponentState.PAUSED) > 0) {
					// nothing to do!
				} else {
					if (getStateCount(ComponentState.STOPPING) == 0) {
						if (log != null && log.isLoggable(Level.FINER)) log.finer(id(component) + "[" + getState().getFlag() + "] number of running/paused of local component states is 0, must stop!");