void SimpleNetworkVisualizationHandler::clearVisualization() {
	TRACE("SimpleNetworkVisualizationHandler::clearVisualization");

	QList<NeuronItem*> neurons = mNeurons;
	neurons << mNeuronItemPool;
	mNeurons.clear();
	mNeuronItemPool = neurons;
	for(QListIterator<NeuronItem*> i(mNeuronItemPool); i.hasNext();) {
		NeuronItem *item = i.next();
		QPointF pos = item->getGlobalPosition();
		item->setParent(0);
		item->setLocalPosition(pos);
		item->setNeuron(0);
		item->setActive(false);
		item->setHidden(true);
		item->setSelected(false);
	}
	QList<SynapseItem*> synapses = mSynapses;
	synapses << mSynapseItemPool;
	mSynapses.clear();
	mSynapseItemPool = synapses;
	for(QListIterator<SynapseItem*> i(mSynapseItemPool); i.hasNext();) {
		SynapseItem *item = i.next();
		QPointF pos = item->getGlobalPosition();
		item->setParent(0);
		item->setLocalPosition(pos);
		item->setSynapse(0);
		item->setActive(false);
		item->setHidden(true);
		item->setSelected(false);
	}
	QList<ModuleItem*> modules = mModules;
	modules << mModuleItemPool;
	mModules.clear();
	mModuleItemPool = modules;
	for(QListIterator<ModuleItem*> i(mModuleItemPool); i.hasNext();) {
		ModuleItem *item = i.next();
		QPointF pos = item->getGlobalPosition();
		item->setParent(0);
		item->setLocalPosition(pos);
		item->setModule(0);
		item->setActive(false);
		item->setHidden(true);
		item->setSelected(false);
		QList<PaintItem*> members = item->getMemberItems();
		for(QListIterator<PaintItem*> j(members); j.hasNext();) {
			PaintItem *it = j.next();
			item->removeMemberItem(it);
			it->setParent(0);
		}
	}
	QList<GroupItem*> groups = mGroups;
	groups << mGroupItemPool;
	mGroups.clear();
	mGroupItemPool = groups;
	for(QListIterator<GroupItem*> i(mGroupItemPool); i.hasNext();) {
		GroupItem *item = i.next();
		QPointF pos = item->getGlobalPosition();
		item->setParent(0);
		item->setLocalPosition(pos);
		item->setNeuronGroup(0);
		item->setActive(false);
		item->setHidden(true);
		item->setSelected(false);
	}

	mNeuronLookup.clear();
	mSynapseLookup.clear();
	mModuleLookup.clear();
	mGroupLookup.clear();

	updateVisualizationSet();


	while(mNeuronItemPool.size() > Math::max(0, mMaxSizeOfNeuronPool->get())) {
		NeuronItem *item = mNeuronItemPool.last();
		mNeuronItemPool.removeAll(item);
		delete item;
	}
	while(mSynapseItemPool.size() > Math::max(0, mMaxSizeOfSynapsePool->get())) {
		SynapseItem *item = mSynapseItemPool.last();
		mSynapseItemPool.removeAll(item);
		delete item;
	}
	while(mModuleItemPool.size() > Math::max(0, mMaxSizeOfModulePool->get())) {
		ModuleItem *item = mModuleItemPool.last();
		mModuleItemPool.removeAll(item);
		delete item;
	}
	while(mGroupItemPool.size() > Math::max(0, mMaxSizeOfGroupPool->get())) {
		GroupItem *item = mGroupItemPool.last();
		mGroupItemPool.removeAll(item);
		delete item;
	}
	
	if(mGridPosition.y() > 500) {
		mGridPosition = QPointF(20.0, 250.0);
	}

}
bool SimpleNetworkVisualizationHandler::updateNetworkView() {
	TRACE("SimpleNetworkVisualizationHandler::updateNetworkView");

	QMutexLocker locker(Neuro::getNeuralNetworkManager()->getNetworkExecutionMutex());
	
	QList<NeuronItem*> currentNeuronItems = mNeurons;
	QList<SynapseItem*> currentSynapseItems = mSynapses;
	QList<ModuleItem*> currentModuleItems = mModules;
	QList<GroupItem*> currentGroupItems = mGroups;

	for(QListIterator<ModuleItem*> i(currentModuleItems); i.hasNext();) {
		ModuleItem *moduleItem = i.next();
		QList<PaintItem*> members = moduleItem->getMemberItems();
		for(QListIterator<PaintItem*> j(members); j.hasNext();) {
			moduleItem->removeMemberItem(j.next());
		}
	}


	mNeurons.clear();
	mSynapses.clear();
	mModules.clear();
	mGroups.clear();

	if(mNetwork != 0) {

		//setup neurons
		QList<Neuron*> neurons = mNetwork->getNeurons();
		
		for(int i = 0; i < neurons.size(); ++i) {

			Neuron *neuron = neurons.at(i);

			NeuronItem *item = getNeuronItem(neuron);
			if(item == 0) {
				if(!mNeuronItemPool.empty()) {
					item = mNeuronItemPool.takeFirst();
				}
				if(item == 0) {
					item = mNeuronItemPrototype->createCopy();
				}
			}

			if(neuron->hasProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION)) {
				NetworkEditorUtil::setPaintItemLocation(item, 
						neuron->getProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION));
			}
			else {
				setLocationByGrid(item);
			}

			item->setNeuron(neuron);
			item->setActive(true);
			item->setHidden(false);

			if(!mNeurons.contains(item)) {
				mNeuronLookup.insert(neuron, item);
				mNeurons.append(item);
			}

			currentNeuronItems.removeAll(item);
		}

		//remove obsolete neuron items
		for(QListIterator<NeuronItem*> i(currentNeuronItems); i.hasNext();) {
			NeuronItem *item = i.next();
			item->setHidden(true);
			item->setActive(false);
			item->setToHiddenLayer(false);
			mNeuronLookup.remove(item->getNeuron());
			item->setNeuron(0);
			item->setParent(0);
			mNeuronItemPool.append(item);
		}

		//setup synapses
		QList<Synapse*> synapses = mNetwork->getSynapses();

		for(int i = 0; i < synapses.size(); ++i) {

			Synapse *synapse = synapses.at(i);

			SynapseItem *item = getSynapseItem(synapse);

			if(item == 0) {
				if(!mSynapseItemPool.empty()) {
					item = mSynapseItemPool.takeFirst();
				}
				if(item == 0) {
					item = mSynapseItemPrototype->createCopy();
				}
			}
			if(synapse->hasProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION)) {
				NetworkEditorUtil::setPaintItemLocation(item, 
						synapse->getProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION));
			}
			else {
				setLocationByGrid(item);
			}

			item->setSynapse(synapse);
			item->setActive(true);
			item->setHidden(false);

			if(!mSynapses.contains(item)) {
				mSynapseLookup.insert(synapse, item);
				mSynapses.append(item);
			}

			currentSynapseItems.removeAll(item);
		}

		//remove obsolete synapse items
		for(QListIterator<SynapseItem*> i(currentSynapseItems); i.hasNext();) {
			SynapseItem *item = i.next();
			item->setHidden(true);
			item->setActive(false);
			item->setToHiddenLayer(false);
			mSynapseLookup.remove(item->getSynapse());
			item->setSynapse(0);
			item->setParent(0);
			mSynapseItemPool.append(item);
		}

		//setup modules
		QList<NeuroModule*> modules = mNetwork->getNeuroModules();

		for(int i = 0; i < modules.size(); ++i) {

			NeuroModule *module = modules.at(i);

			ModuleItem *item = getModuleItem(module);

			if(item == 0) {
				if(!mModuleItemPool.empty()) {
					item = mModuleItemPool.takeFirst();
				}
				if(item == 0) {
					item = mModuleItemPrototype->createCopy();
				}
			}
			if(module->hasProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION)) {
				NetworkEditorUtil::setPaintItemLocation(item, 
						module->getProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION));
			}
			else {
				setLocationByGrid(item);
			}
			if(module->hasProperty(NeuralNetworkConstants::TAG_MODULE_SIZE)) {
				NetworkEditorUtil::setModuleItemSize(item, 
						module->getProperty(NeuralNetworkConstants::TAG_MODULE_SIZE));
			}

			item->setModule(module);
			item->setActive(true);
			item->setHidden(false);

			QList<PaintItem*> memberItems = item->getMemberItems();

			for(QListIterator<PaintItem*> k(memberItems); k.hasNext();) {
				PaintItem *it = k.next();
				QPointF pos = it->getGlobalPosition();
				item->removeMemberItem(it);
				it->setLocalPosition(pos);
			}

			if(!mModules.contains(item)) {
				mModuleLookup.insert(module, item);
				mModules.append(item);
			}
			currentModuleItems.removeAll(item);

			//add member neurons to module
			QRectF moduleBounds = item->getBoundingBox();
			QList<Neuron*> members = module->getNeurons();

			for(QListIterator<Neuron*> j(members); j.hasNext();) {
				Neuron *n = j.next();

				if(n == 0) {
					continue;
				}

				NeuronItem *neuronItem = getNeuronItem(n);
				if(neuronItem == 0) {
					continue;
				}
				QRectF neuronBounds = neuronItem->getBoundingBox();

				QPointF pos = neuronItem->getLocalPosition() - item->getGlobalPosition();
				pos.setX(Math::min(Math::max(pos.x(), (neuronBounds.width() / 2.0)),
						 moduleBounds.width() - (neuronBounds.width() / 2.0)));
				pos.setY(Math::min(Math::max(pos.y(), (neuronBounds.height() / 2.0)),
						 moduleBounds.height() - (neuronBounds.height() / 2.0)));
				

				neuronItem->setLocalPosition(pos);
				item->addMemberItem(neuronItem);
			}

			//add member synapses to module
			for(QListIterator<Synapse*> j(synapses); j.hasNext();) {		
				Synapse *s = j.next();
				if(s == 0) {
					continue;
				}
				Neuron *n = s->getSource();
				if(n == 0) {
					continue;
				}

				if(!members.contains(n)) {
					continue;
				}

				SynapseItem *synapseItem = getSynapseItem(s);
				if(synapseItem == 0) {
					continue;
				}
				synapseItem->setLocalPosition(
								synapseItem->getLocalPosition() - item->getGlobalPosition());

				item->addMemberItem(synapseItem);
			}	
		}

		//remove obsolete module items
		for(QListIterator<ModuleItem*> i(currentModuleItems); i.hasNext();) {
			ModuleItem *item = i.next();
			item->setHidden(true);
			item->setActive(false);
			item->setToHiddenLayer(false);
			mModuleLookup.remove(item->getNeuroModule());
			item->setModule(0);
			item->setParent(0);
			mModuleItemPool.append(item);
		}

		//check if submodules have to be added.
		for(int i = 0; i < modules.size(); ++i) {
			NeuroModule *module = modules.at(i);

			if(module == 0) {
				continue;
			}

			ModuleItem *moduleItem = getModuleItem(module);

			if(moduleItem == 0) {
				continue;
			}

			QList<NeuroModule*> subModules = module->getSubModules();

			for(QListIterator<NeuroModule*> j(subModules); j.hasNext();) {
				NeuroModule *subModule = j.next();

				if(subModule == 0) {
					continue;
				}

				ModuleItem *subModuleItem = getModuleItem(subModule);

				if(subModuleItem == 0) {
					continue;
				}

				subModuleItem->setLocalPosition(
						subModuleItem->getLocalPosition() - moduleItem->getGlobalPosition());
				moduleItem->addMemberItem(subModuleItem);
			}
		}

		//setup groups
		QList<NeuronGroup*> groups = mNetwork->getNeuronGroups();

		for(int i = 0; i < groups.size(); ++i) {

			NeuronGroup *group = groups.at(i);
			if(dynamic_cast<NeuroModule*>(group) != 0) {
				//ignore neuro modules
				continue;
			}

			GroupItem *item = getGroupItem(group);

			if(item == 0) {
				if(!mGroupItemPool.empty()) {
					item = mGroupItemPool.takeFirst();
				}
				if(item == 0) {
					item = mGroupItemPrototype->createCopy();
				}
			}
			if(group->hasProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION)) {
				NetworkEditorUtil::setPaintItemLocation(item, 
						group->getProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION));
			}
			else {
				setLocationByGrid(item);
			}

			item->setNeuronGroup(group);
			item->setActive(true);
			item->setHidden(false);

			if(!mGroups.contains(item)) {
				mGroupLookup.insert(group, item);
				mGroups.append(item);
			}

			currentGroupItems.removeAll(item);
		}

		//remove obsolete group items
		for(QListIterator<GroupItem*> i(currentGroupItems); i.hasNext();) {
			GroupItem *item = i.next();
			item->setHidden(true);
			item->setActive(false);
			item->setToHiddenLayer(false);
			mGroupLookup.remove(item->getNeuronGroup());
			item->setNeuronGroup(0);
			item->setParent(0);
			mGroupItemPool.append(item);
		}

		//update location property
		for(QListIterator<NeuronItem*> i(mNeurons); i.hasNext();) {
			NeuronItem *item = i.next();
			if(item == 0) {
				continue;
			}
			Neuron *neuron = item->getNeuron();
			if(neuron == 0 || neuron->hasProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION)) {
				continue;
			}
			neuron->setProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION, 
											QString::number(item->getGlobalPosition().x()) + "," 
											+ QString::number(item->getGlobalPosition().y()) + ",0");
		}
		for(QListIterator<SynapseItem*> i(mSynapses); i.hasNext();) {
			SynapseItem *item = i.next();
			if(item == 0) {
				continue;
			}
			Synapse *synapse = item->getSynapse();
			if(synapse == 0 || synapse->hasProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION)) {
				continue;
			}
			synapse->setProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION,
 											QString::number(item->getGlobalPosition().x()) + "," 
											+ QString::number(item->getGlobalPosition().y()) + ",0");
		}
		for(QListIterator<ModuleItem*> i(mModules); i.hasNext();) {
			ModuleItem *item = i.next();
			if(item == 0) {
				continue;
			}
			NeuroModule *module = item->getNeuroModule();
			if(module == 0 || module->hasProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION)) {
				continue;
			}
			module->setProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION,
											QString::number(item->getGlobalPosition().x()) + "," 
											+ QString::number(item->getGlobalPosition().y()) + ",0");
		}
		for(QListIterator<GroupItem*> i(mGroups); i.hasNext();) {
			GroupItem *item = i.next();
			if(item == 0) {
				continue;
			}
			NeuronGroup *group = item->getNeuronGroup();
			if(group == 0 || group->hasProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION)) {
				continue;
			}
			group->setProperty(NeuralNetworkConstants::TAG_ELEMENT_LOCATION,
											QString::number(item->getGlobalPosition().x()) + "," 
											+ QString::number(item->getGlobalPosition().y()) + ",0");
		}
	}
	else {
		clearVisualization();
	}
	updateVisualizationSet(); 
	
	if(mOwner != 0) {
		mOwner->updateHiddenLayerMode();
	}

	return true;
}