diff --git a/BaseLib/RunTime.cpp b/BaseLib/RunTime.cpp
index 5c615a44f386ed60d8db00dc4479a57373501a44..8a37ea72f0ee0689fbbc9a5d8eae9309d7dbd4d7 100644
--- a/BaseLib/RunTime.cpp
+++ b/BaseLib/RunTime.cpp
@@ -37,7 +37,7 @@ double RunTime::elapsed()
 #ifndef _WIN32
 	return (_stop.tv_sec + _stop.tv_usec/1000000.0 - (_start.tv_sec + _start.tv_usec/1000000.0));
 #else
-	return (_stop - _start) / 1000;
+	return (_stop - _start) / 1000.0;
 #endif
 }
 
diff --git a/BaseLib/uniqueListInsert.h b/BaseLib/uniqueInsert.h
similarity index 62%
rename from BaseLib/uniqueListInsert.h
rename to BaseLib/uniqueInsert.h
index 8ea948f4a924e1114955aadb1e2fe5029a618a59..04547e8e1e44c793d0a2476aca0dba7fc2698d79 100644
--- a/BaseLib/uniqueListInsert.h
+++ b/BaseLib/uniqueInsert.h
@@ -14,13 +14,15 @@
 #define UNIQUELISTINSERT_H_
 
 #include <list>
+#include <vector>
 
 namespace BaseLib {
 
-void uniqueListInsert (std::list<size_t>& list, size_t element)
+template<class T>
+void uniqueListInsert (std::list<T>& list, T element)
 {
 	// search element
-	std::list<size_t>::const_iterator it;
+	std::list<T>::const_iterator it;
 	for (it = list.begin (); it != list.end(); it++) {
 		if (*it == element) return;
 	}
@@ -28,6 +30,18 @@ void uniqueListInsert (std::list<size_t>& list, size_t element)
 	list.push_back (element);
 }
 
+template<class T>
+void uniqueVectorInsert (std::vector<T>& vec, T element)
+{
+	// search element
+	std::vector<T>::const_iterator it;
+	for (it = vec.begin (); it != vec.end(); ++it)
+		if (*it == element) return;
+	// element not found -> insert
+	vec.push_back (element);
+}
+
+
 } // end namespace BaseLib
 
 #endif /* UNIQUELISTINSERT_H_ */
diff --git a/Gui/DataExplorer.cmake b/Gui/DataExplorer.cmake
index 0780ae920101221abac144f7349487f2897b9326..adb35db72e27184266afb240e1bd271989095686 100644
--- a/Gui/DataExplorer.cmake
+++ b/Gui/DataExplorer.cmake
@@ -110,6 +110,7 @@ ADD_DEPENDENCIES ( ogs-gui VtkVis OGSProject )
 IF(MSVC)
 	# Set linker flags
 	SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:MSVCRT")
+	TARGET_LINK_LIBRARIES( ogs-gui winmm)
 ENDIF(MSVC)
 
 IF(OGS_BUILD_INFO)
diff --git a/Gui/main.cpp b/Gui/main.cpp
index 37de4122690bd0a8d2a2c5b7266aa779f28d52b5..b6d1aedc76c01ded5625073d125cceeda948f5fd 100644
--- a/Gui/main.cpp
+++ b/Gui/main.cpp
@@ -4,13 +4,15 @@
 #ifdef OGS_USE_OPENSG
 #include <OpenSG/OSGBaseFunctions.h>
 #endif
+#include "logog.hpp"
 
 int main(int argc, char* argv[])
 {
 #ifdef OGS_USE_OPENSG
 	OSG::osgInit(argc, argv);
 #endif
-
+	LOGOG_INITIALIZE();
+	logog::Cout* logogCout = new logog::Cout;
 	QApplication a(argc, argv);
 	setlocale(LC_NUMERIC,"C");
 	MainWindow* w = new MainWindow();
@@ -19,6 +21,8 @@ int main(int argc, char* argv[])
 	int returncode = a.exec();
 	delete w;
 
+	delete logogCout;
+	LOGOG_SHUTDOWN();
 #ifdef OGS_USE_OPENSG
 	OSG::osgExit();
 #endif // OGS_USE_OPENSG
diff --git a/MathLib/EarClippingTriangulation.cpp b/MathLib/EarClippingTriangulation.cpp
index 2b5b7bbb0f785c3e1fd12b44723bf3cd44ce16b3..4b7232fec3a8752e128268fdfb381ba11f4647d2 100644
--- a/MathLib/EarClippingTriangulation.cpp
+++ b/MathLib/EarClippingTriangulation.cpp
@@ -16,7 +16,7 @@
 // BaseLib
 #include "swap.h"
 #include "printList.h"
-#include "uniqueListInsert.h"
+#include "uniqueInsert.h"
 
 // MathLib
 #include "EarClippingTriangulation.h"
diff --git a/MeshLib/Elements/Edge.cpp b/MeshLib/Elements/Edge.cpp
index ed49b9095429a2a627f3804ff19836abc38f8b90..dc024ad92ac281b2f731c015057e0b31c506fa9e 100644
--- a/MeshLib/Elements/Edge.cpp
+++ b/MeshLib/Elements/Edge.cpp
@@ -52,6 +52,13 @@ double Edge::computeVolume()
 	return sqrt(MathLib::sqrDist(_nodes[0]->getCoords(), _nodes[1]->getCoords()));
 }
 
+bool Edge::isEdge(unsigned idx1, unsigned idx2) const
+{
+	if (0==idx1 && 1==idx2) return true;
+	if (1==idx1 && 0==idx2) return true;
+	return false;
+}
+
 Element* Edge::clone() const
 {
 	return new Edge(*this);
diff --git a/MeshLib/Elements/Edge.h b/MeshLib/Elements/Edge.h
index dcb0898e5ab2435b4c0d80dc435a54287d671d53..a14be496b32a881f11019bca7ccd8498d4fd327a 100644
--- a/MeshLib/Elements/Edge.h
+++ b/MeshLib/Elements/Edge.h
@@ -75,8 +75,15 @@ public:
 	/// Get the number of nodes for this element.
 	virtual unsigned getNNodes() const { return 2; };
 
+	/**
+	 * Method returns the type of the element. In this case EDGE will be returned.
+	 * @return MshElemType::EDGE
+	 */
 	virtual MshElemType::type getType() const { return MshElemType::EDGE; }
 
+	/// Returns true if these two indeces form an edge and false otherwise
+	bool isEdge(unsigned i, unsigned j) const;
+
 	virtual Element* clone() const;
 
 	/**
@@ -88,7 +95,7 @@ public:
 protected:
 	double computeVolume();
 	/// 1D elements have no edges.
-	Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { (void)edge_id; (void)node_id; return NULL; };
+	Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { (void)edge_id; (void)node_id; return NULL; };
 
 	/// 1D elements have no faces.
 	Node* getFaceNode(unsigned face_id, unsigned node_id) const { (void)face_id; (void)node_id; return NULL; };
diff --git a/MeshLib/Elements/Element.cpp b/MeshLib/Elements/Element.cpp
index bf356f8ccca68fb418dacb8dd10359b2ff4b57a6..e3bef2d317633bb4fa7dbd66e759f873adc273b4 100644
--- a/MeshLib/Elements/Element.cpp
+++ b/MeshLib/Elements/Element.cpp
@@ -59,7 +59,6 @@ bool Element::addNeighbor(Element* e)
 			if (_nodes[i] == e_nodes[j])
 			{
 				face_nodes[count] = _nodes[i];
-				//std::cout << _nodes[i]->getID() << " == " << e_nodes[j]->getID() << std::endl;
 				// increment shared nodes counter and check if enough nodes are similar to be sure e is a neighbour of this
 				if ((++count)>=dim)
 				{
@@ -105,6 +104,15 @@ const Element* Element::getNeighbor(unsigned i) const
 	return NULL;
 }
 
+unsigned Element::getNodeIDinElement(const MeshLib::Node* node) const
+{
+	const unsigned nNodes (this->getNNodes());
+	for (unsigned i(0); i<nNodes; i++)
+		if (node == _nodes[i]) 
+			return i;
+	return std::numeric_limits<unsigned>::max();
+}
+
 const Node* Element::getNode(unsigned i) const
 {
 	if (i < getNNodes())
@@ -136,5 +144,6 @@ bool Element::hasNeighbor(Element* elem) const
 	return false;
 }
 
+
 }
 
diff --git a/MeshLib/Elements/Element.h b/MeshLib/Elements/Element.h
index ae08aad2398a4f7ecf464367c5a76bcde2846354..2a6b0fbce2af3397100ac162a1a49d63214c2702 100644
--- a/MeshLib/Elements/Element.h
+++ b/MeshLib/Elements/Element.h
@@ -93,6 +93,9 @@ public:
 	/// Get the number of nodes for this element.
 	virtual unsigned getNNodes() const = 0;
 
+	/// Returns the position of the given node in the node array of this element.
+	virtual unsigned getNodeIDinElement(const MeshLib::Node* node) const;
+
 	/**
 	 * Get the global index for the Node with local index i.
 	 * The index i should be at most the number of nodes of the element.
@@ -109,11 +112,15 @@ public:
 	/// Get the value for this element.
 	unsigned getValue() const { return _value; };
 
+	/// Returns true if elem is a neighbour of this element and false otherwise.
 	bool hasNeighbor(Element* elem) const;
 
 	/// Destructor
 	virtual ~Element();
 
+	/// Returns true if these two indeces form an edge and false otherwise
+	virtual bool isEdge(unsigned i, unsigned j) const = 0;
+
 	/**
 	 * Method clone is a pure virtual method in the abstract base class Element.
 	 * It has to be implemented in the derived classes (for instance in class Hex).
@@ -143,11 +150,12 @@ protected:
 	Element(unsigned value = 0);
 
 	/// Return a specific edge node.
-	virtual Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const = 0;
+	virtual Node* getEdgeNode(unsigned edge_id, unsigned node_id) const = 0;
 
 	/// Returns the ID of a face given an array of nodes.
 	virtual unsigned identifyFace(Node* nodes[3]) const = 0;
 
+
 	Node** _nodes;
 	unsigned _value;
 	Element** _neighbors;
diff --git a/MeshLib/Elements/Hex.cpp b/MeshLib/Elements/Hex.cpp
index 8cdda69b6953f35b843c5aca37b698927b0868c0..7b0dae8a288a4675bfb965f81153f8fc6b733301 100644
--- a/MeshLib/Elements/Hex.cpp
+++ b/MeshLib/Elements/Hex.cpp
@@ -115,6 +115,16 @@ const Element* Hex::getFace(unsigned i) const
 	return NULL;
 }
 
+bool Hex::isEdge(unsigned idx1, unsigned idx2) const
+{
+	for (unsigned i(0); i<12; i++)
+	{
+		if (_edge_nodes[i][0]==idx1 && _edge_nodes[i][1]==idx2) return true;
+		if (_edge_nodes[i][1]==idx1 && _edge_nodes[i][0]==idx2) return true;
+	}
+	return false;
+}
+
 Element* Hex::clone() const
 {
 	return new Hex(*this);
diff --git a/MeshLib/Elements/Hex.h b/MeshLib/Elements/Hex.h
index c214f54917521091d22b3aefd84e86331d498116..3f1cc3e27825633edc74c8347f6d79503dee7350 100644
--- a/MeshLib/Elements/Hex.h
+++ b/MeshLib/Elements/Hex.h
@@ -81,6 +81,9 @@ public:
 	 */
 	virtual MshElemType::type getType() const { return MshElemType::HEXAHEDRON; }
 
+	/// Returns true if these two indeces form an edge and false otherwise
+	bool isEdge(unsigned i, unsigned j) const;
+
 	/**
 	 * Method clone is inherited from class Element. It makes a deep copy of the Hex instance.
 	 * @return an exact copy of the object
@@ -98,7 +101,7 @@ protected:
 	double computeVolume();
 
 	/// Return a specific edge node.
-	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	/// Returns the ID of a face given an array of nodes.
 	unsigned identifyFace(Node* nodes[3]) const;
diff --git a/MeshLib/Elements/Prism.cpp b/MeshLib/Elements/Prism.cpp
index 58f719059f945e5446ce189f70544dec5a709926..a88089ea26c5a4073b54f4590b58903c04e17810 100644
--- a/MeshLib/Elements/Prism.cpp
+++ b/MeshLib/Elements/Prism.cpp
@@ -120,6 +120,16 @@ unsigned Prism::getNFaceNodes(unsigned i) const
 	return 0;
 }
 
+bool Prism::isEdge(unsigned idx1, unsigned idx2) const
+{
+	for (unsigned i(0); i<9; i++)
+	{
+		if (_edge_nodes[i][0]==idx1 && _edge_nodes[i][1]==idx2) return true;
+		if (_edge_nodes[i][1]==idx1 && _edge_nodes[i][0]==idx2) return true;
+	}
+	return false;
+}
+
 Element* Prism::clone() const
 {
 	return new Prism(*this);
diff --git a/MeshLib/Elements/Prism.h b/MeshLib/Elements/Prism.h
index 0aa4dd0f4fc29013fdef72827dea86ce4b51c5a7..6167377f25cc3ca6dea85a6db8235ac5fee54e87 100644
--- a/MeshLib/Elements/Prism.h
+++ b/MeshLib/Elements/Prism.h
@@ -79,6 +79,9 @@ public:
 	 */
 	virtual MshElemType::type getType() const { return MshElemType::PRISM; }
 
+	/// Returns true if these two indeces form an edge and false otherwise
+	bool isEdge(unsigned i, unsigned j) const;
+
 	/**
 	 * Method clone is inherited from class Element. It makes a deep copy of the
 	 * Hex instance employing the copy constructor of class Prism.
@@ -102,7 +105,7 @@ protected:
 	double computeVolume();
 
 	/// Return a specific edge node.
-	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	/// Returns the ID of a face given an array of nodes.
 	unsigned identifyFace(Node* nodes[3]) const;
diff --git a/MeshLib/Elements/Pyramid.cpp b/MeshLib/Elements/Pyramid.cpp
index adf4cf3604b61711a0aabf5aa36aecfef089ffa3..8f782e89d1158754817b772da2ba981125a88d71 100644
--- a/MeshLib/Elements/Pyramid.cpp
+++ b/MeshLib/Elements/Pyramid.cpp
@@ -119,6 +119,16 @@ unsigned Pyramid::getNFaceNodes(unsigned i) const
 	return 0;
 }
 
+bool Pyramid::isEdge(unsigned idx1, unsigned idx2) const
+{
+	for (unsigned i(0); i<8; i++)
+	{
+		if (_edge_nodes[i][0]==idx1 && _edge_nodes[i][1]==idx2) return true;
+		if (_edge_nodes[i][1]==idx1 && _edge_nodes[i][0]==idx2) return true;
+	}
+	return false;
+}
+
 Element* Pyramid::clone() const
 {
 	return new Pyramid(*this);
diff --git a/MeshLib/Elements/Pyramid.h b/MeshLib/Elements/Pyramid.h
index 4c87b52ee87444a006aab7b44f00d9fafdbff6c1..4b2f33241f2d72f478fba74c6a9a7e02308c025c 100644
--- a/MeshLib/Elements/Pyramid.h
+++ b/MeshLib/Elements/Pyramid.h
@@ -77,6 +77,9 @@ public:
 	 */
 	virtual MshElemType::type getType() const { return MshElemType::PYRAMID; }
 
+	/// Returns true if these two indeces form an edge and false otherwise
+	bool isEdge(unsigned i, unsigned j) const;
+
 	/**
 	 * Method clone is inherited from class Element. It makes a deep copy of the
 	 * Pyramid instance employing the copy constructor of class Pyramid.
@@ -100,7 +103,7 @@ protected:
 	double computeVolume();
 
 	/// Return a specific edge node.
-	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	/// Returns the ID of a face given an array of nodes.
 	unsigned identifyFace(Node* nodes[3]) const;
diff --git a/MeshLib/Elements/Quad.cpp b/MeshLib/Elements/Quad.cpp
index 3bec55469fc4ad8d4aeeebf6a63726501ae6feeb..ba5cecd10d62736a31d2f97e8fcd9b107dd74781 100644
--- a/MeshLib/Elements/Quad.cpp
+++ b/MeshLib/Elements/Quad.cpp
@@ -75,6 +75,16 @@ double Quad::computeVolume()
          + MathLib::calcTriangleArea(_nodes[2]->getCoords(), _nodes[3]->getCoords(), _nodes[0]->getCoords());
 }
 
+bool Quad::isEdge(unsigned idx1, unsigned idx2) const
+{
+	for (unsigned i(0); i<4; i++)
+	{
+		if (_edge_nodes[i][0]==idx1 && _edge_nodes[i][1]==idx2) return true;
+		if (_edge_nodes[i][1]==idx1 && _edge_nodes[i][0]==idx2) return true;
+	}
+	return false;
+}
+
 Element* Quad::clone() const
 {
 	return new Quad(*this);
diff --git a/MeshLib/Elements/Quad.h b/MeshLib/Elements/Quad.h
index 5f9d55d0a9291003f006bd184a1346921321f6d2..1b7a885ab2f2d8d264fe2d7f1c605c0e04365319 100644
--- a/MeshLib/Elements/Quad.h
+++ b/MeshLib/Elements/Quad.h
@@ -62,6 +62,9 @@ public:
 	 */
 	virtual MshElemType::type getType() const { return MshElemType::QUAD; }
 
+	/// Returns true if these two indeces form an edge and false otherwise
+	bool isEdge(unsigned i, unsigned j) const;
+
 	/**
 	 * Method clone is inherited from class Element. It makes a deep copy of the Quad instance.
 	 * @return an exact copy of the object
@@ -85,7 +88,7 @@ protected:
 
 protected:
 	/// Return a specific edge node.
-	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	/// Returns the ID of a face given an array of nodes.
 	unsigned identifyFace(Node* nodes[3]) const;
diff --git a/MeshLib/Elements/Tet.cpp b/MeshLib/Elements/Tet.cpp
index ce57084ec1c697506625ba53d43584cf9835fd58..2d2fe6770932e21ec4d0bb11fd36d7310fb381c8 100644
--- a/MeshLib/Elements/Tet.cpp
+++ b/MeshLib/Elements/Tet.cpp
@@ -105,6 +105,16 @@ const Element* Tet::getFace(unsigned i) const
 	return NULL;
 }
 
+bool Tet::isEdge(unsigned idx1, unsigned idx2) const
+{
+	for (unsigned i(0); i<6; i++)
+	{
+		if (_edge_nodes[i][0]==idx1 && _edge_nodes[i][1]==idx2) return true;
+		if (_edge_nodes[i][1]==idx1 && _edge_nodes[i][0]==idx2) return true;
+	}
+	return false;
+}
+
 Element* Tet::clone() const
 {
 	return new Tet(*this);
diff --git a/MeshLib/Elements/Tet.h b/MeshLib/Elements/Tet.h
index f77af5faad8fa31e6bdb359ff8fa86129d352bbb..8563ad41c2400e6d4f20fcc3caf8f5c90687d14d 100644
--- a/MeshLib/Elements/Tet.h
+++ b/MeshLib/Elements/Tet.h
@@ -76,6 +76,9 @@ public:
 	 */
 	virtual MshElemType::type getType() const { return MshElemType::TETRAHEDRON; }
 
+	/// Returns true if these two indeces form an edge and false otherwise
+	bool isEdge(unsigned i, unsigned j) const;
+
 	/**
 	 * Method clone is inherited from class Element. It makes a deep copy of the Tet instance.
 	 * @return an exact copy of the object
@@ -104,7 +107,7 @@ protected:
 	 * @param node_id the id of the node within the edge (either 0 or 1)
 	 * @return a pointer to the internal Node
 	 */
-	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	/// Returns the ID of a face given an array of nodes.
 	unsigned identifyFace(Node* nodes[3]) const;
diff --git a/MeshLib/Elements/Tri.cpp b/MeshLib/Elements/Tri.cpp
index 316e09394ccc8576dcd24e939260b0c6061486da..e3d51768685ed36e32f94dc2bf384900c9e0739a 100644
--- a/MeshLib/Elements/Tri.cpp
+++ b/MeshLib/Elements/Tri.cpp
@@ -67,6 +67,16 @@ Tri::~Tri()
 {
 }
 
+bool Tri::isEdge(unsigned idx1, unsigned idx2) const
+{
+	for (unsigned i(0); i<3; i++)
+	{
+		if (_edge_nodes[i][0]==idx1 && _edge_nodes[i][1]==idx2) return true;
+		if (_edge_nodes[i][1]==idx1 && _edge_nodes[i][0]==idx2) return true;
+	}
+	return false;
+}
+
 Element* Tri::clone() const
 {
 	return new Tri(*this);
diff --git a/MeshLib/Elements/Tri.h b/MeshLib/Elements/Tri.h
index b14a9847184fce4634e265a71dd0d1b4853e4135..77961bc57a3010469111e7d382b0e5346421653e 100644
--- a/MeshLib/Elements/Tri.h
+++ b/MeshLib/Elements/Tri.h
@@ -64,6 +64,9 @@ public:
 	 */
 	virtual MshElemType::type getType() const { return MshElemType::TRIANGLE; }
 
+	/// Returns true if these two indeces form an edge and false otherwise
+	bool isEdge(unsigned i, unsigned j) const;
+
 	/**
 	 * Method clone is inherited from class Element. It makes a deep copy of the Tri instance.
 	 * @return an exact copy of the object
@@ -86,7 +89,7 @@ protected:
 
 protected:
 	/// Return a specific edge node.
-	inline Node const* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
+	inline Node* getEdgeNode(unsigned edge_id, unsigned node_id) const { return _nodes[_edge_nodes[edge_id][node_id]]; };
 
 	/// Returns the ID of a face given an array of nodes.
 	unsigned identifyFace(Node* nodes[3]) const;
diff --git a/MeshLib/Mesh.cpp b/MeshLib/Mesh.cpp
index e6117acb8ae1e834fa68df7d7ebb4f74fc327d3b..171fb1b01c4eb1fa42579e0e7bf09cda51280dde 100644
--- a/MeshLib/Mesh.cpp
+++ b/MeshLib/Mesh.cpp
@@ -12,6 +12,8 @@
 
 #include "Mesh.h"
 
+#include <set>
+
 #include "Node.h"
 #include "Elements/Tri.h"
 #include "Elements/Quad.h"
@@ -20,6 +22,11 @@
 #include "Elements/Pyramid.h"
 #include "Elements/Prism.h"
 
+#include "logog.hpp"
+
+#include "RunTime.h"
+#include "uniqueInsert.h"
+
 namespace MeshLib {
 
 Mesh::Mesh(const std::string &name, const std::vector<Node*> &nodes, const std::vector<Element*> &elements)
@@ -30,8 +37,10 @@ Mesh::Mesh(const std::string &name, const std::vector<Node*> &nodes, const std::
 	_edge_length[1] = 0;
 	this->makeNodesUnique();
 	this->setDimension();
-	this->setElementInformationForNodes();
-	this->setNeighborInformationForElements();
+	this->setElementsConnectedToNodes();
+	//this->setNodesConnectedByEdges();
+	//this->setNodesConnectedByElements();
+	this->setElementsConnectedToElements();
 }
 
 Mesh::Mesh(const Mesh &mesh)
@@ -53,8 +62,10 @@ Mesh::Mesh(const Mesh &mesh)
 	}
 
 	if (_mesh_dimension==0) this->setDimension();
-	this->setElementInformationForNodes();
-	this->setNeighborInformationForElements();
+	this->setElementsConnectedToNodes();
+	//this->setNodesConnectedByEdges();
+	//this->setNodesConnectedByElements();
+	this->setElementsConnectedToElements();
 }
 
 Mesh::~Mesh()
@@ -116,21 +127,22 @@ void Mesh::setDimension()
 			_mesh_dimension = _elements[i]->getDimension();
 }
 
-void Mesh::setElementInformationForNodes()
+void Mesh::setElementsConnectedToNodes()
 {
 	const size_t nElements (_elements.size());
 	for (unsigned i=0; i<nElements; i++)
 	{
-		const unsigned nNodes (_elements[i]->getNNodes());
+		MeshLib::Element* element = _elements[i];
+		const unsigned nNodes (element->getNNodes());
 		for (unsigned j=0; j<nNodes; j++)
-			_elements[i]->_nodes[j]->addElement(_elements[i]);
+			element->_nodes[j]->addElement(element);
 	}
 #ifdef NDEBUG
 	// search for nodes that are not part of any element
 	const size_t nNodes (_nodes.size());
 	for (unsigned i=0; i<nNodes; i++)
 		if (_nodes[i]->getNElements() == 0)
-			std::cout << "Warning: Node " << i << " is not part of any element." << std::endl;
+			WARN ("Warning: Node %d is not part of any element.", i);
 #endif
 }
 
@@ -142,10 +154,10 @@ void Mesh::setEdgeLengthRange(const double &min_length, const double &max_length
 		_edge_length[1] = max_length;
 	}
 	else
-		std::cerr << "Error in MeshLib::Mesh::setEdgeLengthRange() - min length > max length." << std::endl;
+		ERR ("Error in MeshLib::Mesh::setEdgeLengthRange() - min length > max length.");
 }
 
-void Mesh::setNeighborInformationForElements()
+void Mesh::setElementsConnectedToElements()
 {
 	const size_t nElements = _elements.size();
 #ifdef _OPENMP
@@ -181,5 +193,63 @@ void Mesh::setNeighborInformationForElements()
 	}
 }
 
+void Mesh::setNodesConnectedByEdges()
+{
+	const size_t nNodes (this->_nodes.size());
+	for (unsigned i=0; i<nNodes; i++)
+	{
+		MeshLib::Node* node (_nodes[i]);
+		std::vector<MeshLib::Node*> conn_set;
+		const std::vector<MeshLib::Element*> &conn_elems (node->getElements());
+		const size_t nConnElems (conn_elems.size());
+		for (unsigned j=0; j<nConnElems; j++)
+		{
+			const unsigned idx (conn_elems[j]->getNodeIDinElement(node));
+			const unsigned nElemNodes (conn_elems[j]->getNNodes());
+			for (unsigned k(0); k<nElemNodes; k++)
+			{
+				bool is_in_vector (false);
+				const size_t nConnNodes (conn_set.size());
+				for (unsigned l(0); l<nConnNodes; l++)
+					if (conn_elems[j]->getNode(k) == conn_set[l])
+						is_in_vector = true;
+				if (is_in_vector) continue;
+				if (conn_elems[j]->isEdge(idx, k))
+					conn_set.push_back(_nodes[conn_elems[j]->getNode(k)->getID()]);
+			}
+		}
+		node->setConnectedNodes(conn_set);
+	}
+}
+
+void Mesh::setNodesConnectedByElements()
+{
+	const size_t nNodes (this->_nodes.size());
+	for (unsigned i=0; i<nNodes; i++)
+	{
+		MeshLib::Node* node (_nodes[i]);
+		std::vector<MeshLib::Node*> conn_vec;
+		const std::vector<MeshLib::Element*> &conn_elems (node->getElements());
+		const size_t nConnElems (conn_elems.size());
+		for (unsigned j=0; j<nConnElems; j++)
+		{
+			const unsigned nElemNodes (conn_elems[j]->getNNodes());
+			for (unsigned k(0); k<nElemNodes; k++)
+			{
+				bool is_in_vector (false);
+				const MeshLib::Node* c_node (conn_elems[j]->getNode(k));
+				if (c_node == node) continue;
+				const size_t nConnNodes (conn_vec.size());
+				for (unsigned l(0); l<nConnNodes; l++)
+					if (c_node == conn_vec[l])
+						is_in_vector = true;
+				if (!is_in_vector) 
+					conn_vec.push_back(_nodes[c_node->getID()]);
+			}
+		}
+		node->setConnectedNodes(conn_vec);
+	}
+}
+
 }
 
diff --git a/MeshLib/Mesh.h b/MeshLib/Mesh.h
index 02f9923d030878b9566378586909799843c365d1..cef9ece7faf78d468ff9efc9551b5ff32d1dba64 100644
--- a/MeshLib/Mesh.h
+++ b/MeshLib/Mesh.h
@@ -101,10 +101,14 @@ protected:
 	void setDimension();
 
 	/// Fills in the neighbor-information for nodes (i.e. which element each node belongs to).
-	void setElementInformationForNodes();
+	void setElementsConnectedToNodes();
 
 	/// Fills in the neighbor-information for elements.
-	void setNeighborInformationForElements();
+	void setElementsConnectedToElements();
+
+	void setNodesConnectedByEdges();
+
+	void setNodesConnectedByElements();
 
 	unsigned _mesh_dimension;
 	double _edge_length[2];
diff --git a/MeshLib/MeshQuality/MeshQualityChecker.cpp b/MeshLib/MeshQuality/MeshQualityChecker.cpp
index 83e1c1738efb659eb47d1db2d9bab9e9a5275bc9..ef579055c2937b9718f87fbae2e91e418579f6dd 100644
--- a/MeshLib/MeshQuality/MeshQualityChecker.cpp
+++ b/MeshLib/MeshQuality/MeshQualityChecker.cpp
@@ -36,11 +36,10 @@ BASELIB::Histogram<double> MeshQualityChecker::getHistogram (size_t nclasses) co
 
 void MeshQualityChecker::errorMsg (const Element* elem, size_t idx) const
 {
-	std::cout << "Error in MeshQualityChecker::check() - "
-			  << "Calculated value of element is below double precision minimum." << std::endl;
-	std::cout << "Points of " << MshElemType2String(elem->getType()) << "-Element " << idx << ": " << std::endl;
+	ERR ("Error in MeshQualityChecker::check() - Calculated value of element is below double precision minimum.");
+	ERR ("Points of %s-Element %d: ", MshElemType2String(elem->getType()), idx);
 	for (size_t i(0); i < elem->getNNodes(); i++)
-		std::cout << "\t Node " << i << " " << GeoLib::Point((elem->getNode(i))->getCoords()) << std::endl;
+		ERR ("\t Node %d: %f", i, GeoLib::Point((elem->getNode(i))->getCoords()));
 }
 
 std::vector<double> const&
diff --git a/MeshLib/MeshQuality/MeshQualityChecker.h b/MeshLib/MeshQuality/MeshQualityChecker.h
index ea7a0eabdc06209ec75c74c9a592ebdb0fdb0ed4..6fb929e2fe89be617c39e0bfde761847be8cc4c5 100644
--- a/MeshLib/MeshQuality/MeshQualityChecker.h
+++ b/MeshLib/MeshQuality/MeshQualityChecker.h
@@ -21,6 +21,8 @@
 #include "Mesh.h"
 #include "Elements/Element.h"
 
+#include "logog.hpp"
+
 namespace MeshLib
 {
 class MeshQualityChecker
diff --git a/MeshLib/MeshQuality/MeshQualityShortestLongestRatio.cpp b/MeshLib/MeshQuality/MeshQualityShortestLongestRatio.cpp
index c31b8d90564176d3c1fcaabd08fdadc7445491a9..b70002ca58af457214f460043766ead1ffb9566a 100644
--- a/MeshLib/MeshQuality/MeshQualityShortestLongestRatio.cpp
+++ b/MeshLib/MeshQuality/MeshQualityShortestLongestRatio.cpp
@@ -61,9 +61,8 @@ void MeshQualityShortestLongestRatio::check()
 			break;
 		}
 		default:
-			std::cout << "MeshQualityShortestLongestRatio::check () check for element type "
-			          << MshElemType2String(elem->getType())
-			          << " not implemented" << std::endl;
+			ERR ("MeshQualityShortestLongestRatio::check () check for element type %s not implemented.",
+			     MshElemType2String(elem->getType()));
 		}
 	}
 }
diff --git a/MeshLib/MeshQuality/MeshQualityVolume.cpp b/MeshLib/MeshQuality/MeshQualityVolume.cpp
index 0187c2319f24feffd3744aaf47f1f6fa99171bd8..114a3c1e0b4b69ec2666e14dfd7d942dfae9205f 100644
--- a/MeshLib/MeshQuality/MeshQualityVolume.cpp
+++ b/MeshLib/MeshQuality/MeshQualityVolume.cpp
@@ -52,11 +52,9 @@ void MeshQualityVolume::check()
         _mesh_quality_measure[k] = volume;
 	}
 
-	std::cout << "MeshQualityVolume::check() minimum: " << _min
-	          << ", max_volume: " << _max << std::endl;
+	INFO ("MeshQualityVolume::check() minimum: %f, max_volume: %f", _min, _max);
 	if (error_count > 0)
-		std::cout << "Warning: " << error_count << " elements with zero volume found." <<
-		std::endl;
+		WARN ("Warning: %d elements with zero volume found.", error_count);
 }
 
 } // end namespace MeshLib
diff --git a/MeshLib/MshEditor.cpp b/MeshLib/MshEditor.cpp
index bad87b43686c0e43c8fd0e645acff7542a58c838..6e56aaafd7b394229ce8690a40621453db7a531e 100644
--- a/MeshLib/MshEditor.cpp
+++ b/MeshLib/MshEditor.cpp
@@ -21,6 +21,8 @@
 
 #include "MathTools.h"
 
+#include "logog.hpp"
+
 namespace MeshLib {
 
 void MshEditor::getSurfaceAreaForNodes(const MeshLib::Mesh* mesh, std::vector<double> &node_area_vec)
@@ -51,10 +53,10 @@ void MshEditor::getSurfaceAreaForNodes(const MeshLib::Mesh* mesh, std::vector<do
 			node_area_vec.push_back(node_area);
 		}
 
-		std::cout<< "Total surface Area: " << total_area << std::endl;
+		INFO ("Total surface Area: %f", total_area);
 	}
 	else
-		std::cout << "Error in MshEditor::getSurfaceAreaForNodes() - Given mesh is no surface mesh (dimension != 2)." << std::endl;
+		ERR ("Error in MshEditor::getSurfaceAreaForNodes() - Given mesh is no surface mesh (dimension != 2).");
 }
 
 MeshLib::Mesh* MshEditor::removeMeshNodes(MeshLib::Mesh* mesh,
@@ -116,7 +118,7 @@ MeshLib::Mesh* MshEditor::removeMeshNodes(MeshLib::Mesh* mesh,
 std::vector<GeoLib::PointWithID*> MshEditor::getSurfaceNodes(const MeshLib::Mesh &mesh)
 {
 	/* TODO6
-	std::cout << "Extracting surface nodes..." << std::endl;
+	INFO ("Extracting surface nodes...");
 	// Sort points lexicographically
 	size_t nNodes (mesh.nod_vector.size());
 	std::vector<GeoLib::PointWithID*> nodes;
@@ -149,7 +151,7 @@ std::vector<GeoLib::PointWithID*> MshEditor::getSurfaceNodes(const MeshLib::Mesh
 
 MeshLib::Mesh* MshEditor::getMeshSurface(const MeshLib::Mesh &mesh, const double* dir)
 {
-	std::cout << "Extracting mesh surface..." << std::endl;
+	INFO ("Extracting mesh surface...");
 
 	const std::vector<MeshLib::Element*> elements = mesh.getElements();
 	std::vector<MeshLib::Element*> new_elements;
diff --git a/MeshLib/Node.cpp b/MeshLib/Node.cpp
index 247d787e2476c14b06f82d113bac179a07dc5f9d..4d3b6f83f5e96d912778bf3fee7d6a5ca37cb18a 100644
--- a/MeshLib/Node.cpp
+++ b/MeshLib/Node.cpp
@@ -34,7 +34,6 @@ Node::~Node()
 {
 }
 
-
 void Node::updateCoordinates(double x, double y, double z)
 {
 	_x[0] = x;
diff --git a/MeshLib/Node.h b/MeshLib/Node.h
index 05a50e56a94bca53b5dec66e64dfacb2a7c8b040..9436e1553f949c783d877460e8adfe6e9d95c335 100644
--- a/MeshLib/Node.h
+++ b/MeshLib/Node.h
@@ -16,6 +16,7 @@
 #include <cstdlib>
 #include <limits>
 #include <vector>
+#include <set>
 
 #include "PointWithID.h"
 #include "Mesh.h"
@@ -66,6 +67,8 @@ protected:
 	 */
 	void addElement(Element* elem) { _elements.push_back(elem); };
 
+	void setConnectedNodes(std::vector<Node*> &connected_nodes) { this->_connected_nodes = connected_nodes; };
+
 	/// Sets the ID of a node to the given value.
 	void setID(unsigned id) { this->_id = id; };
 
@@ -73,6 +76,7 @@ protected:
 	/// This method automatically also updates the areas/volumes of all connected elements.
 	virtual void updateCoordinates(double x, double y, double z);
 	
+	std::vector<Node*> _connected_nodes;
 	std::vector<Element*> _elements;
 
 }; /* class */