diff --git a/Base/CMakeLists.txt b/Base/CMakeLists.txt
index 2acb5e21be9845f6427db8933eb2a281c50370cf..c2bff2d135a8a8ac772e3389adb6554518da5ad1 100644
--- a/Base/CMakeLists.txt
+++ b/Base/CMakeLists.txt
@@ -1,14 +1,27 @@
 # Source files
 SET( HEADERS
-	Configure.h.in
-	TimeMeasurementBase.h
-	RunTimeTimer.h
+        binarySearch.h
+        Configure.h.in
 	CPUTimeTimer.h
+        DateTools.h
+        FileFinder.h
+        FileTools.h
+        printList.h
+        quicksort.h
+	RunTimeTimer.h
+        StringTools.h
+        swap.h
+	TimeMeasurementBase.h
+        uniqueListInsert.h
+        wait.h
 )
 
 SET( SOURCES
-	RunTimeTimer.cpp
+	binarySearch.cpp
+	DateTools.cpp
         CPUTimeTimer.cpp
+	RunTimeTimer.cpp
+	StringTools.cpp
 )
 
 # Create the library
@@ -16,3 +29,9 @@ ADD_LIBRARY( Base STATIC ${HEADERS} ${SOURCES} )
 
 SET_TARGET_PROPERTIES(Base PROPERTIES LINKER_LANGUAGE CXX)
 
+INCLUDE_DIRECTORIES(
+        ../GEOLib
+        ../MathLib
+        .
+)
+
diff --git a/Base/Configure.h.in b/Base/Configure.h.in
index aead27c31e567cdc1e141fa27ebce45f7e77f5a5..307759a4d601d1bb95d4b22d4498d1569fed827a 100644
--- a/Base/Configure.h.in
+++ b/Base/Configure.h.in
@@ -3,13 +3,19 @@
  *
  * #defines which gets set through CMake
  */
-#ifndef CONFIGURE_H
-#define CONFIGURE_H
+ #ifndef CONFIGURE_H
+ #define CONFIGURE_H
 
+#define OGS_QT_VERSION ${QT_VERSION_MAJOR}${QT_VERSION_MINOR}
 #define SOURCEPATH "${CMAKE_SOURCE_DIR}"
 
-#cmakedefine HAVE_PTHREADS
-#cmakedefine PROCESSOR_COUNT "${PROCESSOR_COUNT}"
+#cmakedefine OGS_VERSION "${OGS_VERSION}"
+#cmakedefine OGS_DATE "${OGS_DATE}"
 
-#endif // CONFIGURE_H
+// for tests
+#cmakedefine OGS_EXECUTABLE "${OGS_EXECUTABLE}"
+#define PUT_TMP_DIR_IN "${PROJECT_BINARY_DIR}/tests/"
+
+#cmakedefine PROCESSOR_COUNT ${PROCESSOR_COUNT}
 
+#endif // CONFIGURE_H
diff --git a/Base/DateTools.cpp b/Base/DateTools.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4165c7c754f02cdf8a9c210117164c8a7c6467d5
--- /dev/null
+++ b/Base/DateTools.cpp
@@ -0,0 +1,77 @@
+/*
+ * DateTools.cpp
+ *
+ *  Created on: Jun 16, 2010
+ *      Author: KR Initial implementation (in header file)
+ *      TF moved implementation to source file
+ */
+
+#include "DateTools.h"
+#include <cmath>
+#include <cstdlib>
+
+double date2double(int y, int m, int d)
+{
+	if ( (y<1000 || y>9999) || (m<1 || m>12) || (d<1 || d>31) )
+	{
+		std::cout << "Error: date2double() -- input not in expected format." << std::endl;
+		return 0;
+	}
+
+	int ddate=0;
+	if (y<1900) y+=1900;
+	ddate = y*10000;
+	ddate += (m*100);
+	ddate += d;
+
+	return ddate;
+}
+
+std::string date2string(double ddate)
+{
+	if (ddate<10000101 || ddate>99991231)
+	{
+		std::cout << "Error: date2String() -- input not in expected format." << std::endl;
+		return "0.0.0000";
+	}
+
+	int rest (static_cast<int>(ddate));
+	int y = static_cast<int>(floor(rest/10000.0));
+	rest = rest % (y*10000);
+	int m = static_cast<int>(floor(rest/100.0));
+	if (m<1 || m>12) std::cout << "Warning: date2String() -- month not in [1:12]" << std::endl;
+	rest = rest % (m*100);
+	int d = rest;
+	if (d<1 || d>31) std::cout << "Warning: date2String() -- day not in [1:31]" << std::endl;
+
+	std::string day = number2str(d);
+	if (d<10) day = "0" + day;
+	std::string month = number2str(m);
+	if (m<10) month = "0" + month;
+	std::string s =  number2str(y) + "-" + month + "-" + day;
+	return s;
+}
+
+double strDate2double(const std::string &s)
+{
+	size_t sep ( s.find(".",0) );
+	int d ( atoi(s.substr(0, sep).c_str()) );
+	size_t sep2 ( s.find(".", sep+1) );
+	int m ( atoi(s.substr(sep+1,sep2-(sep+1)).c_str()) );
+	int y ( atoi(s.substr(sep2+1, s.length()-(sep2+1)).c_str()) );
+	return date2double(y, m, d);
+}
+
+double xmlDate2double(const std::string &s)
+{
+	if (s.length() == 10)
+	{
+		int d = atoi(s.substr(8,2).c_str());
+		if (d<1 || d>31) std::cout << "Warning: xmlDate2double() -- day not in [1:31]" << std::endl;
+		int m = atoi(s.substr(5,2).c_str());
+		if (m<1 || m>12) std::cout << "Warning: xmlDate2double() -- month not in [1:12]" << std::endl;
+		int y = atoi(s.substr(0,4).c_str());
+		return date2double(y, m, d);
+	}
+	return 0;
+}
diff --git a/Base/DateTools.h b/Base/DateTools.h
new file mode 100644
index 0000000000000000000000000000000000000000..33e965852e5587e61cf3ba4734a59b9ba1c235ee
--- /dev/null
+++ b/Base/DateTools.h
@@ -0,0 +1,42 @@
+/**
+ * \file DateTools.h
+ * 22/01/2010 KR Initial implementation
+ */
+
+#ifndef DATETOOLS_H
+#define DATETOOLS_H
+
+#include "StringTools.h"
+#include <string>
+
+/**
+ * Converts three integers representing a date into a double.
+ * Note: It is not really checked if the date actually makes sense.
+ */
+double date2Double(int y, int m, int d);
+
+/**
+ * Converts a double representing a date into a string.
+ * Note: It is not really checked if the date actually makes sense.
+ * \param ddate Number containing date in double format yyyymmdd
+ * \return A string containing the date in format "dd.mm.yyyy".
+ */
+std::string date2string(double ddate);
+
+/**
+ * Converts a string containing a date into a double.
+ * Note: It is not really checked if the date actually makes sense.
+ * \param s String containing the date, the expected format is "dd.mm.yyyy".
+ * \return A number representing the date as dd.mm.yyyy.
+ */
+double strDate2double(const std::string &s);
+
+/**
+ * Converts a string containing a date into a double.
+ * Note: It is not really checked if the date actually makes sense.
+ * \param s String containing the date, the expected format is conform to the xml date type, i.e. "yyyy-mm-dd".
+ * \return A number representing the date as yyyymmdd.
+ */
+double xmlDate2double(const std::string &s);
+
+#endif //DATETOOLS_H
diff --git a/Base/FileFinder.h b/Base/FileFinder.h
new file mode 100644
index 0000000000000000000000000000000000000000..41ba7228a00270793b22c2bc2552651b14f6f788
--- /dev/null
+++ b/Base/FileFinder.h
@@ -0,0 +1,54 @@
+/**
+ * \file FileFinder.h
+ * 26/10/2010 KR Initial implementation
+ */
+
+#ifndef FILEFINDER_H
+#define FILEFINDER_H
+
+/**
+ * FileFinder stores a list of directories and will return the complete path
+ * for a given filename if the corresponding file is found in any of these
+ * directories.
+ */
+class FileFinder
+{
+public:
+	/// Constructor
+	FileFinder() {};
+
+	/**
+	 * \brief Adds another directory to the search-space.
+	 * If the given directory does not end with a slash one will be appended.
+	 */
+	void addDirectory(std::string dir)
+	{
+		if (dir[dir.size()-1] != '/') dir.append("/");
+		_directories.push_back(dir);
+	};
+
+	/**
+	 * Given a filename, this method will return the complete path where this file can be found.
+	 * If the file is located in more than one of the directories in the search list, only the
+	 * first location will be returned.
+	 */
+	std::string getPath(std::string filename)
+	{
+		if (_directories.empty()) std::cout << "Error: FileFinder::getPath() -- directory list is empty." << std::endl;
+		for (std::list<std::string>::iterator it = _directories.begin(); it != _directories.end(); ++it)
+		{
+			std::string testDir(*it);
+			std::ifstream is(testDir.append(filename).c_str());
+			if (is.good()) return testDir;
+		}
+		std::cout << "Error: FileFinder::getPath() -- file not found." << std::endl;
+		return filename;
+	};
+
+private:
+
+	std::list<std::string> _directories;
+
+
+};
+#endif // FILEFINDER_H
diff --git a/Base/FileTools.h b/Base/FileTools.h
new file mode 100644
index 0000000000000000000000000000000000000000..ddf915b32b2c8f2bd759b7de9e8ac8f21270e25e
--- /dev/null
+++ b/Base/FileTools.h
@@ -0,0 +1,46 @@
+/**
+ * \file FileTools.h
+ * 26/4/2010 LB Initial implementation
+ *
+ */
+
+
+#ifndef FILETOOLS_H
+#define FILETOOLS_H
+
+// ** INCLUDES **
+#include <sys/stat.h>
+
+/**
+ * Returns true if given file exists. From http://www.techbytes.ca/techbyte103.html
+ */
+static bool IsFileExisting(std::string strFilename)
+{
+	struct stat stFileInfo;
+	bool blnReturn;
+	int intStat;
+
+	// Attempt to get the file attributes
+	intStat = stat(strFilename.c_str(),&stFileInfo);
+
+	if(intStat == 0)
+	{
+		// We were able to get the file attributes
+		// so the file obviously exists.
+		blnReturn = true;
+	}
+	else
+	{
+		// We were not able to get the file attributes.
+		// This may mean that we don't have permission to
+		// access the folder which contains this file. If you
+		// need to do that level of checking, lookup the
+		// return values of stat which will give you
+		// more details on why stat failed.
+		blnReturn = false;
+	}
+
+	return(blnReturn);
+}
+
+#endif // FILETOOLS_H
diff --git a/Base/StringTools.cpp b/Base/StringTools.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..01fffcf4acc9a9817bab8918a1db808227e7694b
--- /dev/null
+++ b/Base/StringTools.cpp
@@ -0,0 +1,109 @@
+/*
+ * StringTools.cpp
+ *
+ *  Created on: Jun 16, 2010
+ *      Author: TF
+ */
+
+#include "StringTools.h"
+
+std::list<std::string> splitString(const std::string &str, char delim)
+{
+	std::list<std::string> strList;
+	std::stringstream ss(str);
+    std::string item;
+    while(getline(ss, item, delim)) {
+        strList.push_back(item);
+    }
+    return strList;
+}
+
+std::string replaceString(const std::string &searchString, const std::string &replaceString, std::string stringToReplace)
+ {
+	std::string::size_type pos = stringToReplace.find(searchString, 0);
+	int intLengthSearch = searchString.length();
+
+	while (std::string::npos != pos) {
+		stringToReplace.replace(pos, intLengthSearch, replaceString);
+		pos = stringToReplace.find(searchString, 0);
+	}
+	return stringToReplace;
+}
+
+void trim(std::string &str, char ch)
+{
+  std::string::size_type pos = str.find_last_not_of(ch);
+  if(pos != std::string::npos)
+  {
+    str.erase(pos + 1);
+    pos = str.find_first_not_of(ch);
+    if(pos != std::string::npos) str.erase(0, pos);
+  }
+  else str.erase(str.begin(), str.end());
+}
+
+
+#ifdef MSVC
+void correctScientificNotation(std::string filename, size_t precision)
+{
+	std::ifstream stream;
+	std::ofstream outputStream;
+
+	stream.open(filename.c_str());
+	std::string tmpFilename = filename + ".tmp";
+	outputStream.open(tmpFilename.c_str());
+
+	if (!stream)
+	{
+		std::cout << "correctScientificNotation: fstream is not open" << std::endl;
+		return;
+	}
+
+	std::string line;
+
+	// Iterate over lines in stream
+	while (getline(stream, line))
+	{
+		std::string word;
+		std::istringstream iss(line);
+		// Iterate over all words in line
+		while (iss >> word)
+		{
+			// Search for e+0
+			std::size_t exponentPosition = word.find("e+0", precision);
+			if (exponentPosition == std::string::npos)
+				// If not found search for e-0
+				exponentPosition = word.find("e-0", precision);
+			if (exponentPosition != std::string::npos)
+			{
+				std::size_t wordSize = word.size();
+				std::size_t exponentSize = wordSize - exponentPosition;
+
+				if(exponentSize > 4)
+				{
+					// Erase the leading zero considering trailing characters
+					int i = wordSize - 1;
+					while (!isdigit(word[i]))
+						--i;
+
+					size_t erasePos = wordSize - 3 - (wordSize - 1 - i);
+					std::string eraseString = word.substr(erasePos, 1);
+					if (eraseString.find("0") != std::string::npos)
+						word.erase(erasePos, 1);
+				}
+			}
+
+			outputStream << word << " ";
+		}
+		outputStream << std::endl;
+	}
+
+	stream.close();
+	outputStream.close();
+
+	remove(filename.c_str());
+	rename(tmpFilename.c_str(), filename.c_str());
+}
+#endif
+
+
diff --git a/Base/StringTools.h b/Base/StringTools.h
new file mode 100644
index 0000000000000000000000000000000000000000..d63f537f4bcaae58a770513667a19821b294668e
--- /dev/null
+++ b/Base/StringTools.h
@@ -0,0 +1,64 @@
+#ifndef STRINGTOOLS_H
+#define STRINGTOOLS_H
+
+#include <string>
+#include <list>
+#include <sstream>
+#include <fstream>
+#include <iostream>
+#include <ctype.h>
+
+
+/**
+ *   Splits a string into a list of strings.
+ *  \param str String to be splitted
+ *  \param delim Character indicating that the string should be splitted
+ *  \return
+ */
+std::list<std::string> splitString(const std::string &str, char delim);
+
+/**
+ *   Replaces a substring with another in a string
+ *  \param searchString Search for this string
+ *  \param replaceString Replace with this string
+ *  \param stringToReplace Search and replace in this string
+ *  \return The modified string
+ */
+std::string replaceString(const std::string &searchString, const std::string &replaceString, std::string stringToReplace);
+
+/**
+ *   Converts a number (double, float, int, ...) into a string
+ *  \param d The number to be converted
+ *  \return The number as string
+ */
+template<typename T> std::string number2str(T d)
+{
+	std::stringstream out;
+	out << d;
+	return out.str();
+}
+
+/**
+ *   Converts a string into a number (double, float, int, ...)
+ *  Example: size_t number (str2number<size_t> (str));
+ *  \param str string to be converted
+ *  \return the number
+ */
+template<typename T> T str2number (const std::string &str)
+{
+	std::stringstream strs (str, std::stringstream::in | std::stringstream::out);
+	T v;
+	strs >> v;
+	return v;
+}
+
+/**
+ * Strip whitespace (or other characters) from the beginning and end of a string.
+ */
+void trim(std::string &str, char ch=' ');
+
+#ifdef MSVC
+void correctScientificNotation(std::string filename, size_t precision = 0);
+#endif
+
+#endif //STRINGTOOLS_H
diff --git a/Base/binarySearch.cpp b/Base/binarySearch.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7ecd110b79c7dddec320de8e955ca1929a4fec8b
--- /dev/null
+++ b/Base/binarySearch.cpp
@@ -0,0 +1,22 @@
+/*
+ * binarySearch.cpp
+ *
+ *  Created on: Sep 7, 2010
+ *      Author: TF
+ */
+
+#include "binarySearch.h"
+
+size_t searchElement (double const& val, size_t beg, size_t end, const std::vector<double>& array)
+{
+	if (beg >= end) return std::numeric_limits<size_t>::max();
+	size_t m ((end+beg)/2);
+
+	if (array[m] - val < 0 && array[m+1] - val > 0) {
+		return m;
+	}
+	if (val < array[m]) {
+		return searchElement (val, beg, m, array);
+	}
+	return searchElement (val, m+1, end, array);
+}
diff --git a/Base/binarySearch.h b/Base/binarySearch.h
new file mode 100644
index 0000000000000000000000000000000000000000..92148b228a020f1714f71bcf8e21e0ad0b2573eb
--- /dev/null
+++ b/Base/binarySearch.h
@@ -0,0 +1,43 @@
+/*
+ * binarySearch.h
+ *
+ *  Created on: Jun 7, 2010
+ *      Author: TF
+ */
+
+// STL
+#include <limits>
+#include <vector>
+#include <cstddef>
+
+#ifndef BINARYSEARCH_H_
+#define BINARYSEARCH_H_
+
+/**
+ * Binary search in a sorted vector of elements to get the
+ * id of an element according its key.
+ * @param key the key for the element
+ * @param beg beginning index in the sorted vector of elements
+ * @param end ending index in the sorted vector of elements
+ * @param array the vector of elements
+ * @return the id of the element in the vector or, if not found,
+ * the value std::numeric_limits<size_t>::max()
+ */
+template <class T>
+size_t searchElement (const T& key, size_t beg, size_t end, const std::vector<T>& array)
+{
+	if (beg >= end) return std::numeric_limits<size_t>::max();
+	size_t m ((end+beg)/2);
+
+	if (key == array[m]) {
+		return m;
+	}
+	if (key < array[m]) {
+		return searchElement (key, beg, m, array);
+	}
+	return searchElement (key, m+1, end, array);
+}
+
+size_t searchElement (double const& val, size_t beg, size_t end, const std::vector<double>& array);
+
+#endif /* BINARYSEARCH_H_ */
diff --git a/Base/printList.h b/Base/printList.h
new file mode 100644
index 0000000000000000000000000000000000000000..bb0e7dd1c80af3ffa0b6cfbc8eb0cd2586e72bd4
--- /dev/null
+++ b/Base/printList.h
@@ -0,0 +1,30 @@
+/*
+ * printList.h
+ *
+ *  Created on: Feb 23, 2011
+ *      Author: TF
+ */
+
+#ifndef PRINTLIST_H_
+#define PRINTLIST_H_
+
+// STL
+#include <list>
+#include <string>
+#include <iostream>
+
+namespace BASELIB {
+
+void printList (std::list<size_t> const& mylist, std::string const& title)
+{
+	std::cout << title << std::endl;
+	for (std::list<size_t>::const_iterator my_it (mylist.begin());
+		my_it != mylist.end(); my_it++) {
+		std::cout << *my_it << " ";
+	}
+	std::cout << std::endl;
+}
+
+} // end namespace BASELIB
+
+#endif /* PRINTLIST_H_ */
diff --git a/Base/quicksort.h b/Base/quicksort.h
new file mode 100644
index 0000000000000000000000000000000000000000..0650d485d43ba06777922311220462d1c333d710
--- /dev/null
+++ b/Base/quicksort.h
@@ -0,0 +1,182 @@
+/*
+ * quicksort.h
+ *
+ *  Created on: May 26, 2010
+ *      Author: TF
+ */
+
+#ifndef QUICKSORT_H_
+#define QUICKSORT_H_
+
+// STL
+#include <cstddef>
+
+// Base
+#include "swap.h"
+
+/**
+ * version of partition_ that additional updates the permutation vector
+ * */
+template <class T>
+size_t partition_(T* array, size_t beg, size_t end, size_t *perm)
+{
+	size_t i = beg + 1;
+	size_t j = end - 1;
+	T m = array[beg];
+
+	for (;;) {
+		while ((i < end) && (array[i] <= m))
+			i++;
+		while ((j > beg) && !(array[j] <= m))
+			j--;
+
+		if (i >= j)
+			break;
+		BASELIB::swap(array[i], array[j]);
+		BASELIB::swap(perm[i], perm[j]);
+	}
+
+	BASELIB::swap(array[beg], array[j]);
+	BASELIB::swap(perm[beg], perm[j]);
+	return j;
+}
+
+/**
+ * version of quickSort that stores the permutation
+ * */
+template <class T>
+void quicksort(T* array, size_t beg, size_t end, size_t* perm)
+{
+	if (beg < end) {
+		size_t p = partition_(array, beg, end, perm);
+		quicksort(array, beg, p, perm);
+		quicksort(array, p+1, end, perm);
+	}
+}
+
+// STL
+#include <vector>
+
+template <typename T>
+class Quicksort {
+public:
+	Quicksort (std::vector<T>& array, size_t beg, size_t end, std::vector<size_t>& perm)
+	{
+		quicksort (array, beg, end, perm);
+	}
+private:
+	size_t partition_(std::vector<T>& array, size_t beg, size_t end, std::vector<size_t>& perm)
+	{
+		size_t i = beg + 1;
+		size_t j = end - 1;
+		T m = array[beg];
+
+		for (;;) {
+			while ((i < end) && (array[i] <= m))
+				i++;
+			while ((j > beg) && !(array[j] <= m))
+				j--;
+
+			if (i >= j)
+				break;
+			BASELIB::swap(array[i], array[j]);
+			BASELIB::swap(perm[i], perm[j]);
+		}
+
+		BASELIB::swap(array[beg], array[j]);
+		BASELIB::swap(perm[beg], perm[j]);
+		return j;
+	}
+
+	void quicksort(std::vector<T>& array, size_t beg, size_t end, std::vector<size_t>& perm)
+	{
+		if (beg < end) {
+			size_t p = partition_(array, beg, end, perm);
+			quicksort(array, beg, p, perm);
+			quicksort(array, p+1, end, perm);
+		}
+	}
+};
+
+// specialization for pointer types
+template <typename T>
+class Quicksort <T *> {
+public:
+	Quicksort (std::vector<T*>& array, size_t beg, size_t end, std::vector<size_t>& perm)
+	{
+		quicksort (array, beg, end, perm);
+	}
+
+	Quicksort (std::vector<size_t>& perm, size_t beg, size_t end, std::vector<T*>& array)
+	{
+		quicksort (perm, beg, end, array);
+	}
+
+private:
+	size_t partition_(std::vector<T*>& array, size_t beg, size_t end, std::vector<size_t>& perm)
+	{
+		size_t i = beg + 1;
+		size_t j = end - 1;
+		T* m = array[beg];
+
+		for (;;) {
+			while ((i < end) && (*array[i] <= *m))
+				i++;
+			while ((j > beg) && !(*array[j] <= *m))
+				j--;
+
+			if (i >= j)
+				break;
+			BASELIB::swap(array[i], array[j]);
+			BASELIB::swap(perm[i], perm[j]);
+		}
+
+		BASELIB::swap(array[beg], array[j]);
+		BASELIB::swap(perm[beg], perm[j]);
+		return j;
+	}
+
+	void quicksort(std::vector<T*>& array, size_t beg, size_t end, std::vector<size_t>& perm)
+	{
+		if (beg < end) {
+			size_t p = partition_(array, beg, end, perm);
+			quicksort(array, beg, p, perm);
+			quicksort(array, p+1, end, perm);
+		}
+	}
+
+	size_t partition_(std::vector<size_t> &perm, size_t beg, size_t end, std::vector<T*>& array)
+	{
+		size_t i = beg + 1;
+		size_t j = end - 1;
+		size_t m = perm[beg];
+
+		for (;;) {
+			while ((i < end) && (perm[i] <= m))
+				i++;
+			while ((j > beg) && !(perm[j] <= m))
+				j--;
+
+			if (i >= j)
+				break;
+			BASELIB::swap(perm[i], perm[j]);
+			BASELIB::swap(array[i], array[j]);
+		}
+
+		BASELIB::swap(perm[beg], perm[j]);
+		BASELIB::swap(array[beg], array[j]);
+		return j;
+	}
+
+	void quicksort(std::vector<size_t>& perm, size_t beg, size_t end, std::vector<T*>& array)
+	{
+		if (beg < end) {
+			size_t p = partition_(perm, beg, end, array);
+			quicksort(perm, beg, p, array);
+			quicksort(perm, p+1, end, array);
+		}
+	}
+
+};
+
+#endif /* QUICKSORT_H_ */
diff --git a/Base/swap.h b/Base/swap.h
new file mode 100644
index 0000000000000000000000000000000000000000..9915e9135c3aecbd70a69b9aa4b76e18791bb525
--- /dev/null
+++ b/Base/swap.h
@@ -0,0 +1,18 @@
+#ifndef SWAP_H_
+#define SWAP_H_
+
+namespace BASELIB {
+
+/**
+ * swap the content of arg0 and arg1
+ */
+template<class T> void swap(T& arg0, T& arg1)
+{
+  T temp(arg0);
+  arg0 = arg1;
+  arg1 = temp;
+}
+
+} // end namespace BASELIB
+
+#endif //SWAP_H_
diff --git a/Base/uniqueListInsert.h b/Base/uniqueListInsert.h
new file mode 100644
index 0000000000000000000000000000000000000000..779545a7ca4b097a517b222f541bdf862b58f156
--- /dev/null
+++ b/Base/uniqueListInsert.h
@@ -0,0 +1,28 @@
+/*
+ * uniqueListInsert.h
+ *
+ *  Created on: Feb 23, 2011
+ *      Author: TF
+ */
+
+#ifndef UNIQUELISTINSERT_H_
+#define UNIQUELISTINSERT_H_
+
+#include <list>
+
+namespace BASELIB {
+
+void uniqueListInsert (std::list<size_t>& list, size_t element)
+{
+	// search element
+	std::list<size_t>::const_iterator it;
+	for (it = list.begin (); it != list.end(); it++) {
+		if (*it == element) return;
+	}
+	// element not found -> insert
+	list.push_back (element);
+}
+
+} // end namespace BASELIB
+
+#endif /* UNIQUELISTINSERT_H_ */
diff --git a/Base/wait.h b/Base/wait.h
new file mode 100644
index 0000000000000000000000000000000000000000..2973158740e78f9a94c09eb52d7386530d35c342
--- /dev/null
+++ b/Base/wait.h
@@ -0,0 +1,28 @@
+/**
+ * \file DateTools.h
+ * 2011/02/17 KR Initial implementation
+ */
+
+
+#ifndef WAIT_H
+#define WAIT_H
+
+#include <ctime>
+
+namespace BASELIB {
+
+void wait(int seconds)
+{
+	time_t start_time, cur_time;
+
+	time(&start_time);
+	do
+	{
+		 time(&cur_time);
+	}
+	while((cur_time - start_time) < seconds);
+}
+
+} // end namespace BASELIB
+
+#endif //WAIT_H
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e1fe3728fbd8441e61335b9a658b5d16e7508dc5..b8b1a10d23c70e82386b9d22317b715c94786eb8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,10 @@ cmake_minimum_required(VERSION 2.6)
 # Project name
 project( OGS-6 )
 
+# Set cmake module path 
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
+
+
 # Set cmake module path 
 #SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeConfiguration")
 
@@ -27,6 +31,7 @@ SET( LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib )
 
 # Add subdirectories with the projects
 ADD_SUBDIRECTORY( Base )
+ADD_SUBDIRECTORY( GeoLib )
 ADD_SUBDIRECTORY( MathLib )
 ADD_SUBDIRECTORY( SimpleTests/MatrixTests )
 ADD_SUBDIRECTORY( SimpleTests/SolverTests )
diff --git a/GeoLib/AxisAlignedBoundingBox.cpp b/GeoLib/AxisAlignedBoundingBox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2049e77f0302188ee8d2273aee72e8c4a6f4ae44
--- /dev/null
+++ b/GeoLib/AxisAlignedBoundingBox.cpp
@@ -0,0 +1,74 @@
+/*
+ * \file AxisAlignedBoundingBox.cpp
+ *
+ *  Created on: April 22, 2010
+ *      Author: TF
+ */
+
+#include <limits>
+#include <cstddef>
+#include <cmath>
+#include "AxisAlignedBoundingBox.h"
+
+namespace GEOLIB {
+
+AABB::AABB ()
+{
+	for (std::size_t k(0); k<3; k++) {
+		_min_pnt[k] = std::numeric_limits<double>::max();
+		_max_pnt[k] = std::numeric_limits<double>::min();
+	}
+}
+
+AABB::AABB ( const std::vector<GEOLIB::Point*> *points )
+{
+	size_t nPoints (points->size());
+	for (size_t i=0; i<nPoints; i++)
+	{
+		this->update((*(*points)[i])[0], (*(*points)[i])[1], (*(*points)[i])[2]);
+	}
+}
+
+void AABB::update (GEOLIB::Point const & pnt)
+{
+	update (pnt[0], pnt[1], pnt[2]);
+}
+
+void AABB::update (double x, double y, double z)
+{
+	if (x < _min_pnt[0]) _min_pnt[0] = x;
+	if (_max_pnt[0] < x) _max_pnt[0] = x;
+	if (y < _min_pnt[1]) _min_pnt[1] = y;
+	if (_max_pnt[1] < y) _max_pnt[1] = y;
+	if (z < _min_pnt[2]) _min_pnt[2] = z;
+	if (_max_pnt[2] < z) _max_pnt[2] = z;
+}
+
+bool AABB::containsPoint (GEOLIB::Point const & pnt, double eps) const
+{
+	return containsPoint (pnt[0], pnt[1], pnt[2], eps);
+}
+
+bool AABB::containsPoint (const double *pnt, double eps) const
+{
+	return containsPoint (pnt[0], pnt[1], pnt[2], eps);
+}
+
+bool AABB::containsPoint (double x, double y, double z, double eps) const
+{
+	if ((_min_pnt[0] <= x && x <= _max_pnt[0])
+			|| std::fabs(_min_pnt[0]-x) < eps
+			|| std::fabs(x - _max_pnt[0]) < eps) {
+		if ((_min_pnt[1] <= y && y <= _max_pnt[1])
+				|| std::fabs(_min_pnt[1]-y) < eps
+				|| std::fabs(y-_max_pnt[1]) < eps) {
+			if ((_min_pnt[2] <= z && z <= _max_pnt[2])
+					|| std::fabs(_min_pnt[2]-z) < eps
+					|| std::fabs(z-_max_pnt[2]) < eps) {
+				return true;
+			} else return false;
+		} else return false;
+	} else return false;
+}
+
+}
diff --git a/GeoLib/AxisAlignedBoundingBox.h b/GeoLib/AxisAlignedBoundingBox.h
new file mode 100644
index 0000000000000000000000000000000000000000..8f457b3007bd308dd566e57541ea068789d238dd
--- /dev/null
+++ b/GeoLib/AxisAlignedBoundingBox.h
@@ -0,0 +1,77 @@
+/*
+ * \file AxisAlignedBoundingBox.h
+ *
+ *  Created on: April 22, 2010
+ *      Author: TF
+ */
+
+#ifndef AXISALIGNEDBOUNDINGBOX_H_
+#define AXISALIGNEDBOUNDINGBOX_H_
+
+#include "Point.h"
+#include <vector>
+#include <limits>
+
+namespace GEOLIB {
+
+/**
+ *
+ * \ingroup GEOLIB
+ *
+ * \brief Class AABB is a bounding box around a given geometric entity
+ * */
+class AABB
+{
+public:
+	/**
+	 * construction of object, initialization the axis aligned bounding box
+	 * */
+	AABB ();
+
+	/**
+	 * construction of object using vector of points
+	 * */
+	AABB ( const std::vector<GEOLIB::Point*> *points );
+
+	void update (GEOLIB::Point const & pnt);
+	/**
+	 * update axis aligned bounding box
+	 */
+	void update (double x, double y, double z);
+
+	/**
+	 * update axis aligned bounding box
+	 */
+	void update (const double *pnt)
+	{
+		update (pnt[0], pnt[1], pnt[2]);
+	}
+
+	/**
+	 * check if point is in the axis aligned bounding box
+	 * (employing containsPoint (double x, double y, double z))
+	 */
+	bool containsPoint (GEOLIB::Point const & pnt, double eps = std::numeric_limits<double>::epsilon()) const;
+
+	/**
+	 * wrapper for GEOLIB::Point
+	 */
+	bool containsPoint (const double *pnt, double eps = std::numeric_limits<double>::epsilon()) const;
+
+	/**
+	 * check if point described by its coordinates x, y, z is in
+	 * the axis aligned bounding box
+	 */
+	bool containsPoint (double x, double y, double z, double eps = std::numeric_limits<double>::epsilon()) const;
+
+	GEOLIB::Point getMinPoint () const { return _min_pnt; }
+	GEOLIB::Point getMaxPoint () const { return _max_pnt; }
+
+private:
+	GEOLIB::Point _min_pnt;
+	GEOLIB::Point _max_pnt;
+};
+
+} // end namespace
+
+#endif /* AXISALIGNEDBOUNDINGBOX_H_ */
diff --git a/GeoLib/BruteForceClosestPair.cpp b/GeoLib/BruteForceClosestPair.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d047edf0e43200706348a65daa946675fca7fdcd
--- /dev/null
+++ b/GeoLib/BruteForceClosestPair.cpp
@@ -0,0 +1,34 @@
+/*
+ * BruteForceClosestPair.cpp
+ *
+ *  Created on: Jan 25, 2011
+ *      Author: TF
+ */
+
+#include "BruteForceClosestPair.h"
+#include "MathTools.h"
+
+namespace GEOLIB {
+
+BruteForceClosestPair::BruteForceClosestPair(
+		std::vector<GEOLIB::Point*> const & pnts, size_t& id0, size_t& id1) :
+	ClosestPair (pnts, id0, id1)
+{
+	double sqr_shortest_dist (MathLib::sqrDist (_pnts[0], _pnts[1]));
+
+	const size_t n_pnts (_pnts.size());
+	for (size_t i(0); i<n_pnts; i++) {
+		for (size_t j(i+1); j<n_pnts; j++) {
+			double sqr_dist (MathLib::sqrDist (_pnts[i], _pnts[j]));
+			if (sqr_dist < sqr_shortest_dist) {
+				sqr_shortest_dist = sqr_dist;
+				_id0 = i;
+				_id1 = j;
+			}
+		}
+	}
+	id0 = _id0;
+	id1 = _id1;
+}
+
+} // end namespace GEOLIB
diff --git a/GeoLib/BruteForceClosestPair.h b/GeoLib/BruteForceClosestPair.h
new file mode 100644
index 0000000000000000000000000000000000000000..8de5d88ff42b581b3d9e668cf2a4dca28ed0a369
--- /dev/null
+++ b/GeoLib/BruteForceClosestPair.h
@@ -0,0 +1,22 @@
+/*
+ * BruteForceClosestPair.h
+ *
+ *  Created on: Jan 25, 2011
+ *      Author: TF
+ */
+
+#ifndef BRUTEFORCECLOSESTPAIR_H_
+#define BRUTEFORCECLOSESTPAIR_H_
+
+#include "ClosestPair.h"
+
+namespace GEOLIB {
+
+class BruteForceClosestPair : public ClosestPair {
+public:
+	BruteForceClosestPair(std::vector<GEOLIB::Point*> const & pnts, size_t& id0, size_t& id1);
+};
+
+} // end namespace GEOLIB
+
+#endif /* BRUTEFORCECLOSESTPAIR_H_ */
diff --git a/GeoLib/CMakeLists.txt b/GeoLib/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c091c532b1448e9038cb5595f4825dffcf67af8d
--- /dev/null
+++ b/GeoLib/CMakeLists.txt
@@ -0,0 +1,71 @@
+# Source files
+set( SOURCES
+	AxisAlignedBoundingBox.cpp
+	BruteForceClosestPair.cpp
+	Color.cpp
+	GEOObjects.cpp
+	GeoType.cpp
+	Point.cpp
+	PointVec.cpp
+	Polygon.cpp
+	Polyline.cpp
+#	ProjectData.cpp # uses CFEMesh class
+#	SimplePolygonTree.cpp # uses FileIO/MeshIO
+	Station.cpp
+	Surface.cpp
+	Triangle.cpp
+	Raster.cpp
+)
+
+# Header files
+set( HEADERS
+	AxisAlignedBoundingBox.h
+	BruteForceClosestPair.h
+	ClosestPair.h
+	Color.h
+	GeoObject.h
+	GEOObjects.h
+	GeoType.h
+	Point.h
+	PointVec.h
+	PointWithID.h
+	Polygon.h
+	Polyline.h
+	PolylineVec.h
+#	ProjectData.h # uses CFEMesh class
+	PropertyBounds.h
+	QuadTree.h
+#	SimplePolygonTree.h # uses FileIO/MeshIO
+	Station.h
+	Surface.h
+	SurfaceVec.h
+	TemplatePoint.h
+	TemplateVec.h
+	Triangle.h
+	Raster.h
+)
+
+# Create the library
+add_library( GEO STATIC
+	${SOURCES}
+	${HEADERS}
+)
+
+
+include_directories(
+	.
+	../Base
+	../FEM
+	../FileIO
+	../MathLib
+	../MSH
+)
+
+
+target_link_libraries (
+	GEO
+	Base
+	FEM
+	MathLib
+)
+
diff --git a/GeoLib/ClosestPair.h b/GeoLib/ClosestPair.h
new file mode 100644
index 0000000000000000000000000000000000000000..d2b1d3af0f6fe6cc01bfd8e9c2947fbcd735d025
--- /dev/null
+++ b/GeoLib/ClosestPair.h
@@ -0,0 +1,34 @@
+/*
+ * ClosestPair.h
+ *
+ *  Created on: Jan 25, 2011
+ *      Author: TF
+ */
+
+#ifndef CLOSESTPAIR_H_
+#define CLOSESTPAIR_H_
+
+// STL
+#include <vector>
+
+// GEOLIB
+#include "Point.h"
+
+namespace GEOLIB {
+
+class ClosestPair
+{
+public:
+	ClosestPair (std::vector<GEOLIB::Point*> const & pnts, size_t id0, size_t id1) :
+		_pnts (pnts), _id0 (id0), _id1 (id1)
+	{}
+
+protected:
+	std::vector<GEOLIB::Point*> const & _pnts;
+	size_t _id0;
+	size_t _id1;
+};
+
+} // end namespace GEOLIB
+
+#endif /* CLOSESTPAIR_H_ */
diff --git a/GeoLib/Color.cpp b/GeoLib/Color.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd54503680e14fb63add54c47b625b56c52a0284
--- /dev/null
+++ b/GeoLib/Color.cpp
@@ -0,0 +1,76 @@
+/*
+ * Color.cpp
+ *
+ *  Created on: Jun 16, 2010
+ *      Author: KR initial implementation in header
+ *      TF moved implementation to separate source file
+ */
+
+#include <iostream>
+#include <sstream>
+
+#include "Color.h"
+#include "StringTools.h"
+
+namespace GEOLIB {
+
+Color* getRandomColor()
+{
+	return new Color((rand()%5)*50, (rand()%5)*50, (rand()%5)*50);
+}
+
+int readColorLookupTable(std::map<std::string, Color*> &colors, const std::string &filename)
+{
+	std::string id = "", line = "";
+
+	std::ifstream in( filename.c_str() );
+
+	if (!in.is_open())
+	{
+		std::cout << "Color::readLookupTable() - Could not open file..."  << std::endl;
+		return 0;
+	}
+
+	while ( getline(in, line) )
+	{
+		std::list<std::string> fields = splitString(line, '\t');
+		Color *c = new Color();
+
+		if (fields.size()>=4)
+		{
+			id = fields.front();
+			fields.pop_front();
+			(*c)[0] = atoi(fields.front().c_str());
+			fields.pop_front();
+			(*c)[1] = atoi(fields.front().c_str());
+			fields.pop_front();
+			(*c)[2] = atoi(fields.front().c_str());
+			colors.insert(std::pair<std::string, Color*>(id, c));
+		}
+		else delete c;
+	}
+
+	return 1;
+}
+
+const Color* getColor(const std::string &id, std::map<std::string, Color*> &colors)
+{
+	for (std::map<std::string, Color*>::const_iterator it=colors.begin(); it !=colors.end(); ++it)
+	{
+		if (id.compare(it->first) == 0)
+			return it->second;
+	}
+	std::cout << "Key \"" << id << "\" not found in color lookup table..." << std::endl;
+	Color* c = getRandomColor();
+	colors.insert(std::pair<std::string, Color*>(id, c));
+	return c;
+}
+
+const Color* getColor(double id, std::map<std::string, GEOLIB::Color*> &colors)
+{
+	std::ostringstream stream;
+	stream << id;
+	return getColor(stream.str(), colors);
+}
+
+}
diff --git a/GeoLib/Color.h b/GeoLib/Color.h
new file mode 100644
index 0000000000000000000000000000000000000000..f2843833f1162a92389051cf3b1abafff81db5da
--- /dev/null
+++ b/GeoLib/Color.h
@@ -0,0 +1,38 @@
+/**
+ * \file Color.cpp
+ * 04/02/2010 KR Initial implementation
+ *
+ */
+
+
+#ifndef COLOR_H_
+#define COLOR_H_
+
+#include "TemplatePoint.h"
+
+#include <fstream>
+#include <cstdlib>
+#include <map>
+#include <list>
+
+namespace GEOLIB {
+
+typedef TemplatePoint<unsigned char> Color;
+
+/// Returns a random RGB colour.
+Color* getRandomColor();
+
+/// Reads a color-lookup-table from a file and writes it to a map.
+int readColorLookupTable(std::map<std::string, GEOLIB::Color*> &colors, const std::string &filename);
+
+/// Uses a color-lookup-table (in form of a map) to return a colour for a specified name. If the name is not
+/// in the colortable a new entry is created with the new name and a random colour.
+const Color* getColor(const std::string &id, std::map<std::string, GEOLIB::Color*> &colors);
+
+/// Convenience function to use the getColor method with numbers as identifiers.
+const Color* getColor(double id, std::map<std::string, GEOLIB::Color*> &colors);
+
+
+} // namespace
+
+#endif /* COLOR_H_ */
diff --git a/GeoLib/GEOObjects.cpp b/GeoLib/GEOObjects.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6fd77f767680992e2de20c2f3adaf51589c8b859
--- /dev/null
+++ b/GeoLib/GEOObjects.cpp
@@ -0,0 +1,435 @@
+/*
+ * GEOObjects.cpp
+ *
+ *  Created on: Jan 21, 2010
+ *      Author: TF / KR
+ */
+
+#include "GEOObjects.h"
+#include "StringTools.h"
+
+#include <fstream>
+
+namespace GEOLIB {
+
+GEOObjects::GEOObjects()
+{
+}
+
+GEOObjects::~GEOObjects()
+{
+	// delete surfaces
+	for (size_t k(0); k < _sfc_vecs.size(); k++) {
+		delete _sfc_vecs[k];
+	}
+	// delete polylines
+	for (size_t k(0); k < _ply_vecs.size(); k++) {
+		delete _ply_vecs[k];
+	}
+	// delete points
+	for (size_t k(0); k < _pnt_vecs.size(); k++) {
+		delete _pnt_vecs[k];
+	}
+}
+
+void GEOObjects::addPointVec(std::vector<Point*> *points, std::string &name, std::map<std::string, size_t>* pnt_id_name_map)
+{
+	isUniquePointVecName(name);
+	_pnt_vecs.push_back(new PointVec(name, points, pnt_id_name_map));
+//	std::cout << "minimal dist between points: " << (_pnt_vecs[_pnt_vecs.size()-1])->getShortestPointDistance () << std::endl;
+}
+
+bool GEOObjects::appendPointVec(std::vector<Point*> const& new_points,
+		std::string const &name, std::vector<size_t>* ids)
+{
+	// search vector
+	size_t idx (0);
+	bool nfound (true);
+	for (idx=0; idx<_pnt_vecs.size() && nfound; idx++) {
+		if ( (_pnt_vecs[idx]->getName()).compare (name) == 0 )
+			nfound = false;
+	}
+
+	if (! nfound) {
+		idx--;
+		size_t n_new_pnts (new_points.size());
+		// append points
+		if (ids) {
+			for (size_t k(0); k<n_new_pnts; k++) {
+				ids->push_back (_pnt_vecs[idx]->push_back (new_points[k]));
+			}
+		} else {
+			for (size_t k(0); k<n_new_pnts; k++) {
+				_pnt_vecs[idx]->push_back (new_points[k]);
+			}
+		}
+		return true;
+	} else return false;
+}
+
+const std::vector<Point*>* GEOObjects::getPointVec(const std::string &name) const
+{
+	size_t size (_pnt_vecs.size());
+	for (size_t i=0; i<size; i++)
+	{
+		if (_pnt_vecs[i]->getName().compare(name)==0)
+			return _pnt_vecs[i]->getVector();
+	}
+	std::cout << "GEOObjects::getPointVec() - No entry found with name \"" << name << "\"." << std::endl;
+	return NULL;
+}
+
+const PointVec* GEOObjects::getPointVecObj(const std::string &name) const
+{
+	size_t size (_pnt_vecs.size());
+	for (size_t i=0; i<size; i++) {
+		if (_pnt_vecs[i]->getName().compare(name)==0)
+			return _pnt_vecs[i];
+	}
+	std::cout << "GEOObjects::getPointVec() - No entry found with name \"" << name << "\"." << std::endl;
+	return NULL;
+}
+
+bool GEOObjects::removePointVec(const std::string &name)
+{
+	if (isPntVecUsed (name)) {
+		std::cout << "GEOObjects::removePointVec() - There are still Polylines or Surfaces depending on these points." << std::endl;
+		return false;
+	}
+
+	for (std::vector<PointVec*>::iterator it(_pnt_vecs.begin());
+		it != _pnt_vecs.end(); it++) {
+		if ((*it)->getName().compare(name)==0) {
+			delete *it;
+			_pnt_vecs.erase(it);
+			return true;
+		}
+	}
+	std::cout << "GEOObjects::removePointVec() - No entry found with name \"" << name << "." << std::endl;
+	return false;
+}
+
+
+void GEOObjects::addStationVec(std::vector<Point*> *stations, std::string &name, const Color* const color)
+{
+	size_t size = stations->size();
+	for (size_t i=0; i<size; i++) static_cast<Station*>((*stations)[i])->setColor(color);
+	isUniquePointVecName(name);
+	_pnt_vecs.push_back(new PointVec(name, stations, NULL, PointVec::STATION));
+}
+
+
+std::vector<Point*> *GEOObjects::filterStationVec(const std::string &name,
+		const std::vector<PropertyBounds> &bounds)
+{
+	for (std::vector<PointVec*>::iterator it(_pnt_vecs.begin());
+			it != _pnt_vecs.end(); it++) {
+		if ((*it)->getName().compare(name) == 0 && (*it)->getType()
+				== PointVec::STATION) {
+			return (*it)->filterStations(bounds);
+		}
+	}
+	std::cout << "GEOObjects:: filterStations() - No entry found with name \""
+			<< name << "." << std::endl;
+	return NULL;
+}
+
+const std::vector<Point*> *GEOObjects::getStationVec(const std::string &name) const
+{
+	for (std::vector<PointVec*>::const_iterator it(_pnt_vecs.begin());
+		it != _pnt_vecs.end(); it++) {
+		if ((*it)->getName().compare(name) == 0 && (*it)->getType()
+				== PointVec::STATION)
+			return (*it)->getVector();
+	}
+	std::cout << "GEOObjects::getStationVec() - No entry found with name \""
+			<< name << "." << std::endl;
+	return NULL;
+}
+
+void GEOObjects::addPolylineVec(std::vector<Polyline*> *lines,
+		const std::string &name, std::map<std::string, size_t>* ply_names)
+{
+	for (std::vector<Polyline*>::iterator it (lines->begin());
+		it != lines->end(); ) {
+		if ((*it)->getNumberOfPoints() < 2) {
+			std::vector<Polyline*>::iterator it_erase (it);
+			it = lines->erase (it_erase);
+		} else it++;
+	}
+
+	if (lines->empty()) return;
+
+	_ply_vecs.push_back(new PolylineVec(name, lines, ply_names));
+}
+
+bool GEOObjects::appendPolylineVec(const std::vector<Polyline*> &polylines, const std::string &name)
+{
+	// search vector
+	size_t idx (0);
+	bool nfound (true);
+	for (idx=0; idx<_ply_vecs.size() && nfound; idx++) {
+		if ( (_ply_vecs[idx]->getName()).compare (name) == 0 ) nfound = false;
+	}
+
+	if (! nfound) {
+		idx--;
+		size_t n_plys (polylines.size());
+		// append lines
+		for (size_t k(0); k<n_plys; k++)
+			_ply_vecs[idx]->push_back (polylines[k]);
+		return true;
+	} else return false;
+}
+
+const std::vector<Polyline*> *GEOObjects::getPolylineVec(const std::string &name) const
+{
+	size_t size (_ply_vecs.size());
+	for (size_t i=0; i<size; i++)
+	{
+		if (_ply_vecs[i]->getName().compare(name)==0)
+			return _ply_vecs[i]->getVector();
+	}
+#ifndef NDEBUG
+	std::cout << "DEB: GEOObjects::getPolylineVec() - No entry found with name \"" << name << "." << std::endl;
+#endif
+	return NULL;
+}
+
+const PolylineVec* GEOObjects::getPolylineVecObj(const std::string &name) const
+{
+	size_t size (_ply_vecs.size());
+	for (size_t i=0; i<size; i++) {
+		if (_ply_vecs[i]->getName().compare(name)==0)
+			return _ply_vecs[i];
+	}
+#ifndef NDEBUG
+	std::cout << "DEB: GEOObjects::getPolylineVec() - No entry found with name \"" << name << "\"." << std::endl;
+#endif
+	return NULL;
+}
+
+bool GEOObjects::removePolylineVec(const std::string &name)
+{
+	for (std::vector<PolylineVec*>::iterator it = _ply_vecs.begin();
+		it != _ply_vecs.end(); ++it)
+	{
+		if ((*it)->getName().compare(name) == 0) {
+			delete *it;
+			_ply_vecs.erase(it);
+			return true;
+		}
+	}
+#ifndef NDEBUG
+	std::cout << "GEOObjects::removePolylineVec() - No entry found with name \""
+			<< name << "\"." << std::endl;
+#endif
+	return false;
+}
+
+void GEOObjects::addSurfaceVec(std::vector<Surface*> *sfc, const std::string &name,
+		std::map<std::string, size_t>* sfc_names)
+{
+	_sfc_vecs.push_back(new SurfaceVec(name, sfc, sfc_names));
+}
+
+bool GEOObjects::appendSurfaceVec(const std::vector<Surface*> &surfaces, const std::string &name)
+{
+	// search vector
+	size_t idx (0);
+	bool nfound (true);
+	for (idx=0; idx<_sfc_vecs.size() && nfound; idx++) {
+		if ( (_sfc_vecs[idx]->getName()).compare (name) == 0 ) nfound = false;
+	}
+
+	if (! nfound) {
+		idx--;
+		size_t n_sfcs (surfaces.size());
+		// append surfaces
+		for (size_t k(0); k<n_sfcs; k++)
+			_sfc_vecs[idx]->push_back (surfaces[k]);
+		return true;
+	} else return false;
+}
+
+const std::vector<Surface*>* GEOObjects::getSurfaceVec(const std::string &name) const
+{
+	size_t size (_sfc_vecs.size());
+	for (size_t i=0; i<size; i++)
+	{
+		if (_sfc_vecs[i]->getName().compare(name)==0)
+			return _sfc_vecs[i]->getVector();
+	}
+	std::cout << "GEOObjects::getSurfaceVec() - No entry found with name \"" << name << "." << std::endl;
+	return NULL;
+}
+
+bool GEOObjects::removeSurfaceVec(const std::string &name)
+{
+	for (std::vector<SurfaceVec*>::iterator it (_sfc_vecs.begin());
+		it != _sfc_vecs.end(); it++) {
+		if ((*it)->getName().compare (name) == 0) {
+			delete *it;
+			_sfc_vecs.erase (it);
+			return true;
+		}
+	}
+#ifndef NDEBUG
+	std::cout << "GEOObjects::removeSurfaceVec() - No entry found with name \""
+			<< name << "\"." << std::endl;
+#endif
+	return false;
+}
+
+const SurfaceVec* GEOObjects::getSurfaceVecObj(const std::string &name) const
+{
+	size_t size (_sfc_vecs.size());
+	for (size_t i=0; i<size; i++) {
+		if (_sfc_vecs[i]->getName().compare(name)==0)
+			return _sfc_vecs[i];
+	}
+	std::cout << "GEOObjects::getSurfaceVec() - No entry found with name \"" << name << "\"." << std::endl;
+	return NULL;
+}
+
+bool GEOObjects::isUniquePointVecName(std::string &name)
+{
+	int count=0;
+	bool isUnique = false;
+	std::string cpName;
+
+	while (!isUnique)
+	{
+		isUnique = true;
+		cpName = name;
+
+		count++;
+		// If the original name already exists we start to add numbers to name for
+		// as long as it takes to make the name unique.
+		if (count>1) cpName = cpName + "-" + number2str(count);
+
+		for (size_t i=0; i<_pnt_vecs.size(); i++)
+		{
+			if ( cpName.compare(_pnt_vecs[i]->getName()) == 0 ) isUnique = false;
+		}
+	}
+
+	// At this point cpName is a unique name and isUnique is true.
+	// If cpName is not the original name, "name" is changed and isUnique is set to false,
+	// indicating that a vector with the original name already exists.
+	if (count>1)
+	{
+		isUnique = false;
+		name = cpName;
+	}
+	return isUnique;
+}
+
+bool GEOObjects::isPntVecUsed (const std::string &name) const
+{
+	// search dependent data structures (Polyline)
+	for (std::vector<PolylineVec*>::const_iterator it ( _ply_vecs.begin());	it != _ply_vecs.end(); it++)
+	{
+		std::string a = (*it)->getName();
+		if (((*it)->getName()).compare(name) == 0)
+			return true;
+	}
+	for (std::vector<SurfaceVec*>::const_iterator it ( _sfc_vecs.begin());	it != _sfc_vecs.end(); it++)
+	{
+		std::string a = (*it)->getName();
+		if (((*it)->getName()).compare(name) == 0)
+			return true;
+	}
+
+	return false;
+
+}
+
+void GEOObjects::getStationNames(std::vector<std::string>& names) const
+{
+	for (std::vector<PointVec*>::const_iterator it(_pnt_vecs.begin());	it != _pnt_vecs.end(); it++) {
+		if ((*it)->getType() == PointVec::STATION)
+			names.push_back((*it)->getName());
+	}
+}
+
+void GEOObjects::getGeometryNames (std::vector<std::string>& names) const
+{
+	names.clear ();
+	for (std::vector<PointVec*>::const_iterator it(_pnt_vecs.begin());	it != _pnt_vecs.end(); it++) {
+		if ((*it)->getType() == PointVec::POINT)
+			names.push_back((*it)->getName());
+	}
+}
+
+void GEOObjects::mergeGeometries (std::vector<std::string> const & geo_names, std::string &merged_geo_name)
+{
+	std::vector<size_t> pnt_offsets(geo_names.size(), 0);
+
+	// *** merge points
+	std::vector<GEOLIB::Point*>* merged_points (new std::vector<GEOLIB::Point*>);
+	for (size_t j(0); j<geo_names.size(); j++) {
+		const std::vector<GEOLIB::Point*>* pnts (this->getPointVec(geo_names[j]));
+		if (pnts) {
+			size_t nPoints(0);
+			// do not consider stations
+			if (dynamic_cast<GEOLIB::Station*>((*pnts)[0]) == NULL) {
+				nPoints = pnts->size();
+				for (size_t k(0); k<nPoints; k++) {
+					merged_points->push_back (new GEOLIB::Point (((*pnts)[k])->getData()));
+				}
+			}
+			if (geo_names.size()-1 > j)
+				pnt_offsets[j+1] = nPoints + pnt_offsets[j];
+		}
+	}
+
+	this->addPointVec (merged_points, merged_geo_name);
+	std::vector<size_t> const& id_map (this->getPointVecObj(merged_geo_name)->getIDMap ());
+
+	// *** merge polylines
+	std::vector<GEOLIB::Polyline*> *merged_polylines (new std::vector<GEOLIB::Polyline*>);
+	for (size_t j(0); j<geo_names.size(); j++) {
+		const std::vector<GEOLIB::Polyline*>* plys (this->getPolylineVec(geo_names[j]));
+		if (plys) {
+			for (size_t k(0); k<plys->size(); k++) {
+				GEOLIB::Polyline* kth_ply_new(new GEOLIB::Polyline (*merged_points));
+				GEOLIB::Polyline const*const kth_ply_old ((*plys)[k]);
+				const size_t size_of_kth_ply (kth_ply_old->getNumberOfPoints());
+				// copy point ids from old ply to new ply (considering the offset)
+				for (size_t i(0); i<size_of_kth_ply; i++) {
+					kth_ply_new->addPoint (id_map[pnt_offsets[j]+kth_ply_old->getPointID(i)]);
+				}
+				merged_polylines->push_back (kth_ply_new);
+			}
+		}
+	}
+	this->addPolylineVec (merged_polylines, merged_geo_name);
+
+
+	// *** merge surfaces
+	std::vector<GEOLIB::Surface*> *merged_sfcs (new std::vector<GEOLIB::Surface*>);
+	for (size_t j(0); j<geo_names.size(); j++) {
+		const std::vector<GEOLIB::Surface*>* sfcs (this->getSurfaceVec(geo_names[j]));
+		if (sfcs) {
+			for (size_t k(0); k<sfcs->size(); k++) {
+				GEOLIB::Surface* kth_sfc_new(new GEOLIB::Surface (*merged_points));
+				GEOLIB::Surface const*const kth_sfc_old ((*sfcs)[k]);
+				const size_t size_of_kth_sfc (kth_sfc_old->getNTriangles());
+				// copy point ids from old ply to new ply (considering the offset)
+				for (size_t i(0); i<size_of_kth_sfc; i++) {
+					const GEOLIB::Triangle* tri ((*kth_sfc_old)[i]);
+					const size_t id0 (id_map[pnt_offsets[j]+(*tri)[0]]);
+					const size_t id1 (id_map[pnt_offsets[j]+(*tri)[1]]);
+					const size_t id2 (id_map[pnt_offsets[j]+(*tri)[2]]);
+					kth_sfc_new->addTriangle (id0, id1, id2);
+				}
+				merged_sfcs->push_back (kth_sfc_new);
+			}
+		}
+	}
+	this->addSurfaceVec (merged_sfcs, merged_geo_name);
+}
+
+
+} // namespace
diff --git a/GeoLib/GEOObjects.h b/GeoLib/GEOObjects.h
new file mode 100644
index 0000000000000000000000000000000000000000..9eae16b0e8771813cb7c88ff0a60f756c15bb30a
--- /dev/null
+++ b/GeoLib/GEOObjects.h
@@ -0,0 +1,232 @@
+/*
+ * GEOObjects.h
+ *
+ *  Created on: Jan 21, 2010
+ *      Author: TF / KR
+ */
+
+#ifndef GEOOBJECTS_H_
+#define GEOOBJECTS_H_
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include "PointVec.h"
+#include "Point.h"
+#include "PolylineVec.h"
+#include "Polyline.h"
+#include "SurfaceVec.h"
+#include "Surface.h"
+
+#include "Color.h"
+#include "Station.h"
+
+namespace GEOLIB {
+
+///
+/**
+ * \defgroup GEOLIB This module consists of classes governing geometric objects
+ * and related algorithms.
+ */
+
+/**
+ * \brief Container class for geometric objects.
+ *
+ * This class contains all the methods necessary for the I/O of geometric objects.
+ * Said objects are Points, polylines, Surfaces and Stations and they are stored in
+ * vectors (arrays) which are identified by a unique name.
+ * For a hierarchical definition, surfaces are bounded by polylines and polylines
+ * are defined by points. Therefore, a vector of surfaces references a vector polylines
+ * and a vector of polylines references a vector of points, respectively. For
+ * identification purposes, all of these vectors have the same name, i.e. the polyline-
+ * vector named "aaa" references a point vector "aaa". However, this name ("aaa") is
+ * unique among all the vectors of the same class, i.e. there exists only one point-
+ * vector with this name, etc.
+ * Note: The fact that vectors are uniquely named and the same name is assigned to
+ * related objects is automatically handled by this class.
+ *
+ * For each of these object-classes exists an "add", "remove" and "get"-method which
+ * allows for loading/unloading as well as accessing the data, respectively.
+ * E.g. for points these methods are "addPointVec(name)", "getPointVec(name)" and
+ * "removePointVec(name)". For some objects, additional methods might exist if
+ * necessary.
+ */
+class GEOObjects {
+public:
+	/**
+	 * Adds a vector of points with the given name to GEOObjects.
+	 * @param points vector of pointers to points
+	 * @param name the project name
+	 * @param pnt_names vector of the names corresponding to the points
+	 */
+	virtual void addPointVec(std::vector<Point*> *points, std::string &name, std::map<std::string, size_t>* pnt_names = NULL);
+
+	/** copies the pointers to the points in the vector to the PointVec with provided name.
+	 * the pointers are managed by the GEOObjects, i.e. GEOObjects will delete the Points at the
+	 * end of its scope
+	 * \param points the vector with points
+	 * \param name the name of the internal PointVec
+	 * \param ids On return the vector holds the ids of the inserted points within the internal vector.
+	 * In case the ids are not needed it is possible to give a NULL pointer (default value).
+	 * \return true if the points are appended, false if the a PointVec with the
+	 * corresponding name does not exist
+	 * */
+	virtual bool appendPointVec(const std::vector<Point*> &points,
+			std::string const &name, std::vector<size_t>* ids = NULL);
+
+	/**
+	 * Returns the point vector with the given name.
+	 */
+	const std::vector<Point*> *getPointVec(const std::string &name) const;
+
+	/**
+	 * search and returns the PointVec object with the given name.
+	 * @param name the name of the PointVec object
+	 * @return the PointVec object stored in GEOObjects
+	 */
+	const PointVec* getPointVecObj(const std::string &name) const;
+
+	/** If there exists no dependencies the point vector with the given
+	 * name from GEOObjects will be removed and the method returns true,
+	 * else the return value is false.
+	 */
+	virtual bool removePointVec(const std::string &name);
+
+	/// Adds a vector of stations with the given name and colour to GEOObjects.
+	virtual void addStationVec(std::vector<Point*> *stations, std::string &name,
+			const Color* const color);
+	/// Filters a list of stations with the given name based on the criteria in PropertyBounds.
+	/// (See property system in Station class for more information.)
+	std::vector<Point*> *filterStationVec(const std::string &name,
+			const std::vector<PropertyBounds> &bounds);
+	/// Returns the station vector with the given name.
+	const std::vector<Point*> *getStationVec(const std::string &name) const;
+
+	/// Removes the station vector with the given name from GEOObjects
+	virtual bool removeStationVec(const std::string &name) {
+		return removePointVec(name);
+	}
+
+
+	/**
+	 * Adds a vector of polylines with the given name to GEOObjects.
+	 * @param lines The lines vector.
+	 * @param name The given name.
+	 * @param ply_names vector of the names corresponding to the polylines
+	*/
+	virtual void addPolylineVec(std::vector<Polyline*> *lines,
+			const std::string &name, std::map<std::string,size_t>* ply_names = NULL);
+
+	/** copies the pointers to the polylines in the vector to the PolylineVec with provided name.
+	 * the pointers are managed by the GEOObjects, i.e. GEOObjects will delete the Polylines at the
+	 * end of its scope
+	 * \param polylines the vector with polylines
+	 * \param name the name of the internal PolylineVec
+	 * \return true if the polylines are appended, false if the PolylineVec with the
+	 * corresponding name does not exist
+	 * */
+	virtual bool appendPolylineVec(const std::vector<Polyline*> &polylines,
+			const std::string &name);
+
+	/**
+	 * Returns the polyline vector with the given name.
+	 * */
+	const std::vector<Polyline*> *getPolylineVec(const std::string &name) const;
+
+	/**
+	 * Returns a pointer to a PolylineVec object for the given name as a const.
+	 * @param name the name of the vector of polylines
+	 * @return PolylineVec object
+	 */
+	const PolylineVec* getPolylineVecObj(const std::string &name) const;
+
+	/// Returns a pointer to a PolylineVec object for the given name.
+	PolylineVec* getPolylineVecObj(const std::string &name) {
+		return const_cast<PolylineVec*>(static_cast<const GEOObjects&>(*this).getPolylineVecObj(name));
+	};
+
+	/**
+	 * If no Surfaces depends on the vector of Polylines with the given
+	 * name it will be removed and the method returns true,
+	 * else the return value is false.
+	 */
+	virtual bool removePolylineVec(const std::string &name);
+
+	/** Adds a vector of surfaces with the given name to GEOObjects. */
+	virtual void addSurfaceVec(std::vector<Surface*> *surfaces,
+			const std::string &name, std::map<std::string, size_t>* sfc_names = NULL);
+
+	/**
+	 * Copies the surfaces in the vector to the SurfaceVec with the given name.
+	 * \param surfaces the vector with surfaces
+	 * \param name the name of the internal PolylineVec
+	 * \return true if the surfaces are appended, false if the SurfaceVec with the
+	 * corresponding name does not exist
+	 * */
+	virtual bool appendSurfaceVec(const std::vector<Surface*> &surfaces,
+			const std::string &name);
+
+	/// Returns the surface vector with the given name as a const.
+	const std::vector<Surface*> *getSurfaceVec(const std::string &name) const;
+
+	/// Returns the surface vector with the given name.
+	SurfaceVec* getSurfaceVecObj(const std::string &name) {
+		return const_cast<SurfaceVec*>(static_cast<const GEOObjects&>(*this).getSurfaceVecObj(name));
+	};
+
+	/** removes the vector of Surfaces with the given name */
+	virtual bool removeSurfaceVec(const std::string &name);
+	/**
+	 * Returns a pointer to a SurfaceVec object for the given name. The class
+	 * SurfaceVec stores the relation between surfaces and the names of the surfaces.
+	 * @param name the name of the vector of surfaces (the project name)
+	 * @return SurfaceVec object
+	 */
+	const SurfaceVec* getSurfaceVecObj(const std::string &name) const;
+
+	/// Returns the names of all geometry vectors.
+	void getGeometryNames (std::vector<std::string>& names) const;
+
+	/// Returns the names of all station vectors.
+	void getStationNames(std::vector<std::string>& names) const;
+
+	/**
+	 * merge geometries
+	 * @param names the names of the geometries that are to be merged
+	 * @param merged_geo_name the name of the resulting geometry
+	 */
+	void mergeGeometries (std::vector<std::string> const & names, std::string &merged_geo_name);
+
+	/** constructor */
+	GEOObjects();
+	/** destructor */
+	virtual ~GEOObjects();
+
+protected:
+	/**
+	 * Determines if the given name is unique among all the names in point vectors and creates a
+	 * new name if this is not the case. The new name is then simply "name + x", where x>1 is
+	 * the smallest number that creates a unique name (i.e. "name-2", "name-3", etc.)
+	 * \param name Original name of the list, this name might be changed within this method if necessary.
+	 * \return true if the name was unique, false if a new name has been generated
+	 */
+	bool isUniquePointVecName(std::string &name);
+
+	/// Checks if the point vector with the given name is referenced in a polyline- or surface vector.
+	bool isPntVecUsed (const std::string &name) const;
+
+	/**
+	 * vector manages pointers to PointVec objects
+	 */
+	std::vector<PointVec*> _pnt_vecs;
+
+	/** vector manages pointers to PolylineVec objects */
+	std::vector<PolylineVec*> _ply_vecs;
+	/** vector manages pointers to SurfaceVec objects */
+	std::vector<SurfaceVec*> _sfc_vecs;
+};
+
+} // end namespace
+
+#endif /* GEOOBJECTS_H_ */
diff --git a/GeoLib/GeoObject.h b/GeoLib/GeoObject.h
new file mode 100644
index 0000000000000000000000000000000000000000..d3bc2fbb5273f9677f92f150c18875b85e23054e
--- /dev/null
+++ b/GeoLib/GeoObject.h
@@ -0,0 +1,27 @@
+/*
+ * GeoObject.h
+ *
+ *  Created on: Aug 27, 2010
+ *      Author: TF
+ */
+
+#ifndef GEOOBJECT_H_
+#define GEOOBJECT_H_
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ *
+ * \brief Base class for classes Point, Polyline, Surface.
+ */
+
+class GeoObject {
+public:
+	GeoObject() {};
+	virtual ~GeoObject() {};
+};
+
+} // end namespace GEOLIB
+
+#endif /* GEOOBJECT_H_ */
diff --git a/GeoLib/GeoType.cpp b/GeoLib/GeoType.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..79a13cb251ef5f658723f4a4a84fac4ef1558534
--- /dev/null
+++ b/GeoLib/GeoType.cpp
@@ -0,0 +1,32 @@
+/*
+ * GeoType.cpp
+ *
+ *  Created on: Dec 1, 2010
+ *      Author: TF
+ */
+
+#include "GeoType.h"
+
+namespace GEOLIB {
+
+GEOTYPE convertGeoType (const std::string& geo_type_str)
+{
+	if (geo_type_str.compare ("POINT") == 0) return POINT;
+	if (geo_type_str.compare ("POLYLINE") == 0) return POLYLINE;
+	if (geo_type_str.compare ("SURFACE") == 0) return SURFACE;
+	if (geo_type_str.compare ("VOLUME") == 0) return VOLUME;
+	if (geo_type_str.compare ("GEODOMAIN") == 0) return GEODOMAIN;
+	return INVALID;
+}
+
+std::string convertGeoTypeToString (GEOTYPE geo_type)
+{
+	if (geo_type == POINT) return "POINT";
+	if (geo_type == POLYLINE) return "POLYLINE";
+	if (geo_type == SURFACE) return "SURFACE";
+	if (geo_type == VOLUME) return "VOLUME";
+	if (geo_type == GEODOMAIN) return "GEODOMAIN";
+	return "INVALID";
+}
+
+} // end namespace GEOLIB
diff --git a/GeoLib/GeoType.h b/GeoLib/GeoType.h
new file mode 100644
index 0000000000000000000000000000000000000000..6f7f2bb7cddfe08673367287dcc4da135ec3f2aa
--- /dev/null
+++ b/GeoLib/GeoType.h
@@ -0,0 +1,35 @@
+/*
+ * GeoType.h
+ *
+ *  Created on: Jun 17, 2010
+ *      Author: TF
+ */
+
+#ifndef GEOTYPE_H_
+#define GEOTYPE_H_
+
+#include <string>
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ */
+
+enum GEOTYPE {
+	INVALID = 0,
+	POINT,     //!< POINT
+	POLYLINE,  //!< POLYLINE
+	SURFACE,   //!< SURFACE
+	VOLUME,    //!< VOLUME
+	GEODOMAIN, //!< GEODOMAIN
+	COLUMN     //!< COLUMN. //WW/JOD 
+};
+
+GEOTYPE convertGeoType (const std::string& geo_type_str);
+
+std::string convertGeoTypeToString (GEOTYPE geo_type);
+
+} // end namespace GEOLIB
+
+#endif /* GEOTYPE_H_ */
diff --git a/GeoLib/Point.cpp b/GeoLib/Point.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ebe2072d237066eb9cffee96ca55c0190d28675
--- /dev/null
+++ b/GeoLib/Point.cpp
@@ -0,0 +1,55 @@
+/*
+ * Point.cpp
+ *
+ *  Created on: Jun 22, 2010
+ *      Author: TF
+ */
+
+
+#include <cmath>
+#include <limits>
+
+#include "Point.h"
+
+bool operator<= (const GEOLIB::Point& p0, const GEOLIB::Point& p1)
+{
+	double tol (sqrt (std::numeric_limits<double>::min()));
+
+	if (fabs (p0[0]-p1[0]) > tol * fabs(p0[0])) {
+		if (p0[0] < p1[0]) return true;
+		else return false;
+	} else {
+		// assume p0[0] == p1[0]
+		if (fabs (p0[1]-p1[1]) > tol * fabs(p0[1])) {
+			if (p0[1] < p1[1]) return true;
+			else return false;
+		} else {
+			// assume p0[1] == p1[1] and p0[0] == p1[0]
+			if (p0[2] < p1[2]) return true;
+			else return false;
+		}
+	}
+}
+
+namespace GEOLIB {
+
+bool lessX (GEOLIB::Point const & p0, GEOLIB::Point const & p1)
+{
+	if (p0[0] <= p1[0]) return true;
+	return false;
+}
+
+bool lessY (GEOLIB::Point const & p0, GEOLIB::Point const & p1)
+{
+	if (p0[1] <= p1[1]) return true;
+	return false;
+}
+
+bool lessZ (GEOLIB::Point const & p0, GEOLIB::Point const & p1)
+{
+	if (p0[2] <= p1[2]) return true;
+	return false;
+}
+
+
+} // end namespace GEOLIB
diff --git a/GeoLib/Point.h b/GeoLib/Point.h
new file mode 100644
index 0000000000000000000000000000000000000000..a89a7e7d12be10c30f4687feecd25f70a27bf308
--- /dev/null
+++ b/GeoLib/Point.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ *  Point.h
+ *  Created on: Jan 12, 2010
+ *      Author: TF
+**************************************************************************/
+
+#ifndef POINT_H_
+#define POINT_H_
+
+#include "TemplatePoint.h"
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ */
+
+typedef TemplatePoint<double> Point;
+
+/**
+ * comparison based on the x coordinate
+ * @param p0 first point
+ * @param p1 second point
+ * @return true if the x coordinate of p0 is smaller equal the x coordinate of p1, else false
+ */
+bool lessX (Point const & p0, Point const & p1);
+
+/**
+ * comparison based on the y coordinate
+ * @param p0 first point
+ * @param p1 second point
+ * @return true if the y coordinate of p0 is smaller equal the y coordinate of p1, else false
+ */
+bool lessY (Point const & p0, Point const & p1);
+
+/**
+ * comparison based on the z coordinate
+ * @param p0 first point
+ * @param p1 second point
+ * @return true if the z coordinate of p0 is smaller equal the z coordinate of p1, else false
+ */
+bool lessZ (Point const & p0, Point const & p1);
+
+}
+
+/**
+ * lexicographic comparison of points
+ */
+bool operator<= (GEOLIB::Point const & p0, GEOLIB::Point const & p1);
+
+#endif /* POINT_H_ */
diff --git a/GeoLib/PointVec.cpp b/GeoLib/PointVec.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f59f637ccfbfe369018f1597a0658788b723d575
--- /dev/null
+++ b/GeoLib/PointVec.cpp
@@ -0,0 +1,258 @@
+/*
+ * PointVec.cpp
+ *
+ *  Created on: Jun 11, 2010
+ *      Author: TF
+ */
+
+#include "PointVec.h"
+#include "BruteForceClosestPair.h"
+
+namespace GEOLIB {
+
+PointVec::PointVec (const std::string& name, std::vector<Point*>* points,
+		std::map<std::string, size_t>* name_id_map, PointType type) :
+			_pnt_vec (points), _name_id_map (name_id_map), _type(type), _name (name),
+			_sqr_shortest_dist (std::numeric_limits<double>::max())
+{
+	assert (_pnt_vec);
+	size_t number_of_all_input_pnts (_pnt_vec->size());
+
+	makePntsUnique (_pnt_vec, _pnt_id_map);
+
+	if (number_of_all_input_pnts - _pnt_vec->size() > 0)
+		std::cerr << "WARNING: there are " << number_of_all_input_pnts - _pnt_vec->size() << " double points" << std::endl;
+//	calculateShortestDistance ();
+	calculateAxisAlignedBoundingBox ();
+}
+
+PointVec::~PointVec ()
+{
+	for (size_t k(0); k<_pnt_vec->size(); k++) {
+		delete (*_pnt_vec)[k];
+		(*_pnt_vec)[k] = NULL;
+	}
+	delete _pnt_vec;
+	delete _name_id_map;
+}
+
+size_t PointVec::push_back (Point *pnt)
+{
+	_pnt_id_map.push_back (uniqueInsert(pnt));
+	return _pnt_id_map[_pnt_id_map.size()-1];
+}
+
+void PointVec::push_back (Point *pnt, const std::string& name)
+{
+	std::map<std::string,size_t>::const_iterator it (_name_id_map->find (name));
+	if (it != _name_id_map->end()) {
+		std::cerr << "ERROR: PointVec::push_back (): two points with the same name" << std::endl;
+		return;
+	}
+
+	size_t id (uniqueInsert (pnt));
+	_pnt_id_map.push_back (id);
+	(*_name_id_map)[name] = id;
+}
+
+size_t PointVec::uniqueInsert (Point* pnt)
+{
+	size_t n (_pnt_vec->size()), k;
+	const double eps (std::numeric_limits<double>::epsilon());
+	for (k=0; k<n; k++) {
+		if (fabs((*((*_pnt_vec)[k]))[0]-(*pnt)[0]) < eps
+				&&  fabs( (*((*_pnt_vec)[k]))[1]-(*pnt)[1]) < eps
+				&&  fabs( (*((*_pnt_vec)[k]))[2]-(*pnt)[2]) < eps) {
+			break;
+		}
+	}
+
+	if(k==n) {
+		_pnt_vec->push_back (pnt);
+		// update shortest distance and bounding box
+		for (size_t i(0); i<n; i++) {
+			double sqr_dist (MathLib::sqrDist((*_pnt_vec)[i], (*_pnt_vec)[n]));
+			if (sqr_dist < _sqr_shortest_dist)
+				_sqr_shortest_dist = sqr_dist;
+			aabb.update (*((*_pnt_vec)[n]));
+		}
+		return n;
+	}
+
+	delete pnt;
+	pnt = NULL;
+	return k;
+}
+
+std::vector<Point*> * PointVec::filterStations(const std::vector<PropertyBounds> &bounds) const
+{
+	std::vector<Point*> *tmpStations (new std::vector<Point*>);
+	size_t size (_pnt_vec->size());
+	for (size_t i=0; i<size; i++) {
+		if (static_cast<Station*>((*_pnt_vec)[i])->inSelection(bounds)) tmpStations->push_back((*_pnt_vec)[i]);
+	}
+	return tmpStations;
+}
+
+bool PointVec::getElementIDByName (const std::string& name, size_t &id) const
+{
+	std::map<std::string,size_t>::const_iterator it (_name_id_map->find (name));
+
+	if (it != _name_id_map->end()) {
+		id = it->second;
+		return true;
+	} else return false;
+}
+
+const Point* PointVec::getElementByName (const std::string& name) const
+{
+	size_t id;
+	bool ret (getElementIDByName (name, id));
+	if (ret) {
+		return (*_pnt_vec)[id];
+	} else {
+		return NULL;
+	}
+}
+
+bool PointVec::getNameOfElement (const Point* data, std::string& name) const
+{
+	for (size_t k(0); k<_pnt_vec->size(); k++) {
+		if ((*_pnt_vec)[k] == data) {
+			return getNameOfElementByID (k, name);
+		}
+	}
+	return false;
+}
+
+bool PointVec::getNameOfElementByID (size_t id, std::string& element_name) const
+{
+	if (! _name_id_map) return false;
+	// search in map for id
+	std::map<std::string,size_t>::const_iterator it (_name_id_map->begin());
+	while (it != _name_id_map->end()) {
+		if (it->second == id) {
+			element_name = it->first;
+			return true;
+		}
+		it++;
+	}
+	return false;
+}
+
+double PointVec::getShortestPointDistance () const
+{
+	return sqrt (_sqr_shortest_dist);
+}
+
+void PointVec::makePntsUnique (std::vector<GEOLIB::Point*>* pnt_vec, std::vector<size_t> &pnt_id_map)
+{
+	size_t n_pnts_in_file (pnt_vec->size());
+	std::vector<size_t> perm;
+	pnt_id_map.reserve (n_pnts_in_file);
+	for (size_t k(0); k<n_pnts_in_file; k++) {
+		perm.push_back (k);
+		pnt_id_map.push_back(k);
+	}
+
+	// sort the points
+	Quicksort<GEOLIB::Point*> (*pnt_vec, 0, n_pnts_in_file, perm);
+
+	// unfortunately quicksort is not stable -
+	// sort identical points by id - to make sorting stable
+	double eps (sqrt(std::numeric_limits<double>::min()));
+	// determine intervals with identical points to resort for stability of sorting
+	std::vector<size_t> identical_pnts_interval;
+	bool identical (false);
+	for (size_t k=0; k<n_pnts_in_file-1; k++) {
+		if ( fabs((*((*pnt_vec)[k+1]))[0]-(*((*pnt_vec)[k]))[0]) < eps
+			&&  fabs( (*((*pnt_vec)[k+1]))[1]-(*((*pnt_vec)[k]))[1]) < eps
+			&&  fabs( (*((*pnt_vec)[k+1]))[2]-(*((*pnt_vec)[k]))[2]) < eps) {
+			// points are identical, sort by id
+			if (!identical) identical_pnts_interval.push_back (k);
+			identical = true;
+		} else {
+			if (identical) identical_pnts_interval.push_back (k+1);
+			identical = false;
+		}
+	}
+	if (identical) identical_pnts_interval.push_back (n_pnts_in_file);
+
+	for (size_t i(0); i<identical_pnts_interval.size()/2; i++) {
+		// bubble sort by id
+		size_t beg (identical_pnts_interval[2*i]);
+		size_t end (identical_pnts_interval[2*i+1]);
+		for (size_t j (beg); j<end; j++) {
+			for (size_t k (beg); k<end-1; k++) {
+				if (perm[k] > perm[k+1]) std::swap (perm[k], perm[k+1]);
+			}
+		}
+	}
+
+	// check if there are identical points
+	for (size_t k=0; k<n_pnts_in_file-1; k++) {
+		if ( fabs((*((*pnt_vec)[k+1]))[0]-(*((*pnt_vec)[k]))[0]) < eps
+				&&  fabs( (*((*pnt_vec)[k+1]))[1]-(*((*pnt_vec)[k]))[1]) < eps
+				&&  fabs( (*((*pnt_vec)[k+1]))[2]-(*((*pnt_vec)[k]))[2]) < eps) {
+			pnt_id_map[perm[k+1]] = pnt_id_map[perm[k]];
+		}
+	}
+
+	// reverse permutation
+	Quicksort<GEOLIB::Point*> (perm, 0, n_pnts_in_file, *pnt_vec);
+
+	// remove the second, third, ... occurrence from vector
+	for (size_t k(0); k<n_pnts_in_file; k++) {
+		if (pnt_id_map[k] < k) {
+			delete (*pnt_vec)[k];
+			(*pnt_vec)[k] = NULL;
+		}
+	}
+	// remove NULL-ptr from vector
+	for (std::vector<GEOLIB::Point*>::iterator it(pnt_vec->begin()); it != pnt_vec->end(); ) {
+		if (*it == NULL) {
+			it = pnt_vec->erase (it);
+		}
+		else it++;
+	}
+
+	// renumber id-mapping
+	size_t cnt (0);
+	for (size_t k(0); k<n_pnts_in_file; k++) {
+		if (pnt_id_map[k] == k) { // point not removed, if necessary: id change
+			pnt_id_map[k] = cnt;
+			cnt++;
+		} else {
+			pnt_id_map[k] = pnt_id_map[pnt_id_map[k]];
+		}
+	}
+
+	// KR correct renumbering of indices
+//	size_t cnt(0);
+//	std::map<size_t, size_t> reg_ids;
+//	for (size_t k(0); k < n_pnts_in_file; k++) {
+//		if (pnt_id_map[k] == k) {
+//			reg_ids.insert(std::pair<size_t, size_t>(k, cnt));
+//			cnt++;
+//		} else reg_ids.insert(std::pair<size_t, size_t>(k, reg_ids[pnt_id_map[k]]));
+//	}
+//	for (size_t k(0); k < n_pnts_in_file; k++)
+//		pnt_id_map[k] = reg_ids[k];
+}
+
+void PointVec::calculateShortestDistance ()
+{
+	size_t i, j;
+	BruteForceClosestPair (*_pnt_vec, i, j);
+	_sqr_shortest_dist = MathLib::sqrDist ((*_pnt_vec)[i], (*_pnt_vec)[j]);
+}
+
+void PointVec::calculateAxisAlignedBoundingBox ()
+{
+	const size_t n_pnts (_pnt_vec->size());
+	for (size_t i(0); i<n_pnts; i++) {
+		aabb.update (*(*_pnt_vec)[i]);
+	}
+}
+
+} // end namespace
diff --git a/GeoLib/PointVec.h b/GeoLib/PointVec.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa54cd5bf3db505c6abd8fcfebc425c7b57de193
--- /dev/null
+++ b/GeoLib/PointVec.h
@@ -0,0 +1,200 @@
+/*
+ * \file PointVec.h
+ *
+ *  Created on: Feb 2, 2010
+ *      Author: TF / KR
+ */
+
+
+// GEOLIB
+#include "Point.h"
+#include "Station.h"
+#include "AxisAlignedBoundingBox.h"
+
+// Base
+#include "quicksort.h"
+#include "binarySearch.h"
+
+#include <vector>
+#include <string>
+#include <map>
+
+#ifndef POINTVEC_H_
+#define POINTVEC_H_
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ *
+ * \brief This class manages pointers to Points in a std::vector along with a name.
+ * It also handles the deleting of points. Additionally, each vector of points is identified by
+ * a unique name from class GEOObject. For this reason PointVec should have
+ * a name.
+ * */
+class PointVec
+{
+public:
+	/// Signals if the vector contains object of type Point or Station
+	enum PointType
+	{
+		POINT    = 0,
+		STATION  = 1
+	};
+
+	/**
+	 * Constructor initializes the name of the PointVec object,
+	 * the internal pointer _pnt_vec to the raw points and the internal
+	 * pointer the vector of names of the points
+	 * and sets the type of PointVec.
+	 * @param name the name of the point group
+	 * @param points pointer to a vector of GEOLIB::Pointers -
+	 * PointVec will take the ownership of the vector,
+	 * i.e. delete the points and the vector itself
+	 * @param name_id_map the names to the points -
+	 * PointVec will take the ownership of the vector, i.e. it
+	 * deletes the names
+	 * @param type the type of the point, \sa enum PointType
+	 * @return an object of type PointVec
+	 */
+	PointVec (const std::string& name, std::vector<Point*>* points, std::map<std::string, size_t>* name_id_map = NULL,
+				PointType type = PointVec::POINT);
+
+	/** Destructor deletes all Points of this PointVec. */
+	~PointVec ();
+
+	/**
+	 * Method adds a Point to the (internal) standard vector and takes the ownership.
+	 * If the given point is already included in the vector, the point will be destroyed and
+	 * the id of the existing point will be returned.
+	 * @param pnt the pointer to the Point
+	 * @return the id of the point within the internal vector
+	 */
+	size_t push_back (Point *pnt);
+
+	/**
+	 * push_back adds new elements at the end of the vector _pnt_vec.
+	 * @param pnt a pointer to the point, PointVec takes ownership of the point
+	 * @param name the name of the point
+	 */
+	void push_back (Point *pnt, const std::string& name);
+
+	/**
+	 * get the actual number of Points
+	 */
+	size_t size () const { return _pnt_vec->size(); }
+	/**
+	 * get the type of Point, this can be either POINT or STATION
+	 *
+	 */
+	PointType getType() const { return _type; }
+
+	/**
+	 * getVector returns the internal vector of Points,
+	 * you are not able to change the Points or the address of the vector.
+	 */
+	const std::vector<Point*>* getVector () const { return _pnt_vec; }
+
+	std::vector<Point*> *filterStations(const std::vector<PropertyBounds> &bounds) const;
+
+	/** sets the name of the object
+	 * \param n the name as standard string */
+	void setName(const std::string & n) { _name = n; }
+	/** returns the name of the object */
+	std::string getName () const { return _name; }
+
+	/**
+	 * search the vector of names for the ID of the point with the given name
+	 * @param name the name of the point
+	 * @param id the id of the point
+	 * @return the id of the point
+	 */
+	bool getElementIDByName (const std::string& name, size_t &id) const;
+
+	/**
+	 * Method searchs for point with the given name. If it found a point with the name
+	 * it returns a pointer to the point, else it returns the NULL pointer.
+	 * @param name the name of the point
+	 * @return the pointer to the point or NULL
+	 */
+	const Point* getElementByName (const std::string& name) const;
+
+	/**
+	 * The method returns true if the given element of type T
+	 * can be found and the element has a name, else method returns false.
+	 * @param data the data element, one wants to know the name
+	 * @param name the name of the data element (if the data element is
+	 * found and the data element has a name)
+	 * @return if element is found and has a name: true, else false
+	 */
+	bool getNameOfElement (const Point* data, std::string& name) const;
+
+	/**
+	 * The method returns true if there is a name associated
+	 * with the given id, else method returns false.
+	 * @param id the id
+	 * @param element_name if a name associated with the id
+	 * is found name is assigned to element_name
+	 * @return if there is name associated with the given id:
+	 * true, else false
+	 */
+	bool getNameOfElementByID (size_t id, std::string& element_name) const;
+
+	const std::vector<size_t>& getIDMap () const { return _pnt_id_map; }
+
+	double getShortestPointDistance () const;
+	const GEOLIB::AABB& getAxisAlignedBoundingBox () const;
+
+private:
+	void makePntsUnique (std::vector<GEOLIB::Point*>* pnt_vec, std::vector<size_t> &pnt_id_map);
+
+	/** copy constructor doesn't have an implementation */
+	// compiler does not create a (possible unwanted) copy constructor
+	PointVec (const PointVec &);
+	/** standard constructor doesn't have an implementation */
+	// compiler does not create a (possible unwanted) standard constructor
+	PointVec ();
+
+	/** assignment operator doesn't have an implementation */
+	// this way the compiler does not create a (possible unwanted) assignment operator
+	PointVec& operator= (const PointVec& rhs);
+
+	size_t uniqueInsert (Point *pnt);
+
+	/**
+	 * pointer to a vector of pointers to Points
+	 *
+	 * The destructor of PointVec will delete all GEOLIB::Points
+	 * inside the vector.
+	 */
+	std::vector<Point*> *_pnt_vec;
+	/**
+	 * used to store the name associated with a point
+	 */
+	std::map<std::string, size_t>* _name_id_map;
+	/** the type of the point (\sa enum PointType) */
+	PointType _type;
+	/** the name of the object */
+	std::string _name;
+	/**
+	 * permutation of the geometric elements according
+	 * to their lexicographical order
+	 */
+	std::vector<size_t> _pnt_id_map;
+
+	/**
+	 * method calculates the shortest distance of points inside the _pnt_vec
+	 */
+	void calculateShortestDistance ();
+	/**
+	 * squared shortest distance - calculated by calculateShortestAndLargestDistance, possible update by uniqueInsert
+	 */
+	double _sqr_shortest_dist;
+
+	void calculateAxisAlignedBoundingBox ();
+	AABB aabb;
+};
+
+} // end namespace
+
+#endif /* POINTVEC_H_ */
diff --git a/GeoLib/PointWithID.h b/GeoLib/PointWithID.h
new file mode 100644
index 0000000000000000000000000000000000000000..530830411f7b10e24b49c42c7af797b54cb8a5f7
--- /dev/null
+++ b/GeoLib/PointWithID.h
@@ -0,0 +1,37 @@
+/*
+ * PointWithID.h
+ *
+ *  Created on: Jan 25, 2011
+ *      Author: TF
+ */
+
+#ifndef POINTWITHID_H_
+#define POINTWITHID_H_
+
+#include "Point.h"
+
+namespace GEOLIB {
+/**
+ * class PointWithID is derived from class Point in
+ * order to extend the class Point with an ID.
+ */
+class PointWithID : public Point
+{
+public:
+	PointWithID (double x0, double x1, double x2, size_t id) :
+		Point (x0, x1, x2), _id (id)
+	{}
+
+	PointWithID (double const*const coords, size_t id) :
+		Point (coords), _id (id)
+	{}
+
+
+	size_t getID () const { return _id; }
+
+protected:
+	size_t _id;
+};
+} // end namespace GEOLIB
+
+#endif /* POINTWITHID_H_ */
diff --git a/GeoLib/Polygon.cpp b/GeoLib/Polygon.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..90e79664ba1ad33ad82171b0100a26eda0ba581c
--- /dev/null
+++ b/GeoLib/Polygon.cpp
@@ -0,0 +1,400 @@
+/*
+ * Polygon.cpp
+ *
+ *  Created on: Jun 21, 2010
+ *      Author: TF
+ */
+
+#include <cstdlib> // for exit
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#include "Polygon.h"
+
+// MathLib
+#include "AnalyticalGeometry.h"
+#include "MathTools.h"
+#include "Vector3.h"
+
+// Base
+#include "quicksort.h"
+#include "swap.h"
+
+namespace GEOLIB {
+
+Polygon::Polygon(const Polyline &ply, bool init) :
+	Polyline (ply)
+{
+	if (init) {
+		initialise ();
+	}
+}
+
+Polygon::Polygon (const std::vector<Point*>& pnt_vec) :
+	Polyline (pnt_vec)
+{}
+
+Polygon::~Polygon()
+{
+	// remove polygons from list
+	for (std::list<Polygon*>::iterator it (_simple_polygon_list.begin()); it != _simple_polygon_list.end(); it++) {
+		// the first entry of the list can be a pointer the object itself
+		if (*it != this)
+			delete *it;
+	}
+}
+
+bool Polygon::initialise ()
+{
+	if (this->isClosed()) {
+		calculateAxisAlignedBoundingBox();
+		ensureCWOrientation();
+		return true;
+	} else {
+		std::cerr << "ERROR in Polygon::initialise() - base polyline is not closed" << std::endl;
+		return false;
+	}
+}
+
+bool Polygon::isPntInPolygon (GEOLIB::Point const & pnt) const
+{
+	GEOLIB::Point min_aabb_pnt (_aabb.getMinPoint());
+	GEOLIB::Point max_aabb_pnt (_aabb.getMaxPoint());
+
+	if (pnt[0] < min_aabb_pnt[0] || max_aabb_pnt[0] < pnt[0] || pnt[1] < min_aabb_pnt[1] || max_aabb_pnt[1] < pnt[1])
+		return false;
+
+	size_t n_intersections (0);
+	GEOLIB::Point s;
+
+	if (_simple_polygon_list.empty ()) {
+		const size_t n_nodes (getNumberOfPoints()-1);
+		for (size_t k(0); k<n_nodes; k++) {
+			if (((*(getPoint(k)))[1] <= pnt[1] && pnt[1] <= (*(getPoint(k+1)))[1]) ||
+					((*(getPoint(k+1)))[1] <= pnt[1] && pnt[1] <= (*(getPoint(k)))[1])) {
+				switch (getEdgeType(k, pnt)) {
+				case EdgeType::TOUCHING:
+					return true;
+				case EdgeType::CROSSING:
+					n_intersections++;
+					break;
+				case EdgeType::INESSENTIAL:
+					break;
+				default:
+					// do nothing
+					;
+				}
+			}
+		}
+		if (n_intersections%2 == 1) return true;
+	} else {
+		for (std::list<Polygon*>::const_iterator it (_simple_polygon_list.begin());
+			it != _simple_polygon_list.end(); ++it) {
+			if ((*it)->isPntInPolygon (pnt)) return true;
+		}
+		return false;
+	}
+	return false;
+}
+
+bool Polygon::isPntInPolygon (double x, double y, double z) const
+{
+	const GEOLIB::Point pnt(x,y,z);
+	return isPntInPolygon (pnt);
+}
+
+bool Polygon::isPolylineInPolygon (const Polyline& ply) const
+{
+	size_t ply_size (ply.getNumberOfPoints()), cnt (0);
+	for (size_t k(0); k<ply_size; k++) {
+		if (isPntInPolygon (*(ply[k]))) {
+			cnt++;
+		}
+	}
+	if (cnt == ply_size)
+		return true;
+	return false;
+}
+
+GEOLIB::Point* Polygon::getIntersectionPointPolygonLine (GEOLIB::Point const & a, GEOLIB::Point const & b) const
+{
+	GEOLIB::Point* s (new GEOLIB::Point (0,0,0));
+
+	if (_simple_polygon_list.empty ()) {
+		const size_t n_nodes (getNumberOfPoints()-1);
+		for (size_t k(0); k<n_nodes; k++) {
+			if (MathLib::lineSegmentIntersect (*(getPoint(k)), *(getPoint(k+1)), a, b, *s)) {
+				return s;
+			}
+		}
+	} else {
+		for (std::list<Polygon*>::const_iterator it (_simple_polygon_list.begin());
+			it != _simple_polygon_list.end(); ++it) {
+			const Polygon* polygon (*it);
+			const size_t n_nodes_simple_polygon (polygon->getNumberOfPoints()-1);
+			for (size_t k(0); k<n_nodes_simple_polygon; k++) {
+				if (MathLib::lineSegmentIntersect (*(polygon->getPoint(k)), *(polygon->getPoint(k+1)), a, b, *s)) {
+					return s;
+				}
+			}
+		}
+	}
+	delete s;
+	return NULL;
+}
+
+const std::list<Polygon*>& Polygon::getListOfSimplePolygons()
+{
+	if (_simple_polygon_list.empty())
+		_simple_polygon_list.push_back (this);
+	return _simple_polygon_list;
+}
+
+void Polygon::computeListOfSimplePolygons ()
+{
+	if (! _simple_polygon_list.empty())
+		return;
+
+	_simple_polygon_list.push_back (this);
+	splitPolygonAtPoint (_simple_polygon_list.begin());
+	splitPolygonAtIntersection (_simple_polygon_list.begin());
+
+	for (std::list<Polygon*>::iterator it (_simple_polygon_list.begin());
+		it != _simple_polygon_list.end(); it++) {
+		(*it)->initialise ();
+	}
+}
+
+EdgeType::value Polygon::getEdgeType (size_t k, GEOLIB::Point const & pnt) const
+{
+	switch (getLocationOfPoint(k, pnt)) {
+	case Location::LEFT: {
+		const GEOLIB::Point & v (*(getPoint(k)));
+		const GEOLIB::Point & w (*(getPoint(k+1)));
+		if (v[1] < pnt[1] && pnt[1] <= w[1]) return EdgeType::CROSSING;
+		else return EdgeType::INESSENTIAL;
+		break;
+	}
+	case Location::RIGHT: {
+		const GEOLIB::Point & v (*(getPoint(k)));
+		const GEOLIB::Point & w (*(getPoint(k+1)));
+		if (w[1] < pnt[1] && pnt[1] <= v[1]) return EdgeType::CROSSING;
+		else return EdgeType::INESSENTIAL;
+		break;
+	}
+	case Location::BETWEEN:
+	case Location::SOURCE:
+	case Location::DESTINATION:
+		return EdgeType::TOUCHING;
+	default:
+		return EdgeType::INESSENTIAL;
+	}
+}
+
+void Polygon::calculateAxisAlignedBoundingBox ()
+{
+	size_t n_nodes (getNumberOfPoints());
+	for (size_t k(0); k<n_nodes; k++) {
+		_aabb.update ((*(getPoint(k))));
+	}
+}
+
+void Polygon::ensureCWOrientation ()
+{
+	// *** pre processing: rotate points to xy-plan
+	// *** copy points to vector - last point is identical to the first
+	size_t n_pnts (this->getNumberOfPoints()-1);
+	std::vector<GEOLIB::Point*> tmp_polygon_pnts;
+	for (size_t k(0); k < n_pnts; k++) {
+		tmp_polygon_pnts.push_back (new GEOLIB::Point (*(this->getPoint(k))));
+	}
+
+	// *** calculate supporting plane (plane normal and
+	MathLib::Vector plane_normal;
+	double d;
+	MathLib::getNewellPlane(tmp_polygon_pnts, plane_normal, d);
+
+	// *** rotate if necessary
+	double tol (sqrt(std::numeric_limits<double>::min()));
+	if (fabs(plane_normal[0]) > tol || fabs(plane_normal[1]) > tol) {
+		// rotate copied points into x-y-plane
+		MathLib::rotatePointsToXY(plane_normal, tmp_polygon_pnts);
+	}
+
+	for (size_t k(0); k<tmp_polygon_pnts.size(); k++) {
+		(*(tmp_polygon_pnts[k]))[2] = 0.0; // should be -= d but there are numerical errors
+	}
+
+	// *** get the left most upper point
+	size_t min_x_max_y_idx (0);	// for orientation check
+	for (size_t k(0); k<n_pnts; k++) {
+		if ((*(tmp_polygon_pnts[k]))[0] <= (*(tmp_polygon_pnts[min_x_max_y_idx]))[0]) {
+			if ((*(tmp_polygon_pnts[k]))[0] < (*(tmp_polygon_pnts[min_x_max_y_idx]))[0]) {
+				min_x_max_y_idx = k;
+			} else {
+				if ((*(tmp_polygon_pnts[k]))[1] > (*(tmp_polygon_pnts[min_x_max_y_idx]))[1]) {
+					min_x_max_y_idx = k;
+				}
+			}
+		}
+	}
+	// *** determine orientation
+	MathLib::Orientation orient;
+	if (0 < min_x_max_y_idx && min_x_max_y_idx < n_pnts-2) {
+		orient = MathLib::getOrientation (
+			tmp_polygon_pnts[min_x_max_y_idx-1],
+			tmp_polygon_pnts[min_x_max_y_idx],
+			tmp_polygon_pnts[min_x_max_y_idx+1]);
+	} else {
+		if (0 == min_x_max_y_idx) {
+			orient = MathLib::getOrientation (
+					tmp_polygon_pnts[n_pnts-1],
+					tmp_polygon_pnts[0],
+					tmp_polygon_pnts[1]);
+		} else {
+			orient = MathLib::getOrientation (
+					tmp_polygon_pnts[n_pnts-2],
+					tmp_polygon_pnts[n_pnts-1],
+					tmp_polygon_pnts[0]);
+		}
+	}
+
+	if (orient == MathLib::CCW) {
+		// switch orientation
+		size_t tmp_n_pnts (n_pnts);
+		tmp_n_pnts++; // include last point of polygon (which is identical to the first)
+		for (size_t k(0); k<tmp_n_pnts/2; k++) {
+			BASELIB::swap (_ply_pnt_ids[k], _ply_pnt_ids[tmp_n_pnts-1-k]);
+		}
+	}
+
+	for (size_t k(0); k<n_pnts; k++) {
+		delete tmp_polygon_pnts[k];
+	}
+}
+
+void Polygon::splitPolygonAtIntersection (std::list<Polygon*>::iterator polygon_it)
+{
+	size_t idx0 (0), idx1 (0);
+	while (polygon_it != _simple_polygon_list.end()) {
+		GEOLIB::Point *intersection_pnt (new GEOLIB::Point);
+		bool is_simple (!MathLib::lineSegmentsIntersect (*polygon_it, idx0, idx1, *intersection_pnt));
+		if (!is_simple) {
+			// adding intersection point to pnt_vec
+			size_t intersection_pnt_id (_ply_pnts.size());
+			const_cast<std::vector<Point*>& >(_ply_pnts).push_back (intersection_pnt);
+
+			// split Polygon
+			if (idx0 > idx1) BASELIB::swap (idx0, idx1);
+
+			GEOLIB::Polygon* polygon0 (new GEOLIB::Polygon((*polygon_it)->getPointsVec(), false));
+			for (size_t k(0); k<=idx0; k++) polygon0->addPoint ((*polygon_it)->getPointID (k));
+			polygon0->addPoint (intersection_pnt_id);
+			for (size_t k(idx1+1); k<(*polygon_it)->getNumberOfPoints(); k++)
+				polygon0->addPoint ((*polygon_it)->getPointID (k));
+			if (! polygon0->initialise()) {
+				std::cerr << "ERROR in Polygon::splitPolygonAtIntersection polygon0" << std::endl;
+				exit (1);
+			}
+
+			GEOLIB::Polygon* polygon1 (new GEOLIB::Polygon((*polygon_it)->getPointsVec(), false));
+			polygon1->addPoint (intersection_pnt_id);
+			for (size_t k(idx0+1); k<=idx1; k++)
+				polygon1->addPoint ((*polygon_it)->getPointID (k));
+			polygon1->addPoint (intersection_pnt_id);
+			if (! polygon1->initialise()) {
+				std::cerr << "ERROR in Polygon::splitPolygonAtIntersection polygon1" << std::endl;
+				exit (1);
+			}
+
+			// remove original polyline and add two new polylines
+			std::list<GEOLIB::Polygon*>::iterator polygon0_it, polygon1_it;
+			polygon_it = _simple_polygon_list.erase (polygon_it);
+			polygon1_it = _simple_polygon_list.insert (polygon_it, polygon1);
+			polygon0_it = _simple_polygon_list.insert (polygon1_it, polygon0);
+
+			splitPolygonAtIntersection (polygon0_it);
+			splitPolygonAtIntersection (polygon1_it);
+		} else {
+			delete intersection_pnt;
+		}
+		++polygon_it;
+	}
+}
+
+void Polygon::splitPolygonAtPoint (std::list<GEOLIB::Polygon*>::iterator polygon_it)
+{
+	size_t n ((*polygon_it)->getNumberOfPoints()-1), idx0 (0), idx1(0);
+	size_t *id_vec (new size_t[n]), *perm (new size_t[n]);
+	for (size_t k(0); k<n; k++) {
+		id_vec[k] = (*polygon_it)->getPointID (k);
+		perm[k] = k;
+	}
+
+	quicksort (id_vec, 0, n, perm);
+
+	for (size_t k(0); k<n-1; k++) {
+		if (id_vec[k] == id_vec[k+1]) {
+			idx0 = perm[k];
+			idx1 = perm[k+1];
+			delete [] perm;
+			delete [] id_vec;
+
+			if (idx0 > idx1) BASELIB::swap (idx0, idx1);
+
+			// create two closed polylines
+			GEOLIB::Polygon* polygon0 (new GEOLIB::Polygon((*polygon_it)->getPointsVec()));
+			for (size_t k(0); k<=idx0; k++)
+				polygon0->addPoint ((*polygon_it)->getPointID (k));
+			for (size_t k(idx1+1); k<(*polygon_it)->getNumberOfPoints(); k++)
+				polygon0->addPoint ((*polygon_it)->getPointID (k));
+			polygon0->initialise();
+
+			GEOLIB::Polygon* polygon1 (new GEOLIB::Polygon((*polygon_it)->getPointsVec()));
+			for (size_t k(idx0); k<=idx1; k++)
+				polygon1->addPoint ((*polygon_it)->getPointID (k));
+			polygon1->initialise();
+
+			// remove original polygon and add two new polygons
+			std::list<GEOLIB::Polygon*>::iterator polygon0_it, polygon1_it;
+			polygon1_it = _simple_polygon_list.insert (_simple_polygon_list.erase (polygon_it), polygon1);
+			polygon0_it = _simple_polygon_list.insert (polygon1_it, polygon0);
+
+			splitPolygonAtPoint (polygon0_it);
+			splitPolygonAtPoint (polygon1_it);
+
+			return;
+		}
+	}
+	delete [] perm;
+	delete [] id_vec;
+}
+
+GEOLIB::Polygon* createPolygonFromCircle (GEOLIB::Point const& middle_pnt, double radius,
+		std::vector<GEOLIB::Point*> & pnts, size_t resolution)
+{
+	const size_t off_set (pnts.size());
+	// create points
+	double angle (2.0 * M_PI / resolution);
+	for (size_t k(0); k<resolution; k++) {
+		GEOLIB::Point *pnt (new GEOLIB::Point(middle_pnt.getData()));
+		(*pnt)[0] += radius * cos (k*angle);
+		(*pnt)[1] += radius * sin (k*angle);
+		pnts.push_back (pnt);
+	}
+
+	// create polygon
+	GEOLIB::Polygon* polygon (new GEOLIB::Polygon (pnts, false));
+	for (size_t k(0); k<resolution; k++) {
+		polygon->addPoint (k+off_set);
+	}
+	polygon->addPoint (off_set);
+
+	return polygon;
+}
+
+
+} // end namespace GEOLIB
diff --git a/GeoLib/Polygon.h b/GeoLib/Polygon.h
new file mode 100644
index 0000000000000000000000000000000000000000..f341407183972c50bc478a83118f722b3972af64
--- /dev/null
+++ b/GeoLib/Polygon.h
@@ -0,0 +1,104 @@
+/*
+ * Polygon.h
+ *
+ *  Created on: Jun 21, 2010
+ *      Author: TF
+ */
+
+#ifndef POLYGON_H_
+#define POLYGON_H_
+
+// STL
+#include <list>
+
+// GEOLIB
+#include "AxisAlignedBoundingBox.h"
+#include "Polyline.h"
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ */
+
+/**
+ * edge classification
+ */
+class EdgeType {
+	public:
+		enum value {
+			TOUCHING,  //!< TOUCHING
+			CROSSING,  //!< CROSSING
+			INESSENTIAL//!< INESSENTIAL
+		};
+};
+
+/**
+ *
+ */
+class Polygon : public Polyline
+{
+public:
+	/**
+	 * constructor checks if the given polyline is closed,
+	 * and assures that the orientation is clock wise.
+	 * @param ply closed Polyline
+	 * @param init if true, check if polyline is closed, calculate bounding box
+	 * @return
+	 */
+	Polygon(const Polyline &ply, bool init = true);
+
+	Polygon (const std::vector<Point*>& pnt_vec);
+
+	virtual ~Polygon();
+
+	/**
+	 *
+	 * @return
+	 */
+	bool initialise ();
+
+	/**
+	 * Method checks if the given point is inside the polygon.
+	 * The method requires that the polygon has clock wise orientation.
+	 * @param pnt the Point
+	 * @return if point is inside the polygon true, else false
+	 */
+	bool isPntInPolygon (const GEOLIB::Point& pnt) const;
+	/**
+	 * wrapper for method isPntInPolygon (const GEOLIB::Point&)
+	 * @param x x coordinate of point
+	 * @param y y coordinate of point
+	 * @param z z coordinate of point
+	 * @return if point is inside the polygon true, else false
+	 */
+	bool isPntInPolygon (double x, double y, double z) const;
+	bool isPolylineInPolygon (const Polyline& ply) const;
+	GEOLIB::Point* getIntersectionPointPolygonLine (GEOLIB::Point const & a, GEOLIB::Point const & b) const;
+	void computeListOfSimplePolygons ();
+	const std::list<Polygon*>& getListOfSimplePolygons ();
+
+private:
+	/**
+	 * get the type of edge with respect to the given point (2d method!)
+	 * @param k number of line segment
+	 * @param pnt point that is edge type computed for
+	 * @return a value of enum EdgeType
+	 */
+	EdgeType::value getEdgeType (size_t k, GEOLIB::Point const & pnt) const;
+
+	void calculateAxisAlignedBoundingBox ();
+	void ensureCWOrientation ();
+
+	void splitPolygonAtIntersection (std::list<Polygon*>::iterator polygon_it);
+	void splitPolygonAtPoint (std::list<Polygon*>::iterator polygon_it);
+	std::list<Polygon*> _simple_polygon_list;
+	AABB _aabb;
+};
+
+GEOLIB::Polygon* createPolygonFromCircle (GEOLIB::Point const& middle_pnt, double radius,
+		std::vector<GEOLIB::Point*> & pnts, size_t resolution = 12);
+
+} // end namespace GEOLIB
+
+#endif /* POLYGON_H_ */
diff --git a/GeoLib/Polyline.cpp b/GeoLib/Polyline.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0176824553cd42d1fea7c1e14682472db9b72687
--- /dev/null
+++ b/GeoLib/Polyline.cpp
@@ -0,0 +1,261 @@
+/*
+ * Polyline.cpp
+ *
+ *  Created on: Jun 21, 2010
+ *      Author: TF
+ */
+
+// Base
+#include "swap.h"
+
+#include "Polyline.h"
+
+namespace GEOLIB {
+
+Polyline::Polyline(const std::vector<Point*>& pnt_vec) :
+	GeoObject(), _ply_pnts(pnt_vec)
+{
+	_length.push_back (0.0);
+}
+
+Polyline::Polyline(const Polyline& ply) :
+	GeoObject(), _ply_pnts (ply._ply_pnts)
+{
+	for (size_t k(0); k<ply.getNumberOfPoints(); ++k) {
+		_ply_pnt_ids.push_back (ply.getPointID (k));
+	}
+
+	if (ply.getNumberOfPoints() > 0) {
+		for (size_t k(0); k<ply.getNumberOfPoints(); ++k) {
+			_length.push_back (ply.getLength (k));
+		}
+	}
+}
+
+void Polyline::write(std::ostream &os) const
+{
+	size_t size(_ply_pnt_ids.size());
+	for (size_t k(0); k < size; k++) {
+		os << *(_ply_pnts[_ply_pnt_ids[k]]) << std::endl;
+	}
+}
+
+void Polyline::addPoint(size_t point_id)
+{
+	assert(point_id < _ply_pnts.size());
+	size_t n_pnts (_ply_pnt_ids.size());
+	_ply_pnt_ids.push_back(point_id);
+
+	if (n_pnts > 0) {
+		double act_dist (sqrt(MathLib::sqrDist (_ply_pnts[_ply_pnt_ids[n_pnts-1]], _ply_pnts[point_id])));
+		double dist_until_now (0.0);
+		if (n_pnts > 1)
+			dist_until_now = _length[n_pnts - 1];
+
+		_length.push_back (dist_until_now + act_dist);
+	}
+}
+
+size_t Polyline::getNumberOfPoints() const
+{
+	return _ply_pnt_ids.size();
+}
+
+bool Polyline::isClosed() const
+{
+	if (_ply_pnt_ids.front() == _ply_pnt_ids.back())
+		return true;
+	else
+		return false;
+}
+
+size_t Polyline::getPointID(size_t i) const
+{
+	assert(i < _ply_pnt_ids.size());
+	return _ply_pnt_ids[i];
+}
+
+void Polyline::setPointID(size_t idx, size_t id)
+{
+	assert(idx < _ply_pnt_ids.size());
+	_ply_pnt_ids[idx] = id;
+}
+
+const Point* Polyline::operator[](size_t i) const
+{
+	assert(i < _ply_pnt_ids.size());
+	return _ply_pnts[_ply_pnt_ids[i]];
+}
+
+const Point* Polyline::getPoint(size_t i) const
+{
+	assert(i < _ply_pnt_ids.size());
+ 	return _ply_pnts[_ply_pnt_ids[i]];
+}
+
+std::vector<Point*> const& Polyline::getPointsVec () const
+{
+	return _ply_pnts;
+}
+
+double Polyline::getLength (size_t k) const
+{
+	assert(k < _length.size());
+	return _length[k];
+}
+
+const std::vector<double>& Polyline::getLengthVec () const
+{
+	return _length;
+}
+
+
+Polyline* Polyline::constructPolylineFromSegments(const std::vector<Polyline*> &ply_vec, double prox)
+{
+	size_t nLines = ply_vec.size();
+
+	Polyline* new_ply = new Polyline(*ply_vec[0]);
+	std::vector<GEOLIB::Point*> pnt_vec(new_ply->getPointsVec());
+
+	std::vector<Polyline*> local_ply_vec;
+	for (size_t i = 1; i < nLines; i++) {
+		local_ply_vec.push_back(ply_vec[i]);
+	}
+
+	while (!local_ply_vec.empty()) {
+		bool ply_found(false);
+		prox *= prox; // square distance once to save time later
+		for (std::vector<Polyline*>::iterator it=local_ply_vec.begin(); it!=local_ply_vec.end(); ++it)
+		{
+			if (pnt_vec == (*it)->getPointsVec())
+			{
+				size_t nPoints((*it)->getNumberOfPoints());
+
+				//if (new_ply->getPointID(0) == (*it)->getPointID(0))
+				if (pointsAreIdentical(pnt_vec, new_ply->getPointID(0), (*it)->getPointID(0), prox))
+				{
+					Polyline* tmp = new Polyline((*it)->getPointsVec());
+					for (size_t k = 0; k < nPoints; k++)
+						tmp->addPoint((*it)->getPointID(nPoints - k - 1));
+
+					size_t new_ply_size(new_ply->getNumberOfPoints());
+					for (size_t k = 1; k < new_ply_size; k++)
+						tmp->addPoint(new_ply->getPointID(k));
+					delete new_ply;
+					new_ply = tmp;
+					ply_found = true;
+				}
+				//else if (new_ply->getPointID(0) == (*it)->getPointID(nPoints-1))
+				else if (pointsAreIdentical(pnt_vec, new_ply->getPointID(0), (*it)->getPointID(nPoints-1), prox))
+				{
+					Polyline* tmp = new Polyline(**it);
+					size_t new_ply_size(new_ply->getNumberOfPoints());
+					for (size_t k = 1; k < new_ply_size; k++)
+						tmp->addPoint(new_ply->getPointID(k));
+					delete new_ply;
+					new_ply = tmp;
+					ply_found = true;
+				}
+				//else if (new_ply->getPointID(new_ply->getNumberOfPoints()-1) == (*it)->getPointID(0))
+				else if (pointsAreIdentical(pnt_vec, new_ply->getPointID(new_ply->getNumberOfPoints()-1), (*it)->getPointID(0), prox))
+				{
+					for (size_t k=1; k<nPoints; k++)
+						new_ply->addPoint((*it)->getPointID(k));
+					ply_found = true;
+				}
+				//else if (new_ply->getPointID(new_ply->getNumberOfPoints()-1) == (*it)->getPointID(nPoints-1))
+				else if (pointsAreIdentical(pnt_vec, new_ply->getPointID(new_ply->getNumberOfPoints()-1), (*it)->getPointID(nPoints-1), prox))
+				{
+					for (size_t k=1; k<nPoints; k++)
+						new_ply->addPoint((*it)->getPointID(nPoints-k-1));
+					ply_found = true;
+				}
+				if (ply_found) {
+					local_ply_vec.erase(it);
+					break;
+				}
+			} else
+				std::cout
+						<< "Error in Polyline::contructPolylineFromSegments() - Line segments use different point vectors..."
+						<< std::endl;
+		}
+
+		if (!ply_found) {
+			std::cout
+					<< "Error in Polyline::contructPolylineFromSegments() - Not all segments are connected..."
+					<< std::endl;
+			new_ply = NULL;
+			break;
+		}
+	}
+	return new_ply;
+}
+
+bool Polyline::pointsAreIdentical(const std::vector<Point*> &pnt_vec, size_t i, size_t j, double prox)
+{
+	if (i==j) return true;
+	return (MathLib::checkDistance( *pnt_vec[i], *pnt_vec[j], prox ));
+}
+
+Polyline* Polyline::closePolyline(const Polyline& ply)
+{
+	if (ply.getNumberOfPoints()>2)
+	{
+		Polyline* new_ply = new Polyline(ply);
+		if (ply.isClosed()) return new_ply;
+		new_ply->addPoint(new_ply->getPointID(0));
+		return new_ply;
+	}
+	std::cout << "Error in Polyline::closePolyline() - Input polyline needs to be composed of at least three points..." << std::endl;
+	return NULL;
+}
+
+Location::type Polyline::getLocationOfPoint (size_t k, GEOLIB::Point const & pnt) const
+{
+	assert (k<_ply_pnt_ids.size()-1);
+
+	GEOLIB::Point const& source (*(_ply_pnts[_ply_pnt_ids[k]]));
+	GEOLIB::Point const& dest (*(_ply_pnts[_ply_pnt_ids[k+1]]));
+	GEOLIB::Point a (dest[0]-source[0], dest[1]-source[1], dest[2]-source[2]); // vector
+	GEOLIB::Point b (pnt[0]-source[0], pnt[1]-source[1], pnt[2]-source[2]); // vector
+
+	double det_2x2 (a[0]*b[1] - a[1]*b[0]);
+
+	if (det_2x2 > std::numeric_limits<double>::epsilon()) return Location::LEFT;
+	if (std::numeric_limits<double>::epsilon() < fabs(det_2x2)) return Location::RIGHT;
+	if (a[0]*b[0] < 0.0 || a[1]*b[1] < 0.0) return Location::BEHIND;
+	if (MathLib::sqrNrm2(&a) < MathLib::sqrNrm2(&b)) return Location::BEYOND;
+	if (MathLib::sqrDist (&pnt, _ply_pnts[_ply_pnt_ids[k]]) < sqrt(std::numeric_limits<double>::min()))
+		return Location::SOURCE;
+	if (MathLib::sqrDist (&pnt, _ply_pnts[_ply_pnt_ids[k+1]]) < sqrt(std::numeric_limits<double>::min()))
+		return Location::DESTINATION;
+	return Location::BETWEEN;
+}
+
+std::ostream& operator<< (std::ostream &os, const Polyline &pl)
+{
+	pl.write (os);
+	return os;
+}
+
+bool containsEdge (const Polyline& ply, size_t id0, size_t id1)
+{
+	if (id0 == id1) {
+		std::cerr << "no valid edge id0 == id1 == " << id0 << std::endl;
+		return false;
+	}
+	if (id0 > id1) BASELIB::swap (id0,id1);
+	const size_t n (ply.getNumberOfPoints() - 1);
+	for (size_t k(0); k<n; k++) {
+		size_t ply_pnt0 (ply.getPointID (k));
+		size_t ply_pnt1 (ply.getPointID (k+1));
+		if (ply_pnt0 > ply_pnt1)
+			BASELIB::swap (ply_pnt0, ply_pnt1);
+		if (ply_pnt0 == id0 && ply_pnt1 == id1)
+			return true;
+	}
+	return false;
+}
+
+
+} // end namespace GEOLIB
diff --git a/GeoLib/Polyline.h b/GeoLib/Polyline.h
new file mode 100644
index 0000000000000000000000000000000000000000..6862c22ff7b30fa5e8ad87d8501e163f6c3b9d67
--- /dev/null
+++ b/GeoLib/Polyline.h
@@ -0,0 +1,155 @@
+/*
+ * PolyLine.h
+ *
+ *  Created on: Jan 14, 2010
+ *      Author: TF
+ */
+
+#ifndef POLYLINE_H_
+#define POLYLINE_H_
+
+// GEOLIB
+#include "GeoObject.h"
+#include "Point.h"
+
+// MathLib
+#include "MathTools.h"
+
+#include <vector>
+#include <cmath>
+
+namespace GEOLIB {
+
+class Location {
+public:
+	enum type {
+		LEFT,
+		RIGHT,
+		BEYOND,
+		BEHIND,
+		BETWEEN,
+		SOURCE,
+		DESTINATION
+	};
+};
+
+/**
+ * \ingroup GEOLIB
+ *
+ * \brief Class Polyline consists mainly of a reference to a point vector and
+ * a vector that stores the indices in the point vector.
+ * A polyline consists of at least one line segment. The polyline is specified by the points
+ * of the line segments. The class Polyline stores the position of pointers to the points in the
+ * m_ply_pnt_ids vector.
+ * */
+class Polyline : public GeoObject
+{
+public:
+	/** constructor
+	 * \param pnt_vec a reference to the point vector
+	 */
+	Polyline(const std::vector<Point*>& pnt_vec);
+	/**
+	 * Copy constructor
+	 * @param ply Polyline
+	 */
+	Polyline (const Polyline& ply);
+
+	virtual ~Polyline() {}
+
+	/** write the points to the stream */
+	void write(std::ostream &os) const;
+
+	/** adds a new pointer to a point to the polyline */
+	void addPoint(size_t pos);
+
+	/**
+	 * Closes a polyline by adding a line sement that connects start- and end-point.
+	 * \param ply A Polyline containing at least three points.
+	 * \result A polygon.
+	 */
+	static Polyline* closePolyline(const Polyline& ply);
+
+	/// Constructs one polyline from a vector of connected polylines.
+	/// All polylines in this vector need to reference the same point vector.
+	static Polyline* constructPolylineFromSegments(const std::vector<Polyline*> &ply_vec, double prox = 0.0);
+
+	/**
+	 * returns the number of points,
+	 * the number of segments is about one smaller
+	 * */
+	size_t getNumberOfPoints() const;
+
+	/** returns true if the polyline is closed */
+	bool isClosed() const;
+
+	/**
+	 * returns the index of the i-th polyline point
+	 * in the point vector
+	 */
+	size_t getPointID(size_t i) const;
+
+	/**
+	 * Changes a point index for one point in a line
+	 * @param idx Index of point in line
+	 * @param id ID of point in PointVec object
+	 */
+	void setPointID(size_t idx, size_t id);
+
+	/** \brief const access operator for the access to the i-th point of the polyline.
+	 */
+	const Point* operator[](size_t i) const;
+
+	/**
+	 * \brief returns the i-th point contained in the polyline
+	 * */
+	const Point* getPoint(size_t i) const;
+
+	std::vector<Point*> const& getPointsVec () const;
+
+	/**
+	 * returns the length of the polyline until the k-th line segment
+	 * @param k the k-th line segment
+	 * @return the length of the polyline until the k-th line segment
+	 */
+	double getLength (size_t k) const;
+
+	/**
+	 * get the complete length vector
+	 * @return the length vector of the polyline
+	 */
+	const std::vector<double>& getLengthVec () const;
+
+protected:
+	/**
+	 * 2D method - ignores z coordinate. It calculates the location
+	 * of the point relative to the k-th line segment of the polyline.
+	 * (literatur reference:
+	 * Computational Geometry and Computer Graphics in C++; Michael J. Laszlo)
+	 * @param k the number of line segment
+	 * @param pnt the point
+	 * @return a value of enum LOCATION
+	 */
+	Location::type getLocationOfPoint (size_t k, GEOLIB::Point const & pnt) const;
+
+	static bool pointsAreIdentical(const std::vector<Point*> &pnt_vec, size_t i, size_t j, double prox);
+
+
+	/** a reference to the vector of pointers to the geometric points */
+	const std::vector<Point*> &_ply_pnts;
+	/** position of pointers to the geometric points */
+	std::vector<size_t> _ply_pnt_ids;
+	/**
+	 * the k-th element of the vector contains the length of the polyline until the k-th segment
+	 */
+	std::vector<double> _length;
+};
+
+/** overload the output operator for class Polyline */
+std::ostream& operator<< (std::ostream &os, const Polyline &pl);
+
+bool containsEdge (const Polyline& ply, size_t id0, size_t id1);
+
+} // end namespace
+
+#endif /* POLYLINE_H_ */
diff --git a/GeoLib/PolylineVec.h b/GeoLib/PolylineVec.h
new file mode 100644
index 0000000000000000000000000000000000000000..bb97c68c5ca583c55f7ad24d61546e9aa985e6c9
--- /dev/null
+++ b/GeoLib/PolylineVec.h
@@ -0,0 +1,27 @@
+/*
+ * PolylineVec.h
+ *
+ *  Created on: Feb 9, 2010
+ *      Author: TF
+ */
+
+#ifndef POLYLINEVEC_H_
+#define POLYLINEVEC_H_
+
+#include "TemplateVec.h"
+#include "Polyline.h"
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ *
+ * \brief class PolylineVec encapsulate a std::vector of Polylines
+ * additional one can give the vector of polylines a name
+ * */
+
+typedef TemplateVec<Polyline> PolylineVec;
+
+} // end namespace
+
+#endif /* POLYLINEVEC_H_ */
diff --git a/GeoLib/ProjectData.cpp b/GeoLib/ProjectData.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d668fd46726fe7e7a47b207316b2689c28113143
--- /dev/null
+++ b/GeoLib/ProjectData.cpp
@@ -0,0 +1,148 @@
+/**
+ * \file ProjectData.cpp
+ * 25/08/2010 KR Initial implementation
+ */
+
+#include "ProjectData.h"
+#include "StringTools.h"
+
+
+ProjectData::ProjectData()
+//: _geoObjects ()
+{}
+
+ProjectData::~ProjectData()
+{
+	delete _geoObjects;
+	for (std::map<std::string, MeshLib::CFEMesh*>::iterator it = _msh_vec.begin(); it != _msh_vec.end(); ++it)
+	{
+		delete it->second;
+	}
+	size_t nCond (_cond_vec.size());
+	for (size_t i=0; i<nCond; i++)
+	{
+		delete _cond_vec[i];
+	}
+}
+
+void ProjectData::addMesh(MeshLib::CFEMesh* mesh, std::string &name)
+{
+	isUniqueMeshName(name);
+	_msh_vec[name] = mesh;
+};
+
+const MeshLib::CFEMesh* ProjectData::getMesh(const std::string &name) const
+{
+	return _msh_vec.find(name)->second;
+}
+
+bool ProjectData::removeMesh(const std::string &name)
+{
+	delete _msh_vec[name];
+	size_t result = _msh_vec.erase(name);
+	return (result>0);
+}
+
+void ProjectData::addCondition(FEMCondition* cond)
+{
+	_cond_vec.push_back(cond);
+};
+
+void ProjectData::addConditions(std::vector<FEMCondition*> conds)
+{
+	for (size_t i=0; i<conds.size(); i++)
+		_cond_vec.push_back(conds[i]);
+};
+
+const FEMCondition* ProjectData::getCondition(const std::string &geo_name, GEOLIB::GEOTYPE type, const std::string &cond_name) const
+{
+	for (std::vector<FEMCondition*>::const_iterator it = _cond_vec.begin(); it != _cond_vec.end(); ++it)
+	{
+		if ((*it)->getAssociatedGeometryName().compare(geo_name) == 0) 
+		{
+			if ( ((*it)->getGeoName().compare(cond_name)==0) && ((*it)->getGeoType()==type) )
+				return *it;
+		}
+	}
+	std::cout << "Error in ProjectData::getCondition() - No condition found with name \"" << cond_name << "\"..." << std::endl;
+	return NULL;
+}
+
+const std::vector<FEMCondition*> ProjectData::getConditions(const std::string &geo_name, FEMCondition::CondType type) const
+{
+	std::vector<FEMCondition*> conds;
+	for (std::vector<FEMCondition*>::const_iterator it = _cond_vec.begin(); it != _cond_vec.end(); ++it)
+	{
+		if ((*it)->getAssociatedGeometryName().compare(geo_name) == 0)
+		{
+			if ( (type == FEMCondition::UNSPECIFIED) || ((*it)->getCondType() == type) )
+				conds.push_back(*it);
+		}
+	}
+	return conds;
+}
+
+bool ProjectData::removeCondition(const std::string &geo_name, GEOLIB::GEOTYPE type, const std::string &cond_name)
+{
+	for (std::vector<FEMCondition*>::iterator it = _cond_vec.begin(); it != _cond_vec.end(); ++it)
+	{
+		if ((*it)->getAssociatedGeometryName().compare(geo_name) == 0) 
+		{
+			if ( ((*it)->getGeoName().compare(cond_name)==0) && ((*it)->getGeoType()==type) )
+			{
+				delete *it;
+				_cond_vec.erase(it);
+				return true;
+			}
+		}
+	}
+	std::cout << "Error in ProjectData::getCondition() - No condition found with name \"" << cond_name << "\"..." << std::endl;
+	return false;
+}
+
+void ProjectData::removeConditions(const std::string &geo_name, FEMCondition::CondType type)
+{
+	for (std::vector<FEMCondition*>::iterator it = _cond_vec.begin(); it != _cond_vec.end();)
+	{
+		if ( ((*it)->getAssociatedGeometryName().compare(geo_name) == 0) 
+			&& ( (type == FEMCondition::UNSPECIFIED) || ((*it)->getCondType() == type) ))
+		{
+			delete *it;
+			it = _cond_vec.erase(it);
+		}
+		else ++it;
+	}
+}
+
+bool ProjectData::isUniqueMeshName(std::string &name)
+{
+	int count(0);
+	bool isUnique(false);
+	std::string cpName;
+
+	while (!isUnique)
+	{
+		isUnique = true;
+		cpName = name;
+
+		count++;
+		// If the original name already exists we start to add numbers to name for
+		// as long as it takes to make the name unique.
+		if (count>1) cpName = cpName + "-" + number2str(count);
+
+		for (std::map<std::string, MeshLib::CFEMesh*>::iterator it = _msh_vec.begin(); it != _msh_vec.end(); ++it)
+		{
+			if ( cpName.compare(it->first) == 0 ) isUnique = false;
+		}
+	}
+
+	// At this point cpName is a unique name and isUnique is true.
+	// If cpName is not the original name, "name" is changed and isUnique is set to false,
+	// indicating that a vector with the original name already exists.
+	if (count>1)
+	{
+		isUnique = false;
+		name = cpName;
+	}
+	return isUnique;
+}
diff --git a/GeoLib/ProjectData.h b/GeoLib/ProjectData.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3887909200f6ca320836a75266be93538602e6b
--- /dev/null
+++ b/GeoLib/ProjectData.h
@@ -0,0 +1,75 @@
+/**
+ * \file ProjectData.h
+ * 25/08/2010 KR Initial implementation
+ */
+
+#ifndef PROJECTDATA_H_
+#define PROJECTDATA_H_
+
+#include "GEOObjects.h"
+#include "msh_mesh.h"
+#include "FEMCondition.h"
+
+
+/**
+ * The ProjectData Object contains all the data needed for a certain project, i.e. all
+ * geometric data (stored in a GEOObjects-object), all the meshes, FEM Conditions (i.e.
+ * Boundary Conditions, Source Terms and Initial Conditions), etc.
+ * ProjectData does not administrate any of the objects, it is just a "container class" 
+ * to store them all in one place.
+ * For each class of object stored in this container exists an add-, get- and remove-method.
+ *
+ * \sa GEOModels, FEMCondition
+ */
+class ProjectData
+{
+public:
+	ProjectData();
+	virtual ~ProjectData();
+
+	// Returns the GEOObjects containing all points, polylines and surfaces
+	GEOLIB::GEOObjects* getGEOObjects() { return _geoObjects; };
+
+	// Returns the GEOObjects containing all points, polylines and surfaces
+	void setGEOObjects(GEOLIB::GEOObjects* geo_objects) { _geoObjects = geo_objects; };
+
+	/// Adds a new mesh
+	virtual void addMesh(MeshLib::CFEMesh* mesh, std::string &name);
+
+	/// Returns the mesh with the given name.
+	const MeshLib::CFEMesh* getMesh(const std::string &name) const;
+
+	/// Returns all the meshes with their respective names
+	const std::map<std::string, MeshLib::CFEMesh*>& getMeshObjects() const { return _msh_vec; };
+
+	/// Removes the mesh with the given name.
+	virtual bool removeMesh(const std::string &name);
+
+	/// Adds a new FEM Condition
+	virtual void addCondition(FEMCondition* cond);
+
+	/// Adds a new FEM Condition
+	virtual void addConditions(std::vector<FEMCondition*> conds);
+
+	/// Returns the FEM Condition set on a GeoObject with the given name and type from a certain geometry.
+	const FEMCondition* getCondition(const std::string &geo_name, GEOLIB::GEOTYPE type, const std::string &cond_name) const;
+
+	/// Returns all FEM Conditions with the given type from a certain geometry.
+	const std::vector<FEMCondition*> getConditions(const std::string &geo_name, FEMCondition::CondType type = FEMCondition::UNSPECIFIED) const;
+
+	/// Removes the FEM Condition set on a GeoObject with the given name and type from a certain geometry.
+	virtual bool removeCondition(const std::string &geo_name, GEOLIB::GEOTYPE type, const std::string &cond_name);
+
+	/// Removes all FEM Conditions with the given type from a certain geometry
+	virtual void removeConditions(const std::string &geo_name, FEMCondition::CondType type = FEMCondition::UNSPECIFIED);
+
+	/// Checks if the name of the mesh is already exists, if so it generates a unique name.
+	bool isUniqueMeshName(std::string &name);
+
+private:
+	GEOLIB::GEOObjects* _geoObjects;
+	std::map<std::string, MeshLib::CFEMesh*> _msh_vec;
+	std::vector<FEMCondition*> _cond_vec;
+};
+
+#endif //PROJECTDATA_H_
diff --git a/GeoLib/PropertyBounds.h b/GeoLib/PropertyBounds.h
new file mode 100644
index 0000000000000000000000000000000000000000..9615d0c7df9c968dacf36aa2a9abea6fc0101e06
--- /dev/null
+++ b/GeoLib/PropertyBounds.h
@@ -0,0 +1,29 @@
+/**
+ * \file PropertyBounds.h
+ * 18/01/2010 KR Initial implementation
+ */
+
+#ifndef PROPERTYBOUNDS_H
+#define PROPERTYBOUNDS_H
+
+#include <string>
+
+class PropertyBounds
+{
+public:
+	PropertyBounds(std::string pname, double minVal, double maxVal ) :  _name(pname), _minVal(minVal), _maxVal(maxVal) {}
+
+	std::string getName() const { return _name; }
+	double getMin() const { return _minVal; }
+	double getMax() const { return _maxVal; }
+
+	void setMin(double val) { _minVal = val; }
+	void setMax(double val) { _maxVal = val; }
+
+private:
+	std::string _name;
+	double _minVal;
+	double _maxVal;
+};
+
+#endif //PROPERTYBOUNDS_H
diff --git a/GeoLib/QuadTree.h b/GeoLib/QuadTree.h
new file mode 100644
index 0000000000000000000000000000000000000000..b13af3d4a7207bb661ed100348541605c418a1b2
--- /dev/null
+++ b/GeoLib/QuadTree.h
@@ -0,0 +1,508 @@
+/*
+ * QuadTree.h
+ *
+ *  Created on: Nov 9, 2010
+ *      Author: TF
+ */
+
+#ifndef QUADTREE_H_
+#define QUADTREE_H_
+
+namespace GEOLIB {
+
+/**
+ * A quadtree is a rooted tree in which every internal
+ * node has four children. Every node corresponds to a square.
+ * (see Computational Geometry - Algorithms and Applications [Mark de Berg,
+ * Otfried Cheong, Marc van Kreveld, Mark Overmars] - Chapter 14)
+ *
+ * One can instantiate the class template with a point type and a value for
+ * the maximal number of points per node. The point-type have to provide
+ * the access to its coordinates via operator[] and for debugging
+ * purposes operator<<)
+ */
+template <typename POINT> class QuadTree {
+public:
+	enum Quadrant {
+		NE = 0, //!< north east
+		NW, //!< north west
+		SW, //!< south west
+		SE  //!< south east
+	};
+	/**
+	 * This is the constructor for class QuadTree. It takes two points
+	 * (lower left and the upper right points).
+	 * @param ll lower left point of the square
+	 * @param ur upper right point of the square
+	 */
+	QuadTree(POINT const& ll, POINT const& ur, size_t max_points_per_node) :
+		_father (NULL), _ll (ll), _ur (ur), _depth (0), _is_leaf (true),
+		_max_points_per_node (max_points_per_node)
+	{
+		assert (_max_points_per_node > 0);
+
+		// init childs
+		for (size_t k(0); k<4; k++) {
+			_childs[k] = NULL;
+		}
+
+		if ((_ur[0] - _ll[0]) > (_ur[1] - _ll[1])) {
+			_ur[1] = _ll[1] + _ur[0] - _ll[0];
+		} else {
+			_ur[0] = _ll[0] + _ur[1] - _ll[1];
+		}
+//#ifndef NDEBUG
+//		std::cerr << "lower left: " << _ll << ", upper right: " << _ur << ", depth " << _depth << std::endl;
+//#endif
+	}
+
+	/**
+	 * destructor
+	 */
+	~QuadTree()
+	{
+		if (_is_leaf) {
+			for (size_t k(0); k<4; k++) {
+				delete _childs[k];
+			}
+		}
+	}
+
+	/**
+	 * This method adds the given point to the quadtree. If necessary,
+	 * the quadtree will be extended.
+	 * @param pnt the point
+	 * @return If the point can be inserted the method returns true, else false.
+	 */
+	bool addPoint (POINT * pnt)
+	{
+		if ((*pnt)[0] < _ll[0]) return false;
+		if ((*pnt)[0] > _ur[0]) return false;
+		if ((*pnt)[1] < _ll[1]) return false;
+		if ((*pnt)[1] > _ur[1]) return false;
+
+		if (!_is_leaf) {
+			for (size_t k(0); k<4; k++) {
+				if (_childs[k]->addPoint (pnt))
+					return true;
+			}
+		}
+
+		// check if point is already in quadtree
+		bool pnt_in_quadtree (false);
+		double equal_pnt_dist (MathLib::fastpow(2, _depth) * fabs(_ll[0] - _ur[0]) * 1e-6);
+		for (size_t k(0); k<_pnts.size() && !pnt_in_quadtree; k++) {
+			const double sqr_dist (MathLib::sqrDist(_pnts[k]->getData(), pnt->getData()));
+			if (sqr_dist < equal_pnt_dist) {
+				pnt_in_quadtree = true;
+			}
+		}
+		if (!pnt_in_quadtree) {
+			_pnts.push_back (pnt);
+		} else {
+			return false;
+		}
+
+		if (_pnts.size () > _max_points_per_node) {
+			splitNode ();
+		}
+		return true;
+	}
+
+	/**
+	 * This method balances the quadtree, i.e., it will be inserted nodes
+	 * such that the depth between neighbored leafs is at most one. If you want
+	 * to create a mesh (for instance with GMSH) you can use this method to
+	 * improve the mesh quality. The balance method should be used after
+	 * inserting all points.
+	 */
+	void balance ()
+	{
+		std::list<QuadTree<POINT>*> leaf_list;
+		getLeafs (leaf_list);
+
+		while (!leaf_list.empty()) {
+			QuadTree<POINT>* node (leaf_list.front());
+			leaf_list.pop_front ();
+
+			if (node->isLeaf()) {
+				if (needToRefine (node)) {
+					node->splitNode ();
+					leaf_list.push_back (node->getChild(NE));
+					leaf_list.push_back (node->getChild(NW));
+					leaf_list.push_back (node->getChild(SW));
+					leaf_list.push_back (node->getChild(SE));
+
+					// check if north neighbor has to be refined
+					QuadTree<POINT>* north_neighbor (node->getNorthNeighbor());
+					if (north_neighbor != NULL) {
+						if (north_neighbor->getDepth() < node->getDepth ()) {
+							if (north_neighbor->isLeaf()) {
+								leaf_list.push_back (north_neighbor);
+							}
+						}
+					}
+
+					// check if west neighbor has to be refined
+					QuadTree<POINT>* west_neighbor (node->getWestNeighbor());
+					if (west_neighbor != NULL) {
+						if (west_neighbor->getDepth() < node->getDepth ()) {
+							if (west_neighbor->isLeaf()) {
+								leaf_list.push_back (west_neighbor);
+							}
+						}
+					}
+
+					// check if south neighbor has to be refined
+					QuadTree<POINT>* south_neighbor (node->getSouthNeighbor());
+					if (south_neighbor != NULL) {
+						if (south_neighbor->getDepth() < node->getDepth ()) {
+							if (south_neighbor->isLeaf()) {
+								leaf_list.push_back (south_neighbor);
+							}
+						}
+					}
+
+					// check if east neighbor has to be refined
+					QuadTree<POINT>* east_neighbor (node->getEastNeighbor());
+					if (east_neighbor != NULL) {
+						if (east_neighbor->getDepth() < node->getDepth ()) {
+							if (east_neighbor->isLeaf()) {
+								leaf_list.push_back (east_neighbor);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * add all leafs of the quadtree to the list
+	 * @param leaf_list list of leafs
+	 */
+	void getLeafs (std::list<QuadTree<POINT>*>& leaf_list)
+	{
+		if (_is_leaf) {
+			leaf_list.push_back (this);
+		} else {
+			for (size_t k(0); k<4; k++) {
+				_childs[k]->getLeafs (leaf_list);
+			}
+		}
+	}
+
+	const std::vector<POINT*>& getPoints () const { return _pnts; }
+
+	void getSquarePoints (POINT& ll, POINT& ur) const
+	{
+		ll = _ll;
+		ur = _ur;
+	}
+
+	void getLeaf (const POINT& pnt, POINT& ll, POINT& ur)
+	{
+		if (this->isLeaf()) {
+			ll = _ll;
+			ur = _ur;
+		} else {
+			if (pnt[0] <= 0.5*(_ur[0]+_ll[0])) { // WEST
+				if (pnt[1] <= 0.5*(_ur[1]+_ll[1])) { // SOUTH
+					_childs[SW]->getLeaf (pnt, ll, ur);
+				} else { // NORTH
+					_childs[NW]->getLeaf (pnt, ll, ur);
+				}
+			} else { // EAST
+				if (pnt[1] <= 0.5*(_ur[1]+_ll[1])) { // SOUTH
+					_childs[SE]->getLeaf (pnt, ll, ur);
+				} else { // NORTH
+					_childs[NE]->getLeaf (pnt, ll, ur);
+				}
+			}
+		}
+	}
+
+	void getQuadTree (std::vector<POINT*>& pnts, std::vector<GEOLIB::Polyline*>& plys) const
+	{
+		size_t pnt_pos (pnts.size());
+		pnts.push_back (new POINT (_ll));
+		pnts.push_back (new POINT (_ur[0], _ll[1], _ll[2]));
+		pnts.push_back (new POINT (_ur));
+		pnts.push_back (new POINT (_ll[0], _ur[1], _ll[2]));
+
+		if (_father == NULL) {
+			size_t ply_pos (plys.size());
+			plys.push_back (new Polyline (pnts));
+			for (size_t i(0); i<4; i++)
+				plys[ply_pos]->addPoint (pnt_pos+i);
+			plys[ply_pos]->addPoint (pnt_pos);
+		}
+
+		if (! _is_leaf) {
+			for (size_t i(0); i<4; i++) {
+				_childs[i]->getQuadTree (pnts, plys);
+			}
+		}
+	}
+
+	QuadTree<POINT> const * getFather ()
+	{
+		return _father;
+	}
+
+	QuadTree<POINT> const * getChild (Quadrant quadrant) const
+	{
+		return _childs[quadrant];
+	}
+
+
+private:
+	QuadTree<POINT> * getChild (Quadrant quadrant)
+	{
+		return _childs[quadrant];
+	}
+
+	bool isLeaf () const { return _is_leaf; }
+
+	bool isChild (QuadTree<POINT> const * const tree, Quadrant quadrant) const
+	{
+		if (_childs[quadrant] == tree) return true;
+		return false;
+	}
+
+	QuadTree<POINT>* getNorthNeighbor () const
+	{
+		if (this->_father == NULL) { // root of QuadTree
+			return NULL;
+		}
+
+		if (this->_father->isChild (this, SW))
+			return this->_father->getChild (NW);
+		if (this->_father->isChild (this, SE))
+			return this->_father->getChild (NE);
+
+		QuadTree<POINT>* north_neighbor (this->_father->getNorthNeighbor ());
+		if (north_neighbor == NULL)
+			return NULL;
+		if (north_neighbor->isLeaf())
+			return north_neighbor;
+
+		if (this->_father->isChild (this, NW))
+			return north_neighbor->getChild (SW);
+		else
+			return north_neighbor->getChild (SE);
+	}
+
+	QuadTree<POINT>* getSouthNeighbor () const
+	{
+		if (this->_father == NULL) { // root of QuadTree
+			return NULL;
+		}
+
+		if (this->_father->isChild (this, NW))
+			return this->_father->getChild (SW);
+		if (this->_father->isChild (this, NE))
+			return this->_father->getChild (SE);
+
+		QuadTree<POINT>* south_neighbor (this->_father->getSouthNeighbor ());
+		if (south_neighbor == NULL)
+			return NULL;
+		if (south_neighbor->isLeaf())
+			return south_neighbor;
+
+		if (this->_father->isChild (this, SW))
+			return south_neighbor->getChild (NW);
+		else
+			return south_neighbor->getChild (NE);
+	}
+
+	QuadTree<POINT>* getEastNeighbor () const
+	{
+		if (this->_father == NULL) { // root of QuadTree
+			return NULL;
+		}
+
+		if (this->_father->isChild (this, NW))
+			return this->_father->getChild (NE);
+		if (this->_father->isChild (this, SW))
+			return this->_father->getChild (SE);
+
+		QuadTree<POINT>* east_neighbor (this->_father->getEastNeighbor ());
+		if (east_neighbor == NULL)
+			return NULL;
+		if (east_neighbor->isLeaf())
+			return east_neighbor;
+
+		if (this->_father->isChild (this, SE))
+			return east_neighbor->getChild (SW);
+		else
+			return east_neighbor->getChild (NW);
+	}
+
+	QuadTree<POINT>* getWestNeighbor () const
+	{
+		if (this->_father == NULL) { // root of QuadTree
+			return NULL;
+		}
+
+		if (this->_father->isChild (this, NE))
+			return this->_father->getChild (NW);
+		if (this->_father->isChild (this, SE))
+			return this->_father->getChild (SW);
+
+		QuadTree<POINT>* west_neighbor (this->_father->getWestNeighbor ());
+		if (west_neighbor == NULL)
+			return NULL;
+		if (west_neighbor->isLeaf())
+			return west_neighbor;
+
+		if (this->_father->isChild (this, SW))
+			return west_neighbor->getChild (SE);
+		else
+			return west_neighbor->getChild (NE);
+	}
+
+	size_t getDepth () const { return _depth; }
+
+	/**
+	 * private constructor
+	 * @param ll lower left point
+	 * @param ur upper right point
+	 * @param father father in the tree
+	 * @param depth depth of the node
+	 * @return
+	 */
+	QuadTree (POINT const& ll, POINT const& ur, QuadTree* father, size_t depth, size_t max_points_per_node) :
+		_father (father), _ll (ll), _ur (ur), _depth (depth), _is_leaf (true),
+		_max_points_per_node (max_points_per_node)
+	{
+		// init childs
+		for (size_t k(0); k<4; k++) {
+			_childs[k] = NULL;
+		}
+
+//#ifndef NDEBUG
+//		std::cerr << "lower left: " << _ll << ", upper right: " << _ur << ", depth: " << _depth << std::endl;
+//#endif
+	}
+
+	void splitNode ()
+	{
+		// create childs
+		POINT mid_point(_ll);
+		mid_point[0] += (_ur[0] - _ll[0]) / 2.0;
+		mid_point[1] += (_ur[1] - _ll[1]) / 2.0;
+		_childs[0] = new QuadTree<POINT> (mid_point, _ur, this, _depth + 1, _max_points_per_node); // north east
+		POINT h_ll(mid_point), h_ur(mid_point);
+		h_ll[0] = _ll[0];
+		h_ur[1] = _ur[1];
+		_childs[1] = new QuadTree<POINT> (h_ll, h_ur, this, _depth + 1, _max_points_per_node); // north west
+		_childs[2] = new QuadTree<POINT> (_ll, mid_point, this, _depth + 1, _max_points_per_node); // south west
+		h_ll = _ll;
+		h_ll[0] = mid_point[0];
+		h_ur = _ur;
+		h_ur[1] = mid_point[1];
+		_childs[3] = new QuadTree<POINT> (h_ll, h_ur, 	this, _depth + 1, _max_points_per_node); // south east
+
+		// distribute points to sub quadtrees
+		for (size_t j(0); j < _pnts.size(); j++) {
+			bool nfound(true);
+			for (size_t k(0); k < 4 && nfound; k++) {
+				if (_childs[k]->addPoint(_pnts[j])) {
+					nfound = false;
+				}
+			}
+		}
+		_pnts.clear();
+		_is_leaf = false;
+	}
+
+	bool needToRefine (QuadTree<POINT>* node)
+	{
+		QuadTree<POINT>* north_neighbor (node->getNorthNeighbor ());
+		if (north_neighbor != NULL) {
+			if (north_neighbor->getDepth() == node->getDepth()) {
+				if (! north_neighbor->isLeaf ()) {
+					if (! (north_neighbor->getChild(SW))->isLeaf()) {
+						return true;
+					}
+					if (! (north_neighbor->getChild(SE))->isLeaf()) {
+						return true;
+					}
+				}
+			}
+		}
+
+		QuadTree<POINT>* west_neighbor (node->getWestNeighbor ());
+		if (west_neighbor != NULL) {
+			if (west_neighbor->getDepth() == node->getDepth()) {
+				if (! west_neighbor->isLeaf ()) {
+					if (! (west_neighbor->getChild(SE))->isLeaf()) {
+						return true;
+					}
+					if (! (west_neighbor->getChild(NE))->isLeaf()) {
+						return true;
+					}
+				}
+			}
+		}
+
+		QuadTree<POINT>* south_neighbor (node->getSouthNeighbor ());
+		if (south_neighbor != NULL) {
+			if (south_neighbor->getDepth() == node->getDepth()) {
+				if (!south_neighbor->isLeaf()) {
+					if (!(south_neighbor->getChild(NE))->isLeaf()) {
+						return true;
+					}
+					if (!(south_neighbor->getChild(NW))->isLeaf()) {
+						return true;
+					}
+				}
+			}
+		}
+
+		QuadTree<POINT>* east_neighbor (node->getEastNeighbor ());
+		if (east_neighbor != NULL) {
+			if (east_neighbor->getDepth() == node->getDepth()) {
+				if (! east_neighbor->isLeaf ()) {
+					if (! (east_neighbor->getChild(NW))->isLeaf()) {
+						return true;
+					}
+					if (! (east_neighbor->getChild(SW))->isLeaf()) {
+						return true;
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	QuadTree<POINT>* _father;
+	/**
+	 * childs are sorted:
+	 *   _childs[0] is north east child
+	 *   _childs[1] is north west child
+	 *   _childs[2] is south west child
+	 *   _childs[3] is south east child
+	 */
+	QuadTree<POINT>* _childs[4];
+	/**
+	 * lower left point of the square
+	 */
+	POINT _ll;
+	/**
+	 * upper right point of the square
+	 */
+	POINT _ur;
+	size_t _depth;
+	std::vector<POINT *> _pnts;
+	bool _is_leaf;
+	/**
+	 * maximum number of points per leaf
+	 */
+	const size_t _max_points_per_node;
+};
+
+}
+
+#endif /* QUADTREE_H_ */
diff --git a/GeoLib/Raster.cpp b/GeoLib/Raster.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ddf5005444ee498329fa5a94ac30bd66b9c45e6e
--- /dev/null
+++ b/GeoLib/Raster.cpp
@@ -0,0 +1,66 @@
+/*
+ * Raster.cpp
+ *
+ *  Created on: Sep 7, 2011
+ *      Author: TF
+ */
+
+#include "Raster.h"
+
+namespace GEOLIB {
+
+Raster::Raster(double cell_size, double no_data_val) :
+	_cell_size(cell_size), _no_data_val(no_data_val)
+{
+}
+
+void Raster::setCellSize(double cell_size)
+{
+	_cell_size = cell_size;
+}
+
+void Raster::setNoDataVal (double no_data_val)
+{
+	_no_data_val = no_data_val;
+}
+
+double* Raster::getRasterFromSurface(Surface const& sfc, size_t &n_x_pnts, size_t &n_y_pnts) const
+{
+	Point const& ll (sfc.getAABB().getMinPoint());
+	Point const& ur (sfc.getAABB().getMaxPoint());
+
+	n_x_pnts = static_cast<size_t>(fabs(ur[0]-ll[0]) / _cell_size)+1;
+	n_y_pnts = static_cast<size_t>(fabs(ur[1]-ll[1]) / _cell_size)+1;
+	const size_t n_triangles (sfc.getNTriangles());
+	double *z_vals (new double[n_x_pnts*n_y_pnts]);
+	if (!z_vals) {
+		std::cout << "DEBUG: CreateRaster::getRaster " << n_x_pnts << " x " << n_y_pnts << " to big" << std::endl;
+	}
+	size_t k(0);
+
+	for (size_t r(0); r < n_x_pnts; r++) {
+		for (size_t c(0); c < n_y_pnts; c++) {
+			const double test_pnt[3] = { ll[0] + r*_cell_size, ll[1] + c*_cell_size, 0};
+			for (k=0; k<n_triangles; k++) {
+				if (sfc[k]->containsPoint2D(test_pnt)) {
+					Triangle const * const tri (sfc[k]);
+					// compute coefficients c0, c1, c2 for the plane f(x,y) = c0 x + c1 y + c2
+					double coeff[3] = {0.0, 0.0, 0.0};
+					GEOLIB::getPlaneCoefficients(*tri, coeff);
+					z_vals[r*n_y_pnts+c] = coeff[0] * test_pnt[0] + coeff[1] * test_pnt[1] + coeff[2];
+					break;
+				}
+			}
+			if (k==n_triangles) {
+				z_vals[r*n_y_pnts+c] = _no_data_val;
+			}
+		}
+	}
+
+	return z_vals;
+}
+
+Raster::~Raster()
+{}
+
+}
diff --git a/GeoLib/Raster.h b/GeoLib/Raster.h
new file mode 100644
index 0000000000000000000000000000000000000000..a330638ca4a22c2ab0d023fcd5a569ab1ca4f7d7
--- /dev/null
+++ b/GeoLib/Raster.h
@@ -0,0 +1,29 @@
+/*
+ * Raster.h
+ *
+ *  Created on: Sep 7, 2011
+ *      Author: TF
+ */
+
+#ifndef RASTER_H_
+#define RASTER_H_
+
+#include "Surface.h"
+
+namespace GEOLIB {
+
+class Raster {
+public:
+	Raster(double cell_size=1, double no_data_val=9999);
+	void setCellSize(double cell_size);
+	void setNoDataVal (double no_data_val);
+	double* getRasterFromSurface (Surface const& sfc, size_t &n_x_pnts, size_t &n_y_pnts) const;
+	virtual ~Raster();
+private:
+	double _cell_size;
+	double _no_data_val;
+};
+
+}
+
+#endif /* RASTER_H_ */
diff --git a/GeoLib/SimplePolygonTree.cpp b/GeoLib/SimplePolygonTree.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c3454ac9a29ad31f7cf2ce87d5c3f8cefb366ddc
--- /dev/null
+++ b/GeoLib/SimplePolygonTree.cpp
@@ -0,0 +1,183 @@
+/*
+ * SimplePolygonTree.cpp
+ *
+ *  Created on: Jun 22, 2010
+ *      Author: TF
+ */
+
+#include "SimplePolygonTree.h"
+
+namespace GEOLIB {
+
+SimplePolygonTree::SimplePolygonTree(const Polygon* polygon, SimplePolygonTree* parent) :
+	_node (polygon), _parent (parent)
+{}
+
+SimplePolygonTree::~SimplePolygonTree()
+{}
+
+const Polygon* SimplePolygonTree::getPolygon () const
+{
+	return _node;
+}
+
+bool SimplePolygonTree::isPolygonInside (const SimplePolygonTree* polygon_hierarchy) const
+{
+	const Polygon* polygon (polygon_hierarchy->getPolygon());
+	// check *all* points of polygon
+	size_t n_pnts_polygon (polygon->getNumberOfPoints() - 1), cnt(0);
+	for (size_t k(0); k<n_pnts_polygon && cnt == k; k++) {
+		if (_node->isPntInPolygon (*(polygon->getPoint(k)))) {
+			cnt++;
+		}
+	}
+	// all points of the given polygon are contained in the
+	if (cnt == n_pnts_polygon) return true;
+	else {
+		return false;
+	}
+}
+
+void SimplePolygonTree::insertSimplePolygonTree (SimplePolygonTree* polygon_hierarchy)
+{
+	const Polygon* polygon (polygon_hierarchy->getPolygon());
+	bool nfound (true);
+	for (std::list<SimplePolygonTree*>::const_iterator it (_childs.begin());
+		it != _childs.end() && nfound; it++)
+	{
+		// check all points of polygon
+		size_t n_pnts_polygon (polygon->getNumberOfPoints()), cnt(0);
+		for (size_t k(0); k<n_pnts_polygon && cnt == k; k++) {
+			if (((*it)->getPolygon())->isPntInPolygon (*(polygon->getPoint(k))))
+				cnt++;
+		}
+		// all points of the given polygon are contained in the current polygon
+		if (cnt == n_pnts_polygon) {
+			(*it)->insertSimplePolygonTree (polygon_hierarchy);
+			nfound = false;
+		}
+	}
+	if (nfound)
+		_childs.push_back (polygon_hierarchy);
+}
+
+bool SimplePolygonTree::isGeoObjInside (const GeoObject* geo_obj) const
+{
+	if (dynamic_cast<const Point*>(geo_obj))
+		return _node->isPntInPolygon (*(dynamic_cast<const Point*>(geo_obj)));
+
+	if (dynamic_cast<const Polyline*>(geo_obj))
+		return isPolylineInside (dynamic_cast<const Polyline*>(geo_obj));
+
+	return false;
+}
+
+bool SimplePolygonTree::isPolylineInside (const Polyline* ply) const
+{
+	// check *all* points of polyline
+	size_t n_pnts_polyline (ply->getNumberOfPoints() - 1), cnt(0);
+	for (size_t k(0); k<n_pnts_polyline && cnt == k; k++) {
+		if (_node->isPntInPolygon (*(ply->getPoint(k)))) {
+			cnt++;
+		}
+	}
+	// all points of the given polyline are contained in the polygon
+	if (cnt == n_pnts_polyline) return true;
+
+	return false;
+}
+
+void SimplePolygonTree::insertGeoObj (const GeoObject* geo_obj)
+{
+	// check if the geo object is contained in a child of this node
+	bool nfound (true);
+	for (std::list<SimplePolygonTree*>::const_iterator it (_childs.begin());
+		it != _childs.end() && nfound; it++)
+	{
+		// check Point
+		if (dynamic_cast<const Point*>(geo_obj)) {
+			if (((*it)->getPolygon())->isPntInPolygon (*(dynamic_cast<const Point*>(geo_obj)))) {
+				(*it)->insertGeoObj (geo_obj);
+				nfound = false;
+			}
+		}
+		// check Polyline
+		if (nfound && dynamic_cast<const Polyline*>(geo_obj)) {
+			const Polyline* ply (dynamic_cast<const Polyline*>(geo_obj));
+			size_t n_pnts_polyline (ply->getNumberOfPoints()), cnt(0);
+			// check all points of Polyline
+			for (size_t k(0); k<n_pnts_polyline && cnt == k; k++) {
+				if (((*it)->getPolygon())->isPntInPolygon (*(ply->getPoint(k))))
+					cnt++;
+			}
+			// all points of the given polygon are contained in the current polygon
+			if (cnt == n_pnts_polyline) {
+				(*it)->insertGeoObj (geo_obj);
+				nfound = false;
+			}
+		}
+	}
+
+	if (nfound) {
+		_geo_objs.push_back (geo_obj);
+	}
+
+}
+
+//void SimplePolygonTree::visitAndProcessNodes (FileIO::GMSHInterface& gmsh_io)
+//{
+//	if (getLevel() == 0) {
+//		gmsh_io.writeGMSHPolygon (*_node);
+//
+//		std::list<SimplePolygonTree*>::iterator it (_childs.begin());
+//		while (it != _childs.end()) {
+//			(*it)->_visitAndProcessNodes (gmsh_io);
+//			it++;
+//		}
+//		gmsh_io.writePlaneSurface ();
+//	}
+//}
+
+//void SimplePolygonTree::_visitAndProcessNodes (FileIO::GMSHInterface& gmsh_io)
+//{
+//	gmsh_io.writeGMSHPolygon (*_node);
+//
+//	std::list<SimplePolygonTree*>::iterator it (_childs.begin());
+//	while (it != _childs.end()) {
+//		(*it)->_visitAndProcessNodes (gmsh_io);
+//		it++;
+//	}
+//}
+
+size_t SimplePolygonTree::getLevel () const
+{
+	if (_parent == NULL) return 0;
+	else return 1+_parent->getLevel ();
+}
+
+void createPolygonTree (std::list<SimplePolygonTree*>& list_of_simple_polygon_hierarchies)
+{
+	std::list<SimplePolygonTree*>::iterator it0 (list_of_simple_polygon_hierarchies.begin()), it1;
+	while (it0 != list_of_simple_polygon_hierarchies.end()) {
+		it1 = it0;
+		it1++;
+		while (it1 != list_of_simple_polygon_hierarchies.end()) {
+			if ((*it0)->isPolygonInside (*it1)) {
+				(*it0)->insertSimplePolygonTree (*it1);
+				it1 = list_of_simple_polygon_hierarchies.erase (it1);
+			} else {
+				if ((*it1)->isPolygonInside (*it0)) {
+					(*it1)->insertSimplePolygonTree (*it0);
+					(*it1)->insertSimplePolygonTree (*it0);
+					it0 = list_of_simple_polygon_hierarchies.erase (it0);
+				}
+
+				it1++;
+			}
+		}
+		it0++;
+	}
+}
+
+
+} // end namespace GEOLIB
diff --git a/GeoLib/SimplePolygonTree.h b/GeoLib/SimplePolygonTree.h
new file mode 100644
index 0000000000000000000000000000000000000000..688364df5f75f1753d988cdb7370a95ae20f2c35
--- /dev/null
+++ b/GeoLib/SimplePolygonTree.h
@@ -0,0 +1,57 @@
+/*
+ * SimplePolygonTree.h
+ *
+ *  Created on: Jun 22, 2010
+ *      Author: TF
+ */
+
+#ifndef SIMPLEPOLYGONTREE_H_
+#define SIMPLEPOLYGONTREE_H_
+
+#include "Polygon.h"
+// FileIO
+#include "MeshIO/GMSHInterface.h"
+
+namespace GEOLIB {
+
+/**
+ * \brief This class computes and stores the topological relations between
+ * polygons and geometric objects like Point and Polyline.
+ *
+ * It is used to generate a proper input file for gmsh.
+ */
+class SimplePolygonTree {
+public:
+	SimplePolygonTree(const Polygon* polygon, SimplePolygonTree* parent = NULL);
+	virtual ~SimplePolygonTree();
+
+	const Polygon* getPolygon () const;
+	const std::list<SimplePolygonTree*>& getChilds() const;
+	const std::list<GeoObject*>& getGeoObjects () const;
+	size_t getLevel () const;
+
+	bool isPolygonInside (const SimplePolygonTree* polygon_tree) const;
+	void insertSimplePolygonTree (SimplePolygonTree* polygon_tree);
+//	void visitAndProcessNodes (FileIO::GMSHInterface& gmsh_io);
+
+	bool isGeoObjInside (const GeoObject* geo_obj) const;
+	void insertGeoObj (const GeoObject* geo_obj);
+
+private:
+	bool isPolylineInside (const Polyline* ply) const;
+//	void _visitAndProcessNodes (FileIO::GMSHInterface& gmsh_io);
+	const Polygon* _node;
+	SimplePolygonTree* _parent;
+	std::list<SimplePolygonTree*> _childs;
+	std::list<const GeoObject*> _geo_objs;
+};
+
+/**
+ * creates from a list of simple polygons a list
+ * @param list_of_simple_polygon_trees
+ */
+void createPolygonTree (std::list<SimplePolygonTree*>& list_of_simple_polygon_trees);
+
+}
+
+#endif /* SIMPLEPOLYGONTREE_H_ */
diff --git a/GeoLib/Station.cpp b/GeoLib/Station.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..81a67b624b815be342c2307f0f16a84fddb984ff
--- /dev/null
+++ b/GeoLib/Station.cpp
@@ -0,0 +1,380 @@
+/**
+ * \file Station.cpp
+ * KR Initial implementation
+ */
+
+#include <cstdlib>
+#include <fstream>
+#include <iomanip>
+#include <cmath>
+// Base
+#include "StringTools.h"
+#include "DateTools.h"
+// GEOLIB
+#include "Station.h"
+
+
+namespace GEOLIB {
+
+Station::Station(double x, double y, double z, std::string name, Color* const color) :
+	Point (x,y,z), _name(name), _type(Station::STATION), _color(color)
+{
+	addProperty("x", &getX, &Station::setX);
+	addProperty("y", &getY, &Station::setY);
+	addProperty("z", &getZ, &Station::setZ);
+}
+
+Station::Station(Point* coords, std::string name, Color* const color) :
+	Point (*coords), _name(name), _type(Station::STATION), _color(color)
+{
+	addProperty("x", &getX, &Station::setX);
+	addProperty("y", &getY, &Station::setY);
+	addProperty("z", &getZ, &Station::setZ);
+}
+
+void Station::addProperty(std::string pname, double (*getFct)(void*), void (*set)(void*, double))
+{
+	STNProperty p;
+	p.name = pname;
+	p.get = getFct;
+	p.set = set;
+	_properties.push_back(p);
+}
+
+
+Station::~Station()
+{
+	delete _color;
+}
+
+void Station::setColor(unsigned char r, unsigned char g, unsigned char b)
+{
+	(*_color)[0]=r;
+	(*_color)[1]=g;
+	(*_color)[2]=b;
+}
+
+void Station::setColor(const Color* const color)
+{
+	(*_color)[0]=(*color)[0];
+	(*_color)[1]=(*color)[1];
+	(*_color)[2]=(*color)[2];
+}
+
+Station* Station::createStation(const std::string & line)
+{
+	std::list<std::string>::const_iterator it;
+	Station* station = new Station();
+	std::list<std::string> fields = splitString(line, '\t');
+
+	if (fields.size() >= 3) {
+
+		it = fields.begin();
+		station->_name  = *it;
+		(*station)[0]     = strtod((replaceString(",", ".", *(++it))).c_str(), NULL);
+		(*station)[1]     = strtod((replaceString(",", ".", *(++it))).c_str(), NULL);
+		if (++it != fields.end())
+		{
+			(*station)[2] = strtod((replaceString(",", ".", *it)).c_str(), NULL);
+		}
+	}
+	else
+	{
+		std::cout << "Station::createStation() - Unexpected file format..." << std::endl;
+		delete station;
+		return NULL;
+	}
+	return station;
+
+}
+
+Station* Station::createStation(const std::string &name, double x, double y, double z)
+{
+	Station* station = new Station();
+	station->_name = name;
+	(*station)[0] = x;
+	(*station)[1] = y;
+	(*station)[2] = z;
+	return station;
+}
+
+const std::map<std::string, double> Station::getProperties()
+{
+	std::map<std::string, double> propertyMap;
+
+	for (int i=0; i<static_cast<int>(_properties.size()); i++)
+	{
+		double (*getFct)(void*) = _properties[i].get;
+		//setFct set = _properties[i].set;
+		propertyMap[_properties[i].name] = (*getFct)((void*)this);
+	}
+
+	return propertyMap;
+}
+
+bool Station::inSelection(const std::vector<PropertyBounds> &bounds)
+{
+	double value;
+	for (size_t i=0; i<bounds.size(); i++)
+	{
+		for (size_t j=0; j<_properties.size(); j++)
+		{
+			if (_properties[j].name.compare(bounds[i].getName())==0)
+			{
+				double (*get)(void*) = _properties[j].get;
+				value = (*get)((void*)this);
+				if (!(value >= bounds[i].getMin() && value <= bounds[i].getMax())) return false;
+			}
+		}
+	}
+	return true;
+}
+
+
+
+////////////////////////
+// The Borehole class //
+////////////////////////
+
+StationBorehole::StationBorehole(double x, double y, double z) :
+	Station (x,y,z), _zCoord(0), _depth(0), _date(0)
+{
+	_type = Station::BOREHOLE;
+	addProperty("date", &StationBorehole::getDate, &StationBorehole::setDate);
+	addProperty("depth", &StationBorehole::getDepth, &StationBorehole::setDepth);
+
+	// add first point of borehole
+	_profilePntVec.push_back(this);
+	_soilName.push_back("");
+}
+
+StationBorehole::~StationBorehole(void)
+{
+	// deletes profile vector of borehole, starting at layer 1
+	// the first point is NOT deleted as it points to the station object itself
+	for (size_t k(1); k<_profilePntVec.size(); k++) delete _profilePntVec[k];
+}
+
+int StationBorehole::find(const std::string &str)
+{
+	size_t size = _soilName.size();
+	for (size_t i=0; i<size; i++)
+	{
+		if (_soilName[i].find(str)==0) return 1;
+	}
+	return 0;
+}
+
+int StationBorehole::readStratigraphyFile(const std::string &path, std::vector<std::list<std::string> > &data)
+{
+    std::string line;
+	std::ifstream in( path.c_str() );
+
+	if (!in.is_open())
+    {
+		std::cout << "StationBorehole::readStratigraphyFile() - Could not open file..." << std::endl;
+		return 0;
+	}
+
+	while ( getline(in, line) )
+	{
+		std::list<std::string> fields = splitString(line, '\t');
+		data.push_back(fields);
+	}
+
+	in.close();
+
+	return 1;
+}
+
+int StationBorehole::addStratigraphy(const std::string &path, StationBorehole* borehole)
+{
+	std::vector<std::list<std::string> > data;
+	if (readStratigraphyFile(path, data))
+	{
+		size_t size = data.size();
+		for (size_t i=0; i<size; i++)
+			addLayer(data[i], borehole);
+
+		// check if a layer is missing
+		size = borehole->_soilName.size();
+		std::cout << "StationBorehole::addStratigraphy ToDo" << std::endl;
+	//	for (size_t i=0; i<size; i++)
+	//	{
+	//		if ((borehole->_soilLayerThickness[i] == -1) ||(borehole->_soilName[i].compare("") == 0))
+	//		{
+	//			borehole->_soilLayerThickness.clear();
+	//			borehole->_soilName.clear();
+	//
+	//			cout << "StationBorehole::addStratigraphy() - Profile incomplete (Borehole " << borehole->_name << ", Layer " << (i+1) << " missing).\n";
+	//
+	//			return 0;
+	//		}
+	//	}
+	}
+	else
+	{
+		borehole->addSoilLayer(borehole->getDepth(), "depth");
+	}
+
+	return 1;
+}
+
+int StationBorehole::addLayer(std::list<std::string> fields, StationBorehole* borehole)
+{
+	if (fields.size() >= 4) /* check if there are enough fields to create a borehole object */
+	{
+		if (fields.front().compare(borehole->_name) == 0) /* check if the name of the borehole matches the name in the data */
+		{
+			fields.pop_front();
+
+			// int layer = atoi(fields.front().c_str());
+			fields.pop_front();
+
+			std::cerr << "StationBorehole::addLayer - assuming correct order" << std::endl;
+			double thickness(strtod(replaceString(",", ".", fields.front()).c_str(), 0));
+			fields.pop_front();
+			borehole->addSoilLayer(thickness, fields.front());
+		}
+	} else {
+		std::cout
+				<< "StationBorehole::addLayer() - Unexpected file format (Borehole "
+				<< borehole->_name << ")..." << std::endl;
+		return 0;
+	}
+	return 1;
+}
+
+int StationBorehole::addStratigraphies(const std::string &path, std::vector<Point*> *boreholes)
+{
+	std::vector<std::list<std::string> > data;
+
+	if (readStratigraphyFile(path, data))
+	{
+		std::string name;
+
+		size_t it=0;
+		size_t nBoreholes = data.size();
+		for (size_t i=0; i<nBoreholes; i++) {
+			std::list<std::string> fields = data[i];
+
+			if (fields.size() >= 4) {
+				name = static_cast<StationBorehole*>((*boreholes)[it])->_name;
+				if ( fields.front().compare(name) != 0 ) {
+						if (it < boreholes->size()-1) it++;
+				}
+
+				fields.pop_front();
+				//the method just assumes that layers are read in correct order
+				fields.pop_front();
+				double thickness (strtod(replaceString(",", ".", fields.front()).c_str(), 0));
+				fields.pop_front();
+				std::string soil_name (fields.front());
+				fields.pop_front();
+				static_cast<StationBorehole*>((*boreholes)[it])->addSoilLayer(thickness, soil_name);
+			} else
+			{
+				std::cout << "StationBorehole::addStratigraphies() - Unexpected file format..." << std::endl;
+				//return 0;
+			}
+		}
+	}
+	else
+	{
+		createSurrogateStratigraphies(boreholes);
+	}
+
+	return 1;
+}
+
+
+StationBorehole* StationBorehole::createStation(const std::string &line)
+{
+	StationBorehole* borehole = new StationBorehole();
+	std::list<std::string> fields = splitString(line, '\t');
+
+	if (fields.size()      >= 5) {
+		borehole->_name     = fields.front();
+		fields.pop_front();
+		(*borehole)[0]      = strtod((replaceString(",", ".", fields.front())).c_str(), NULL);
+		fields.pop_front();
+		(*borehole)[1]      = strtod((replaceString(",", ".", fields.front())).c_str(), NULL);
+		fields.pop_front();
+		(*borehole)[2]      = strtod((replaceString(",", ".", fields.front())).c_str(), NULL);
+		fields.pop_front();
+		borehole->_depth	= strtod((replaceString(",", ".", fields.front())).c_str(), NULL);
+		fields.pop_front();
+		if (fields.empty())
+			borehole->_date = 0;
+		else
+		{
+			borehole->_date = strDate2double(fields.front());
+			fields.pop_front();
+		}
+	}
+	else
+	{
+		std::cout << "Station::createStation() - Unexpected file format..." << std::endl;
+		delete borehole;
+		return NULL;
+	}
+	return borehole;
+}
+
+StationBorehole* StationBorehole::createStation(const std::string &name, double x, double y, double z, double depth, std::string date)
+{
+	StationBorehole* station = new StationBorehole();
+	station->_name  = name;
+	(*station)[0]   = x;
+	(*station)[1]   = y;
+	(*station)[2]   = z;
+	station->_depth = depth;
+	if (date.compare("0000-00-00")) station->_date  = xmlDate2double(date);
+	return station;
+}
+
+void StationBorehole::createSurrogateStratigraphies(std::vector<Point*> *boreholes)
+{
+	size_t nBoreholes = boreholes->size();
+	for (size_t i=0; i<nBoreholes; i++)
+	{
+		StationBorehole* bore = static_cast<StationBorehole*>((*boreholes)[i]);
+		bore->addSoilLayer(bore->getDepth(), "depth");
+	}
+}
+
+void StationBorehole::addSoilLayer ( double thickness, const std::string &soil_name)
+{
+	/*
+	// TF - Altmark
+	if (_profilePntVec.empty())
+		addSoilLayer ((*this)[0], (*this)[1], (*this)[2]-thickness, soil_name);
+	else {
+		size_t idx (_profilePntVec.size());
+		// read coordinates from last above
+		double x((*_profilePntVec[idx-1])[0]);
+		double y((*_profilePntVec[idx-1])[1]);
+		double z((*_profilePntVec[idx-1])[2]-thickness);
+		addSoilLayer (x, y, z, soil_name);
+	}
+	*/
+
+	// KR - Bode
+	if (_profilePntVec.empty())
+		addSoilLayer ((*this)[0], (*this)[1], (*this)[2], "");
+
+	size_t idx (_profilePntVec.size());
+	double x((*_profilePntVec[idx-1])[0]);
+	double y((*_profilePntVec[idx-1])[1]);
+	double z((*_profilePntVec[0])[2]-thickness);
+	addSoilLayer (x, y, z, soil_name);
+
+}
+
+void StationBorehole::addSoilLayer ( double x, double y, double z, const std::string &soil_name)
+{
+	_profilePntVec.push_back (new Point (x, y, z));
+	_soilName.push_back(soil_name);
+}
+
+} // namespace
diff --git a/GeoLib/Station.h b/GeoLib/Station.h
new file mode 100644
index 0000000000000000000000000000000000000000..5a6943398eeb90699f37bc83d7cac77f4903652d
--- /dev/null
+++ b/GeoLib/Station.h
@@ -0,0 +1,276 @@
+/**
+ * \file Station.h
+ * KR Initial implementation
+ */
+
+#ifndef GEO_STATION_H
+#define GEO_STATION_H
+
+#include <string>
+#include <list>
+#include <vector>
+#include <map>
+
+#include "Polyline.h"
+#include "Point.h"
+#include "Color.h"
+#include "PropertyBounds.h"
+
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ *
+ * \brief An observation station as a geometric object (i.e. basically a Point with some additional information.
+ *
+ * An observation station as a geometric object. Such a station is basically a point object
+ * with some additional information such as colour, a name, etc.
+ *
+ * Notes concerning the property-system used in this class:
+ * Variables of Station and derived classes can be defined to be "properties" of this class.
+ * Certain functions in the GUI allow you to modify aspects of the visualisation based on these
+ * properties (e.g. filtering operations such as "display only boreholes drilled after 1990 with a
+ * depth between 400-800m").
+ * To make use of this functionality you need to define properties using the "Station::addProperty()"-method.
+ * Parameters for this function include the name of the property as well as a method to read and write the
+ * value of the associated variable (see documentation for "addProperty" for details). Furthermore, these read
+ * and write-functions need to be actually implemented as static functions to avoid casting problems with the
+ * function pointers used to dynamically connect the GUI functionality to the variables defined within the
+ * station-classes. Please refer to the documentation of the properties defined below for details.
+ */
+class Station : public Point
+{
+
+protected:
+
+	//typedef double (Station::*getFct)();
+	//typedef void (Station::*setFct)(double);
+
+	/**
+	 * \brief Container for station-properties. 
+	 * Each property consists of a name, a get- and a set-function.
+	 * Please refer to Station::addProperty for details.
+	 */
+	struct STNProperty
+	{
+		std::string name;
+		double (*get)(void*);
+		void (*set)(void*, double);
+	};
+
+public:
+	/// Signals if the object is a "simple" Station or a Borehole (i.e. containing borehole-specific information).
+	enum StationType
+	{
+		STATION  = 1,
+		BOREHOLE = 2
+	};
+
+	/**
+	 * \brief Constructor
+	 *
+	 * Constructor initialising a Station object
+	 * \param x The x-coordinate of the station.
+	 * \param y The y-coordinate of the station.
+	 * \param z The z-coordinate of the station.
+	 * \param name The name of the station.
+	 * \param color The color of the station in visualisation.
+	 */
+	Station(double x = 0.0, double y = 0.0, double z = 0.0, std::string name = "", Color* const color = new Color(0,128,0));
+
+	Station(Point* coords, std::string name = "", Color* const color = new Color(0,128,0));
+
+
+	virtual ~Station();
+
+	/**
+	 * \brief Defines a property for this class.
+	 *
+	 * Variables in Station and its derived classes can be defined to be properties of this station.
+	 * This definition consists of a name for the property as well as a function pointer to a method to
+	 * read and to write this variable.
+	 * Due to inheritance these function pointers only work correctly if the read and write functions are
+	 * implemented as static functions, i.e. both the read and the write functin get a void-pointer to the
+	 * actual station-object. This pointer is then casted to the correct class and the respective value can
+	 * then be read or written dynamically from that object. It is highly recommended to define both the
+	 * read and write function as protected because it does not actually make sense for these functions to be
+	 * static except in the context of function pointers. Please refer to the examples below, i.e. the getX
+	 * and setX methods.
+	 * \param pname The name of the property.
+	 * \param get A function pointer to a static read function for the variable referred to by pname
+	 * \param set A function pointer to a static write function for the variable referred to by pname
+	 * \return
+	 */
+	void addProperty(std::string pname, double (*get)(void*), void (*set)(void*, double));
+
+	/// Sets colour for this station
+	void setColor(unsigned char r, unsigned char g, unsigned char b);
+
+	/// Sets colour for this station
+	void setColor(const Color* color);
+
+	/// returns the colour for this station
+	Color* getColor () { return _color; }
+
+	/// Returns a map containing all the properties of that station type.
+	const std::map<std::string, double> getProperties();
+
+	/// Determines if the station's parameters are within the the bounds of the current selection (see property system for details)
+	bool inSelection(const std::vector<PropertyBounds> &bounds);
+
+	/// Returns true if all properties of this stations are within the boundaries given by \param bounds and false otherwise
+	bool inSelection(std::map<std::string, double> properties) const;
+
+	/// Returns the name of the station.
+	std::string getName() const { return _name; }
+
+	/// Returns the GeoSys-station-type for the station.
+	int type() const { return _type; }
+
+	/// Creates a Station-object from information contained in a string (assuming the string has the right format)
+	static Station* createStation(const std::string &line);
+
+	/// Creates a new station object based on the given parameters.
+	static Station* createStation(const std::string &name, double x, double y, double z);
+
+
+protected:
+	/**
+	 * \brief Returns the x-coordinate of this station. See the detailed documentation for getX() concerning the syntax.
+	 *
+	 * Returns the x-coordinate of this station.
+	 * This function belongs to the property system of Station and return the value for property "x"
+	 * (i.e. the x-coordinate of the station). It is implemented as a static method to avoid casting issues
+	 * related to the function pointer associated with this function. Therefore, this function needs to be
+	 * called "getX((void*)this);". It is highly recommended to define this function as protected because it
+	 * does not actually make sense for these functions to be static except in the context of function pointers.
+	 * \param stnObject A pointer to the station object for which the x-coordinate should be returned, usually (void*)this will work fine.
+	 * \return The x-coordinate for this station.
+	 */
+	static double getX(void* stnObject) { Station* stn = (Station*)stnObject; return (*stn)[0]; }
+	/// Returns the y-coordinate of this station. See the detailed documentation for getX concerning the syntax.
+	static double getY(void* stnObject) { Station* stn = (Station*)stnObject; return (*stn)[1]; }
+	/// Returns the z-coordinate of this station. See the detailed documentation for getX concerning the syntax.
+	static double getZ(void* stnObject) { Station* stn = (Station*)stnObject; return (*stn)[2]; }
+	/// Sets the x-coordinate for this station. See the detailed documentation for getX concerning the syntax.
+	static void setX(void* stnObject, double val) { Station* stn = (Station*)stnObject; (*stn)[0]=val; }
+	/// Sets the y-coordinate for this station. See the detailed documentation for getX concerning the syntax.
+	static void setY(void* stnObject, double val) { Station* stn = (Station*)stnObject; (*stn)[1]=val; }
+	/// Sets the z-coordinate for this station. See the detailed documentation for getX concerning the syntax.
+	static void setZ(void* stnObject, double val) { Station* stn = (Station*)stnObject; (*stn)[2]=val; }
+
+
+	std::string _name;
+	StationType _type;	// GeoSys Station Type
+	std::vector<STNProperty> _properties;
+
+
+private:
+	Color* _color;
+};
+
+
+/********* Boreholes *********/
+
+
+/**
+ * \brief A borehole as a geometric object.
+ *
+ * A borehole inherits Station but has some additional information such as a date, a borehole profile, etc.
+ */
+class StationBorehole : public Station
+{
+
+public:
+	/** constructor initialises the borehole with the given coordinates */
+	StationBorehole(double x = 0.0, double y = 0.0, double z = 0.0);
+	~StationBorehole(void);
+
+	/// Creates a StationBorehole-object from a string (assuming the string has the right format)
+	static StationBorehole* createStation(const std::string &line);
+
+	/// Creates a new borehole object based on the given parameters.
+	static StationBorehole* createStation(const std::string &name, double x, double y, double z, double depth, std::string date = "");
+
+	/// Reads the stratigraphy for a specified station from a file
+	static int addStratigraphy(const std::string &path, StationBorehole* borehole);
+
+	/**
+	 * \brief Reads all stratigraphy information from a file in one go.
+	 *
+	 * Reads all stratigraphy information from a file in one go.
+	 * Be very careful when using this method -- it is pretty fast but it checks nothing and just
+	 * assumes that everything is in right order and will work out fine!
+	 */
+	static int addStratigraphies(const std::string &path, std::vector<Point*> *boreholes);
+
+	/// Finds the given string in the vector of soil-names
+	int find(const std::string &str);
+
+	// Returns the depth of the borehole
+	double getDepth() const { return _depth; }
+
+	/// Returns the date entry for the borehole
+	double getDate() const { return _date; }
+
+	/// Returns a reference to a vector of Points representing the stratigraphy of the borehole (incl. the station-point itself)
+	const std::vector<Point*> &getProfile() const { return _profilePntVec; }
+
+	/// Returns a reference to a vector of soil names for the stratigraphy of the borehole
+	const std::vector<std::string> &getSoilNames() const { return _soilName; }
+
+	/// Sets the depth of the borehole
+	void setDepth( double depth ) { _depth = depth; }
+
+	/// Add a soil layer to the boreholes stratigraphy.
+	void addSoilLayer ( double thickness, const std::string &soil_name);
+
+	/**
+	 * Add a soil layer to the boreholes stratigraphy.
+	 * Note: The given coordinates always mark THE END of the soil layer. The reason behind this is
+	 * that the beginning of the first layer is identical with the position of the borehole. For each
+	 * layer following the beginning is already given by the end of the last layer. This also saves
+	 * a seperate entry in the profile vector for the end of the borehole which in the given notation
+	 * is just the coordinate given for the last soil layer (i.e. the end of that layer).
+	 */
+	void addSoilLayer ( double x, double y, double z, const std::string &soil_name);
+
+
+
+protected:
+	/// Returns the depth of this borehole. Please see the documentation for Station::getX for details concerning the syntax.
+	static double getDepth(void* stnObject)  { StationBorehole* stn = (StationBorehole*)stnObject; return stn->_depth; }
+	/// Returns the date this borehole has been drilled. Please see the documentation for Station::getX for details concerning the syntax.
+	static double getDate(void* stnObject)  { StationBorehole* stn = (StationBorehole*)stnObject; return stn->_date; }
+	/// Sets the depth of this borehole. Please see the documentation for Station::getX for details concerning the syntax.
+	static void setDepth(void* stnObject, double val) { StationBorehole* stn = (StationBorehole*)stnObject; stn->_depth = val; }
+	/// Sets the date when this borehole has been drilled. Please see the documentation for Station::getX for details concerning the syntax.
+	static void setDate(void* stnObject, double val) { StationBorehole* stn = (StationBorehole*)stnObject; stn->_date = val; }
+
+private:
+	/// Adds a layer for the specified borehole profile based on the information given in the stringlist
+	static int addLayer(std::list<std::string> fields, StationBorehole* borehole);
+
+	/// Creates fake stratigraphies of only one layer with a thickness equal to the borehole depth
+	static void createSurrogateStratigraphies(std::vector<Point*> *boreholes);
+
+	/// Reads the specified file containing borehole stratigraphies into an vector of stringlists
+	static int readStratigraphyFile(const std::string &path, std::vector<std::list<std::string> > &data);
+
+	//long profile_type;
+	//std::vector<long> _soilType;
+	double _zCoord; // height at which the borehole officially begins (this might _not_ be the actual elevation)
+	double _depth;	// depth of the borehole
+	double _date;	// date when the borehole has been drilled
+
+	/// Contains the names for all the soil layers
+	std::vector<std::string> _soilName;
+
+	/// Contains the points for the lower boundaries of all layers
+	std::vector<Point*> _profilePntVec;
+};
+
+} // namespace
+
+#endif // GEO_STATION_H
diff --git a/GeoLib/Surface.cpp b/GeoLib/Surface.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..066df2a2d572aa5fa8305dfd3d7162c84831d793
--- /dev/null
+++ b/GeoLib/Surface.cpp
@@ -0,0 +1,107 @@
+/*
+ * Surface.cpp
+ *
+ *  Created on: Apr 22, 2010
+ *      Author: TF
+ */
+
+#include <list>
+
+// GEOLIB
+#include "Surface.h"
+#include "AxisAlignedBoundingBox.h"
+#include "Polygon.h"
+
+// MathLib
+#include "AnalyticalGeometry.h"
+#include "EarClippingTriangulation.h"
+
+namespace GEOLIB {
+
+Surface::Surface (const std::vector<Point*> &pnt_vec) :
+	GeoObject(), _sfc_pnts(pnt_vec), _bv()
+{}
+
+Surface::~Surface ()
+{
+	for (size_t k(0); k<_sfc_triangles.size(); k++)
+		delete _sfc_triangles[k];
+}
+
+void Surface::addTriangle (size_t pnt_a, size_t pnt_b, size_t pnt_c)
+{
+	assert (pnt_a < _sfc_pnts.size() && pnt_b < _sfc_pnts.size() && pnt_c < _sfc_pnts.size());
+	_sfc_triangles.push_back (new Triangle(_sfc_pnts, pnt_a, pnt_b, pnt_c));
+	_bv.update (*_sfc_pnts[pnt_a]);
+	_bv.update (*_sfc_pnts[pnt_b]);
+	_bv.update (*_sfc_pnts[pnt_c]);
+}
+
+Surface* Surface::createSurface(const Polyline &ply)
+{
+	if (!ply.isClosed()) {
+		std::cout << "Error in Surface::createSurface() - Polyline is not closed..." << std::cout;
+		return NULL;
+	}
+
+	if (ply.getNumberOfPoints() > 2) {
+		// create empty surface
+		Surface *sfc(new Surface(ply.getPointsVec()));
+
+		Polygon* polygon (new Polygon (ply));
+		polygon->computeListOfSimplePolygons ();
+
+		// create surfaces from simple polygons
+		const std::list<GEOLIB::Polygon*>& list_of_simple_polygons (polygon->getListOfSimplePolygons());
+		for (std::list<GEOLIB::Polygon*>::const_iterator simple_polygon_it (list_of_simple_polygons.begin());
+			simple_polygon_it != list_of_simple_polygons.end(); ++simple_polygon_it) {
+
+			std::list<GEOLIB::Triangle> triangles;
+			std::cout << "triangulation of surface: ... " << std::flush;
+			MathLib::EarClippingTriangulation(*simple_polygon_it, triangles);
+			std::cout << "done - " << triangles.size () << " triangles " << std::endl;
+
+			// add Triangles to Surface
+			std::list<GEOLIB::Triangle>::const_iterator it (triangles.begin());
+			while (it != triangles.end()) {
+				sfc->addTriangle ((*it)[0], (*it)[1], (*it)[2]);
+				it++;
+			}
+		}
+		delete polygon;
+		return sfc;
+	} else {
+		std::cout << "Error in Surface::createSurface() - Polyline consists of less than three points and therefore cannot be triangulated..." << std::cout;
+		return NULL;
+	}
+
+}
+
+size_t Surface::getNTriangles () const
+{
+	return _sfc_triangles.size();
+}
+
+const Triangle* Surface::operator[] (size_t i) const
+{
+	assert (i < _sfc_triangles.size());
+	return _sfc_triangles[i];
+}
+
+bool Surface::isPntInBV (const double *pnt, double eps) const
+{
+	return _bv.containsPoint (pnt, eps);
+}
+
+bool Surface::isPntInSfc (const double *pnt) const
+{
+	bool nfound (true);
+	for (size_t k(0); k<_sfc_triangles.size() && nfound; k++) {
+		if (_sfc_triangles[k]->containsPoint (pnt)) {
+			nfound = false;
+		}
+	}
+	return !nfound;
+}
+
+} // end namespace
diff --git a/GeoLib/Surface.h b/GeoLib/Surface.h
new file mode 100644
index 0000000000000000000000000000000000000000..7bf36f273bd77f716dd5d50e82a15da4ae27f9c9
--- /dev/null
+++ b/GeoLib/Surface.h
@@ -0,0 +1,82 @@
+/*
+ * Surface.h
+ *
+ *  Created on: Jan 22, 2010
+ *      Author: TF
+ */
+
+#ifndef SURFACE_H_
+#define SURFACE_H_
+
+#include <vector>
+
+#include "GeoObject.h"
+#include "Point.h"
+#include "Polyline.h"
+#include "Triangle.h"
+#include "AxisAlignedBoundingBox.h"
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ *
+ * \brief A Surface is represented by Triangles. It consists of a reference
+ * to a vector of (pointers to) points (m_sfc_pnts) and a vector that stores
+ * the Triangles consisting of points from m_sfc_pnts.
+ * */
+class Surface : public GeoObject
+{
+public:
+	Surface	(const std::vector<Point*> &pnt_vec);
+	virtual ~Surface ();
+
+	/**
+	 * adds three indices describing a triangle and updates the bounding box
+	 * */
+	void addTriangle (size_t pnt_a, size_t pnt_b, size_t pnt_c);
+
+	/// Triangulates a new surface based on closed polyline.
+	static Surface* createSurface(const Polyline &ply);
+
+	/**
+	 * returns the number of triangles describing the Surface
+	 * */
+	size_t getNTriangles () const;
+
+	/** \brief const access operator for the access to the i-th Triangle of the surface.
+	*/
+	const Triangle* operator[] (size_t i) const;
+
+	/**
+	 * is the given point in the bounding volume of the surface
+	 */
+	bool isPntInBV (const double *pnt, double eps = std::numeric_limits<double>::epsilon()) const;
+
+	/**
+	 * is the given point pnt located in the surface
+	 * @param pnt the point
+	 * @return true if the point is contained in the surface
+	 */
+	bool isPntInSfc (const double *pnt) const;
+
+	const std::vector<Point*> *getPointVec() const { return &_sfc_pnts; };
+
+	/**
+	 * method allows access to the internal axis aligned bounding box
+	 * @return axis aligned bounding box
+	 */
+	AABB const & getAABB () const { return _bv; }
+
+protected:
+	/** a vector of pointers to Points */
+	const std::vector<Point*> &_sfc_pnts;
+	/** position of pointers to the geometric points */
+	std::vector<Triangle*> _sfc_triangles;
+	/** bounding volume is an axis aligned bounding box */
+	AABB _bv;
+};
+
+}
+
+#endif /* SURFACE_H_ */
diff --git a/GeoLib/SurfaceVec.h b/GeoLib/SurfaceVec.h
new file mode 100644
index 0000000000000000000000000000000000000000..7554f27d593253614e88614c1cd8d789bb151086
--- /dev/null
+++ b/GeoLib/SurfaceVec.h
@@ -0,0 +1,26 @@
+/*
+ * \file SurfaceVec.h
+ *
+ *  Created on: Feb 9, 2010
+ *      Author: fischeth
+ */
+
+
+#ifndef SURFACEVEC_H_
+#define SURFACEVEC_H_
+
+#include "TemplateVec.h"
+#include "Surface.h"
+
+namespace GEOLIB {
+
+/**
+ * Class SurfaceVec encapsulate a std::vector of Surfaces
+ * and a name.
+ * */
+
+typedef TemplateVec<Surface> SurfaceVec;
+
+} // end namespace
+
+#endif /* SURFACEVEC_H_ */
diff --git a/GeoLib/TemplatePoint.h b/GeoLib/TemplatePoint.h
new file mode 100644
index 0000000000000000000000000000000000000000..41667d8d26e4136d3512bf16ce36978e66bae1f2
--- /dev/null
+++ b/GeoLib/TemplatePoint.h
@@ -0,0 +1,133 @@
+/*
+ * TemplatePoint.h
+ *
+ *  Created on: Jan 28, 2010
+ *      Author: fischeth
+ */
+
+#ifndef TEMPLATEPOINT_H_
+#define TEMPLATEPOINT_H_
+
+#include <cassert>
+#include <iostream>
+#include <string>
+#include <sstream>
+
+#include "GeoObject.h"
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ *
+ * \brief class-template for points can be instantiated by a numeric type.
+ * \param T the coordinate type
+ */
+template <class T> class TemplatePoint : public GeoObject
+{
+public:
+	/** default constructor */
+	TemplatePoint ();
+
+	/** constructor - constructs a TemplatePoint object
+	 \param x1 value for the first coordinate
+	 \param x2 value for the second coordinate
+	 \param x3 value for the third coordinate
+	 */
+	TemplatePoint (T x1, T x2, T x3);
+
+	/** constructor - constructs a TemplatePoint object
+	 \param x values for three coordinates
+	 */
+	TemplatePoint (T const* x);
+
+	/** virtual destructor */
+	virtual ~TemplatePoint() {};
+
+	/** \brief const access operator
+	 *  The access to the point coordinates is like the access to a field. Code example:
+	 * \code
+	 * Point<double> point (1.0, 2.0, 3.0);
+	 * double sqrNrm2 = point[0] * point[0] + point[1] * point[1] + point[2] + point[2];
+	 * \endcode
+	*/
+	const T& operator[] (size_t idx) const {
+		assert (idx <= 2);
+		return _x[idx];
+	}
+	/** \brief access operator (see book Effektiv C++ programmieren - subsection 1.3.2 ).
+	 * \sa const T& operator[] (size_t idx) const
+	 */
+	T& operator[] (size_t idx) {
+		return const_cast<T&> (static_cast<const TemplatePoint&> (*this)[idx]);
+	}
+
+	/** returns an array containing the coordinates of the point */
+	const T* getData () const { return _x; }
+
+	/** write point coordinates into stream (used from operator<<)
+	 * \param os a standard output stream
+	*/
+	virtual void write (std::ostream &os) const {
+		os << _x[0] << " " << _x[1] << " " << _x[2] << std::flush;
+	}
+
+	/**
+	 * write point coordinates into string
+	*/
+	virtual std::string write () const {
+		std::ostringstream strStream;
+		strStream << _x[0] << " " << _x[1] << " " << _x[2];
+		return strStream.str();
+	}
+
+	/** read point coordinates into stream (used from operator>>) */
+	virtual void read (std::istream &is) {
+		is >> _x[0] >> _x[1] >> _x[2];
+	}
+
+protected:
+	T _x[3];
+};
+
+template <class T> TemplatePoint<T>::TemplatePoint() :
+	GeoObject()
+{
+	_x[0] = static_cast<T>(0);
+	_x[1] = static_cast<T>(0);
+	_x[2] = static_cast<T>(0);
+}
+
+template <class T> TemplatePoint<T>::TemplatePoint(T x1, T x2, T x3) :
+	GeoObject()
+{
+	_x[0] = x1;
+	_x[1] = x2;
+	_x[2] = x3;
+}
+
+template <class T> TemplatePoint<T>::TemplatePoint (T const* x) :
+	GeoObject()
+{
+	for (size_t k(0); k<3; k++) _x[k] = x[k];
+}
+
+/** overload the output operator for class Point */
+template <class T>
+std::ostream& operator<< (std::ostream &os, const TemplatePoint<T> &p)
+{
+	p.write (os);
+	return os;
+}
+
+/** overload the input operator for class Point */
+template <class T>
+std::istream& operator>> (std::istream &is, TemplatePoint<T> &p)
+{
+	p.read (is);
+	return is;
+}
+
+} // end namespace GEO
+
+#endif /* TEMPLATEPOINT_H_ */
diff --git a/GeoLib/TemplateVec.h b/GeoLib/TemplateVec.h
new file mode 100644
index 0000000000000000000000000000000000000000..878539a4ea3034383f133bc7fff701bc1470d4c6
--- /dev/null
+++ b/GeoLib/TemplateVec.h
@@ -0,0 +1,181 @@
+/*
+ * TemplateVec.h
+ *
+ *  Created on: Feb 26, 2010
+ *      Author: TF
+ */
+
+#ifndef TEMPLATEVEC_H_
+#define TEMPLATEVEC_H_
+
+namespace GEOLIB {
+
+/**
+ * \ingroup GEOLIB
+ *
+ * \brief The class TemplateVec takes a unique name and manages
+ * a std::vector of pointers to data elements of type T.
+ *
+ * Instances are classes PolylineVec and SurfaceVec.
+ * */
+template <class T> class TemplateVec
+{
+public:
+	/**
+	 * Constructor of class TemlateVec.
+	 * @param name unique name of the project the elements belonging to.
+	 * In order to access the data elements a unique name is required.
+	 * @param data_vec vector of data elements
+	 * @param elem_name_map Names of data elements can be given by a
+	 * std::map<std::string, size_t>. Here the std::string is the name
+	 * of the element and the value for size_t stands for an index in
+	 * the data_vec.
+
+	 */
+	TemplateVec (const std::string &name, std::vector<T*> *data_vec, std::map<std::string, size_t>* elem_name_map = NULL) :
+		_name(name), _data_vec(data_vec), _name_id_map (elem_name_map)
+	{}
+
+	/**
+	 * destructor, deletes all data elements
+	 */
+	virtual ~TemplateVec ()
+	{
+		for (size_t k(0); k<size(); k++) delete (*_data_vec)[k];
+		delete _data_vec;
+		delete _name_id_map;
+	}
+
+	/** sets the name of the vector of geometric objects
+	 * the data elements belonging to
+	 * \param n the name as standard string */
+	void setName (const std::string & n) { _name = n; }
+	/**
+	 * the name, the data element belonging to
+	 * @return the name of the object
+	 */
+	std::string getName () const { return _name; }
+
+	/**
+	 * @return the number of data elements
+	 */
+	size_t size () const { return _data_vec->size(); }
+
+	/**
+	 * get a pointer to a standard vector containing the data elements
+	 * @return the data elements
+	 */
+	const std::vector<T*>* getVector () const { return _data_vec; }
+
+	/**
+	 * search the vector of names for the ID of the geometric element with the given name
+	 * @param name the name of the geometric element
+	 * @param id the id of the geometric element
+	 * @return
+	 */
+	bool getElementIDByName (const std::string& name, size_t &id) const
+	{
+		std::map<std::string,size_t>::const_iterator it (_name_id_map->find (name));
+
+		if (it != _name_id_map->end()) {
+			id = it->second;
+			return true;
+		} else return false;
+	}
+
+	const T* getElementByName (const std::string& name) const
+	{
+		size_t id;
+		bool ret (getElementIDByName (name, id));
+		if (ret) {
+			return (*_data_vec)[id];
+		} else {
+			return NULL;
+		}
+	}
+
+	/**
+	 * The method returns true if there is a name associated
+	 * with the given id, else method returns false.
+	 * @param id the id
+	 * @param element_name if a name associated with the id
+	 * is found name is assigned to element_name
+	 * @return if there is name associated with the given id:
+	 * true, else false
+	 */
+	bool getNameOfElementByID (size_t id, std::string& element_name) const
+	{
+		if (! _name_id_map) return false;
+		// search in map for id
+		std::map<std::string,size_t>::const_iterator it (_name_id_map->begin());
+		while (it != _name_id_map->end()) {
+			if (it->second == id) {
+				element_name = it->first;
+				return true;
+			}
+			it++;
+		}
+		return false;
+	}
+
+	void setNameOfElementByID (size_t id, std::string& element_name)
+	{
+		if (! _name_id_map) return;
+		_name_id_map->insert( std::pair<std::string, size_t>(element_name, id) );
+	}
+
+	/**
+	 * The method returns true if the given element of type T
+	 * can be found and the element has a name, else method returns false.
+	 * @param data the data element, one wants to know the name
+	 * @param name the name of the data element (if the data element is
+	 * found and the data element has a name)
+	 * @return if element is found and has a name: true, else false
+	 */
+	bool getNameOfElement (const T* data, std::string& name) const
+	{
+		for (size_t k(0); k<_data_vec->size(); k++) {
+			if ((*_data_vec)[k] == data) {
+				return getNameOfElementByID (k, name);
+			}
+		}
+		return false;
+	}
+
+	void push_back (T* data_element, std::string const * const name = NULL)
+	{
+		_data_vec->push_back (data_element);
+		if (name == NULL) return;
+		if (! name->empty()) {
+			if (_name_id_map == NULL) {
+				_name_id_map = new std::map <std::string, size_t>;
+			}
+			_name_id_map->insert (std::pair<std::string,size_t>(*name, _data_vec->size()-1));
+		}
+	}
+
+
+private:
+	/** copy constructor doesn't have an implementation */
+	// compiler does not create a (possible unwanted) copy constructor
+	TemplateVec (const TemplateVec &);
+	/** assignment operator doesn't have an implementation */
+	// this way the compiler does not create a (possible unwanted) assignment operator
+	TemplateVec& operator= (const TemplateVec& rhs);
+
+	/** the name of the object */
+	std::string _name;
+
+	/**
+	 * pointer to a vector of data elements
+	 */
+	std::vector <T*> *_data_vec;
+	/**
+	 * store names associated with the element ids
+	 */
+	std::map<std::string, size_t>* _name_id_map;
+};
+
+} // end namespace GEOLIB
+
+#endif /* TEMPLATEVEC_H_ */
diff --git a/GeoLib/Triangle.cpp b/GeoLib/Triangle.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..06df2b4c28720ce481c661c2abaa61fb93d1851a
--- /dev/null
+++ b/GeoLib/Triangle.cpp
@@ -0,0 +1,207 @@
+/*
+ * \file Triangle.cpp
+ *
+ *  Created on: Jun 6, 2011
+ *      Author: TF
+ */
+
+#include "Triangle.h"
+
+// MathLib
+#include "LinAlg/Solvers/GaussAlgorithm.h"
+#include "MathTools.h"
+#include "LinAlg/Dense/Matrix.h"
+#include "Vector3.h"
+
+namespace GEOLIB {
+
+Triangle::Triangle (std::vector<Point *> const &pnt_vec) :
+	_pnts(pnt_vec), _initialized (false), _longest_edge (0.0)
+{
+	_pnt_ids[0] = std::numeric_limits<size_t>::max();
+	_pnt_ids[1] = std::numeric_limits<size_t>::max();
+	_pnt_ids[2] = std::numeric_limits<size_t>::max();
+}
+
+Triangle::Triangle (std::vector<Point *> const &pnt_vec, size_t pnt_a, size_t pnt_b, size_t pnt_c) :
+	_pnts(pnt_vec), _initialized (true), _longest_edge (0.0)
+{
+	_pnt_ids[0] = pnt_a;
+	_pnt_ids[1] = pnt_b;
+	_pnt_ids[2] = pnt_c;
+	_longest_edge = MathLib::sqrDist (_pnts[_pnt_ids[0]], _pnts[_pnt_ids[1]]);
+	double tmp (MathLib::sqrDist (_pnts[_pnt_ids[1]], _pnts[_pnt_ids[2]]));
+	if (tmp > _longest_edge) _longest_edge = tmp;
+	tmp = MathLib::sqrDist (_pnts[_pnt_ids[0]], _pnts[_pnt_ids[2]]);
+	if (tmp > _longest_edge) _longest_edge = tmp;
+	_longest_edge = sqrt (_longest_edge);
+}
+
+void Triangle::setTriangle (size_t pnt_a, size_t pnt_b, size_t pnt_c)
+{
+	assert (pnt_a < _pnts.size() && pnt_b < _pnts.size() && pnt_c < _pnts.size());
+	_pnt_ids[0] = pnt_a;
+	_pnt_ids[1] = pnt_b;
+	_pnt_ids[2] = pnt_c;
+
+	_longest_edge = MathLib::sqrDist (_pnts[_pnt_ids[0]], _pnts[_pnt_ids[1]]);
+	double tmp (MathLib::sqrDist (_pnts[_pnt_ids[1]], _pnts[_pnt_ids[2]]));
+	if (tmp > _longest_edge) _longest_edge = tmp;
+	tmp = MathLib::sqrDist (_pnts[_pnt_ids[0]], _pnts[_pnt_ids[2]]);
+	if (tmp > _longest_edge) _longest_edge = tmp;
+	_longest_edge = sqrt (_longest_edge);
+}
+
+bool Triangle::containsPoint (const double *pnt) const
+{
+	GEOLIB::Point const& a_tmp (*(_pnts[_pnt_ids[0]]));
+	GEOLIB::Point const& b_tmp (*(_pnts[_pnt_ids[1]]));
+	GEOLIB::Point const& c_tmp (*(_pnts[_pnt_ids[2]]));
+
+	GEOLIB::Point s(a_tmp);
+	for (size_t k(0); k<3; k++) {
+		s[k] += b_tmp[k] + c_tmp[k];
+		s[k] /= 3.0;
+	}
+
+	double eps (1e-2);
+	GEOLIB::Point const a (a_tmp[0] + eps *(a_tmp[0]-s[0]),
+			a_tmp[1] + eps *(a_tmp[1]-s[1]),
+			a_tmp[2] + eps *(a_tmp[2]-s[2]));
+	GEOLIB::Point const b (b_tmp[0] + eps *(b_tmp[0]-s[0]),
+				b_tmp[1] + eps *(b_tmp[1]-s[1]),
+				b_tmp[2] + eps *(b_tmp[2]-s[2]));
+	GEOLIB::Point const c (c_tmp[0] + eps *(c_tmp[0]-s[0]),
+				c_tmp[1] + eps *(c_tmp[1]-s[1]),
+				c_tmp[2] + eps *(c_tmp[2]-s[2]));
+
+	const double delta (std::numeric_limits<double>::epsilon());
+	const double upper (1+delta);
+
+	// check special case where points of triangle have the same x-coordinate
+	if (fabs(b[0]-a[0]) <= std::numeric_limits<double>::epsilon() &&
+			fabs(c[0]-a[0]) <= std::numeric_limits<double>::epsilon()) {
+		// all points of triangle have same x-coordinate
+		if (fabs(pnt[0]-a[0]) / _longest_edge <= 1e-3) {
+			// criterion: p-a = u0 * (b-a) + u1 * (c-a); 0 <= u0, u1 <= 1, u0+u1 <= 1
+			MathLib::Matrix<double> mat (2,2);
+			mat(0,0) = b[1] - a[1];
+			mat(0,1) = c[1] - a[1];
+			mat(1,0) = b[2] - a[2];
+			mat(1,1) = c[2] - a[2];
+			double y[2] = {pnt[1]-a[1], pnt[2]-a[2]};
+
+			MathLib::GaussAlgorithm gauss (mat);
+			gauss.execute (y);
+
+			if (-delta <= y[0] && y[0] <= upper && -delta <= y[1] && y[1] <= upper
+					&& y[0] + y[1] <= upper) {
+				return true;
+			} else {
+				return false;
+			}
+		} else {
+			return false;
+		}
+	}
+
+	// check special case where points of triangle have the same y-coordinate
+	if (fabs(b[1]-a[1]) <= std::numeric_limits<double>::epsilon() &&
+			fabs(c[1]-a[1]) <= std::numeric_limits<double>::epsilon()) {
+		// all points of triangle have same y-coordinate
+		if (fabs(pnt[1]-a[1]) / _longest_edge <= 1e-3) {
+			// criterion: p-a = u0 * (b-a) + u1 * (c-a); 0 <= u0, u1 <= 1, u0+u1 <= 1
+			MathLib::Matrix<double> mat (2,2);
+			mat(0,0) = b[0] - a[0];
+			mat(0,1) = c[0] - a[0];
+			mat(1,0) = b[2] - a[2];
+			mat(1,1) = c[2] - a[2];
+			double y[2] = {pnt[0]-a[0], pnt[2]-a[2]};
+
+			MathLib::GaussAlgorithm gauss (mat);
+			gauss.execute (y);
+
+			if (-delta <= y[0] && y[0] <= upper && -delta <= y[1] && y[1] <= upper && y[0] + y[1] <= upper) {
+				return true;
+			} else {
+				return false;
+			}
+		} else {
+			return false;
+		}
+	}
+
+	// criterion: p-a = u0 * (b-a) + u1 * (c-a); 0 <= u0, u1 <= 1, u0+u1 <= 1
+	MathLib::Matrix<double> mat (2,2);
+	mat(0,0) = b[0] - a[0];
+	mat(0,1) = c[0] - a[0];
+	mat(1,0) = b[1] - a[1];
+	mat(1,1) = c[1] - a[1];
+	double y[2] = {pnt[0]-a[0], pnt[1]-a[1]};
+
+	MathLib::GaussAlgorithm gauss (mat);
+	gauss.execute (y);
+
+	// check if the solution fulfills the third equation
+	if (fabs((b[2]-a[2]) * y[0] + (c[2]-a[2]) * y[1] - (pnt[2] - a[2])) < 1e-3) {
+		if (-delta <= y[0] && y[0] <= upper && -delta <= y[1] && y[1] <= upper &&
+				y[0] + y[1] <= upper) {
+			return true;
+		}
+		return false;
+	} else {
+		return false;
+	}
+}
+
+bool Triangle::containsPoint2D (const double *pnt) const
+{
+	GEOLIB::Point const& a (*(_pnts[_pnt_ids[0]]));
+	GEOLIB::Point const& b (*(_pnts[_pnt_ids[1]]));
+	GEOLIB::Point const& c (*(_pnts[_pnt_ids[2]]));
+
+	// criterion: p-a = u0 * (b-a) + u1 * (c-a); 0 <= u0, u1 <= 1, u0+u1 <= 1
+	MathLib::Matrix<double> mat (2,2);
+	mat(0,0) = b[0] - a[0];
+	mat(0,1) = c[0] - a[0];
+	mat(1,0) = b[1] - a[1];
+	mat(1,1) = c[1] - a[1];
+	double y[2] = {pnt[0]-a[0], pnt[1]-a[1]};
+
+	MathLib::GaussAlgorithm gauss (mat);
+	gauss.execute (y);
+
+	const double delta (std::numeric_limits<double>::epsilon());
+	const double upper (1+delta);
+
+	// check if u0 and u1 fulfills the condition (with some delta)
+	if (-delta <= y[0] && y[0] <= upper && -delta <= y[1] && y[1] <= upper && y[0] + y[1] <= upper) {
+		return true;
+	}
+	return false;
+}
+
+void getPlaneCoefficients(Triangle const& tri, double c[3])
+{
+	GEOLIB::Point const& p0 (*(tri.getPoint(0)));
+	GEOLIB::Point const& p1 (*(tri.getPoint(1)));
+	GEOLIB::Point const& p2 (*(tri.getPoint(2)));
+	MathLib::Matrix<double> mat (3,3);
+	mat(0,0) = p0[0];
+	mat(0,1) = p0[1];
+	mat(0,2) = 1.0;
+	mat(1,0) = p1[0];
+	mat(1,1) = p1[1];
+	mat(1,2) = 1.0;
+	mat(2,0) = p2[0];
+	mat(2,1) = p2[1];
+	mat(2,2) = 1.0;
+	c[0] = p0[2];
+	c[1] = p1[2];
+	c[2] = p2[2];
+
+	MathLib::GaussAlgorithm gauss (mat);
+	gauss.execute (c);
+}
+
+} // end namespace GEOLIB
diff --git a/GeoLib/Triangle.h b/GeoLib/Triangle.h
new file mode 100644
index 0000000000000000000000000000000000000000..48a1028ac34c221e588d88aa05a7fa11444003de
--- /dev/null
+++ b/GeoLib/Triangle.h
@@ -0,0 +1,99 @@
+/*
+ * \file Triangle.h
+ *
+ *  Created on: Mar 23, 2010
+ *      Author: TF
+ */
+
+#ifndef TRIANGLE_H_
+#define TRIANGLE_H_
+
+#include <vector>
+
+// GeoLib
+#include "Point.h"
+
+namespace GEOLIB {
+
+/** \brief Class Triangle consists of a reference to a point vector and
+ * a vector that stores the indices in the point vector.
+ * A surface is composed by triangles. The class Surface stores the position
+ * of pointers to the points of triangles in the m_sfc_pnt_ids vector.
+ * */
+class Triangle
+{
+public:
+	/**
+	 * construction of object, initialization of reference to point vector
+	 */
+	Triangle (std::vector<Point *> const &pnt_vec);
+
+	/**
+	 * construction of object, initialization of reference to point vector,
+	 * saves the three indices describing a triangle
+	 */
+	Triangle (std::vector<Point *> const &pnt_vec, size_t pnt_a, size_t pnt_b, size_t pnt_c);
+
+	/**
+	 * saves three indices describing a triangle
+	 * */
+	void setTriangle (size_t pnt_a, size_t pnt_b, size_t pnt_c);
+
+	/** \brief const access operator to access the index
+	 * of the i-th triangle point
+	*/
+	const size_t& operator[] (size_t i) const {
+		assert (i < 3);
+		return _pnt_ids[i];
+	}
+
+//	/** \brief access operator to access the index
+//	 * of the i-th triangle point
+//	 * */
+//	size_t& operator[] (size_t i) {
+//		assert (i < 3);
+//		return _pnt_ids[i];
+//	}
+
+	/**
+	 * \brief const access operator to access the i-th triangle Point
+	 */
+	const Point* getPoint (size_t i) const {
+		assert (i < 3);
+		return _pnts[_pnt_ids[i]];
+	}
+
+	/**
+	 * checks if point is in triangle
+	 * @param pnt
+	 * @return true, if point is in triangle, else false
+	 */
+	bool containsPoint (const double *pnt) const;
+
+	bool containsPoint (const Point &pnt) const
+	{
+		return containsPoint (pnt.getData());
+	}
+
+	/**
+	 * projects the triangle points to the x-y-plane and
+	 * checks if point pnt is contained into the triangle
+	 * @param pnt the point to test for
+	 * @return true, if the point is into the projected triangle
+	 */
+	bool containsPoint2D (const double *pnt) const;
+
+protected:
+	/** a vector of pointers to points */
+	const std::vector<Point*> &_pnts;
+	/** position of pointers to the geometric points */
+	size_t _pnt_ids[3];
+	bool _initialized;
+	double _longest_edge;
+};
+
+void getPlaneCoefficients(Triangle const& tri, double c[3]);
+
+} // end namespace GEOLIB
+
+#endif /* TRIANGLE_H_ */
diff --git a/MathLib/AnalyticalGeometry.cpp b/MathLib/AnalyticalGeometry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..efcf96bf5de5dd517031f67e47501c83488052bb
--- /dev/null
+++ b/MathLib/AnalyticalGeometry.cpp
@@ -0,0 +1,215 @@
+/*
+ * \file AnalyticalGeometry.cpp
+ *
+ *  Created on: Mar 17, 2010
+ *      Author: TF
+ */
+
+#include <cmath>
+#include <cstdlib> // for exit
+#include <list>
+#include <limits>
+#include <fstream>
+
+// Base
+#include "swap.h"
+#include "quicksort.h"
+
+// GEO
+#include "Polyline.h"
+#include "Triangle.h"
+
+// MathLib
+#include "MathTools.h"
+#include "AnalyticalGeometry.h"
+#include "LinAlg/Solvers/GaussAlgorithm.h"
+#include "LinAlg/Dense/Matrix.h" // for transformation matrix
+#include "max.h"
+
+namespace MathLib {
+
+Orientation getOrientation (const double& p0_x, const double& p0_y,
+	const double& p1_x, const double& p1_y,
+	const double& p2_x, const double& p2_y)
+{
+	double h1 ((p1_x-p0_x)*(p2_y-p0_y));
+	double h2 ((p2_x-p0_x)*(p1_y-p0_y));
+
+	double tol (sqrt(std::numeric_limits<double>::min()));
+	if (fabs (h1-h2) <= tol * max (fabs(h1), fabs(h2)))
+		return COLLINEAR;
+	if (h1-h2 > 0.0) return CCW;
+
+	return CW;
+}
+
+Orientation getOrientation (const GEOLIB::Point* p0, const GEOLIB::Point* p1, const GEOLIB::Point* p2)
+{
+		return getOrientation ((*p0)[0], (*p0)[1], (*p1)[0], (*p1)[1], (*p2)[0], (*p2)[1]);
+}
+
+bool lineSegmentIntersect (const GEOLIB::Point& a, const GEOLIB::Point& b,
+		const GEOLIB::Point& c, const GEOLIB::Point& d,
+		GEOLIB::Point& s)
+{
+	Matrix<double> mat(2,2);
+	mat(0,0) = b[0] - a[0];
+	mat(1,0) = b[1] - a[1];
+	mat(0,1) = c[0] - d[0];
+	mat(1,1) = c[1] - d[1];
+
+	// check if vectors are parallel
+	double eps (sqrt(std::numeric_limits<double>::min()));
+	if (fabs(mat(1,1)) < eps) {
+		// vector (D-C) is parallel to x-axis
+		if (fabs(mat(0,1)) < eps) {
+			// vector (B-A) is parallel to x-axis
+			return false;
+		}
+	} else {
+		// vector (D-C) is not parallel to x-axis
+		if (fabs(mat(0,1)) >= eps) {
+			// vector (B-A) is not parallel to x-axis
+			// \f$(B-A)\f$ and \f$(D-C)\f$ are parallel iff there exists
+			// a constant \f$c\f$ such that \f$(B-A) = c (D-C)\f$
+			if (fabs (mat(0,0) / mat(0,1) - mat(1,0) / mat(1,1)) < eps * fabs (mat(0,0) / mat(0,1)))
+				return false;
+		}
+	}
+
+	double *rhs (new double[2]);
+	rhs[0] = c[0] - a[0];
+	rhs[1] = c[1] - a[1];
+
+	GaussAlgorithm lu_solver (mat);
+	lu_solver.execute (rhs);
+	if (0 <= rhs[0] && rhs[0] <= 1.0 && 0 <= rhs[1] && rhs[1] <= 1.0) {
+		s[0] = a[0] + rhs[0] * (b[0] - a[0]);
+		s[1] = a[1] + rhs[0] * (b[1] - a[1]);
+		s[2] = a[2] + rhs[0] * (b[2] - a[2]);
+		// check z component
+		double z0 (a[2] - d[2]), z1(rhs[0]*(b[2]-a[2]) + rhs[1]*(d[2]-c[2]));
+		delete [] rhs;
+		if (std::fabs (z0-z1) < eps)
+			return true;
+		else
+			return false;
+	} else delete [] rhs;
+	return false;
+}
+
+bool lineSegmentsIntersect (const GEOLIB::Polyline* ply, size_t &idx0, size_t &idx1, GEOLIB::Point& intersection_pnt)
+{
+	size_t n_segs (ply->getNumberOfPoints() - 1);
+	/**
+	 * computing the intersections of all possible pairs of line segments of the given polyline
+	 * as follows:
+	 * let the segment \f$s_1 = (A,B)\f$ defined by \f$k\f$-th and \f$k+1\f$-st point
+	 * of the polyline and segment \f$s_2 = (C,B)\f$ defined by \f$j\f$-th and
+	 * \f$j+1\f$-st point of the polyline, \f$j>k+1\f$
+	 */
+	for (size_t k(0); k<n_segs-2; k++) {
+		for (size_t j(k+2); j<n_segs; j++) {
+			if (k!=0 || j<n_segs-1) {
+				if (lineSegmentIntersect (*(*ply)[k], *(*ply)[k+1], *(*ply)[j], *(*ply)[j+1], intersection_pnt)) {
+					idx0 = k;
+					idx1 = j;
+					return true;
+				}
+			}
+		}
+	}
+	return false;
+}
+
+bool isPointInTriangle (const double p[3], const double a[3], const double b[3], const double c[3])
+{
+	// criterion: p-b = u0 * (b - a) + u1 * (b - c); 0 <= u0, u1 <= 1, u0+u1 <= 1
+	MathLib::Matrix<double> mat (2,2);
+	mat(0,0) = a[0] - b[0];
+	mat(0,1) = c[0] - b[0];
+	mat(1,0) = a[1] - b[1];
+	mat(1,1) = c[1] - b[1];
+	double rhs[2] = {p[0]-b[0], p[1]-b[1]};
+
+	MathLib::GaussAlgorithm gauss (mat);
+	gauss.execute (rhs);
+
+	if (0 <= rhs[0] && rhs[0] <= 1 && 0 <= rhs[1] && rhs[1] <= 1 && rhs[0] + rhs[1] <= 1) return true;
+	return false;
+}
+
+bool isPointInTriangle (const GEOLIB::Point* p,
+		const GEOLIB::Point* a, const GEOLIB::Point* b, const GEOLIB::Point* c)
+{
+	return isPointInTriangle (p->getData(), a->getData(), b->getData(), c->getData());
+}
+
+// NewellPlane from book Real-Time Collision detection p. 494
+void getNewellPlane(const std::vector<GEOLIB::Point*>& pnts, Vector &plane_normal,
+		double& d)
+{
+	d = 0;
+	Vector centroid;
+	size_t n_pnts (pnts.size());
+	for (size_t i(n_pnts - 1), j(0); j < n_pnts; i = j, j++) {
+		plane_normal[0] += ((*(pnts[i]))[1] - (*(pnts[j]))[1])
+				* ((*(pnts[i]))[2] + (*(pnts[j]))[2]); // projection on yz
+		plane_normal[1] += ((*(pnts[i]))[2] - (*(pnts[j]))[2])
+				* ((*(pnts[i]))[0] + (*(pnts[j]))[0]); // projection on xz
+		plane_normal[2] += ((*(pnts[i]))[0] - (*(pnts[j]))[0])
+				* ((*(pnts[i]))[1] + (*(pnts[j]))[1]); // projection on xy
+
+		centroid += *(pnts[j]);
+	}
+
+	plane_normal *= 1.0 / plane_normal.Length();
+	d = centroid.Dot(plane_normal) / n_pnts;
+}
+
+
+void rotatePointsToXY(Vector &plane_normal,
+		std::vector<GEOLIB::Point*> &pnts)
+{
+	double small_value (sqrt (std::numeric_limits<double>::min()));
+	if (fabs(plane_normal[0]) < small_value && fabs(plane_normal[1]) < small_value)
+		return;
+
+	// *** some frequently used terms ***
+	// sqrt (v_1^2 + v_2^2)
+	double h0(sqrt(plane_normal[0] * plane_normal[0] + plane_normal[1]
+			* plane_normal[1]));
+	// 1 / sqrt (v_1^2 + v_2^2)
+	double h1(1 / h0);
+	// 1 / sqrt (h0 + v_3^2)
+	double h2(1.0 / sqrt(h0 + plane_normal[2] * plane_normal[2]));
+
+	Matrix<double> rot_mat(3, 3);
+	// calc rotation matrix
+	rot_mat(0, 0) = plane_normal[2] * plane_normal[0] * h2 * h1;
+	rot_mat(0, 1) = plane_normal[2] * plane_normal[1] * h2 * h1;
+	rot_mat(0, 2) = - h0 * h2;
+	rot_mat(1, 0) = -plane_normal[1] * h1;
+	rot_mat(1, 1) = plane_normal[0] * h1;;
+	rot_mat(1, 2) = 0.0;
+	rot_mat(2, 0) = plane_normal[0] * h2;
+	rot_mat(2, 1) = plane_normal[1] * h2;
+	rot_mat(2, 2) = plane_normal[2] * h2;
+
+	double *tmp (NULL);
+	size_t n_pnts(pnts.size());
+	for (size_t k(0); k < n_pnts; k++) {
+		tmp = rot_mat * pnts[k]->getData();
+		for (size_t j(0); j < 3; j++)
+			(*(pnts[k]))[j] = tmp[j];
+		delete [] tmp;
+	}
+
+	tmp = rot_mat * plane_normal.getData();
+	for (size_t j(0); j < 3; j++)
+		plane_normal[j] = tmp[j];
+
+	delete [] tmp;
+}
+
+} // end namespace MathLib
diff --git a/MathLib/AnalyticalGeometry.h b/MathLib/AnalyticalGeometry.h
new file mode 100644
index 0000000000000000000000000000000000000000..d982f10f3a0058f93caa2de82c48d61b8d98755b
--- /dev/null
+++ b/MathLib/AnalyticalGeometry.h
@@ -0,0 +1,88 @@
+/*
+ * \file AnalyticalGeometry.h
+ *
+ *  Created on: Mar 17, 2010
+ *      Author: TF
+ */
+
+#ifndef ANALYTICAL_GEOMETRY_H_
+#define ANALYTICAL_GEOMETRY_H_
+
+// MathLib
+#include "Vector3.h"
+// GEOLIB
+#include "Triangle.h"
+
+namespace GEOLIB {
+	class Polyline;
+}
+
+namespace MathLib {
+
+enum Orientation {
+	CW = 1,
+	CCW = 2,
+	COLLINEAR = 3
+};
+
+/**
+ * computes the orientation of the three 2D-Points given by their coordinates
+ * p0_x, p0_y, p1_x, p1_y, p2_x and p2_y
+ * \returns CW (clockwise), CCW (counterclockwise) or COLLINEAR (points are on a line)
+ */
+Orientation getOrientation (const double& p0_x, const double& p0_y,
+	const double& p1_x, const double& p1_y,
+	const double& p2_x, const double& p2_y);
+
+/**
+ * wrapper for getOrientation ()
+ */
+Orientation getOrientation (const GEOLIB::Point* p0, const GEOLIB::Point* p1, const GEOLIB::Point* p2);
+
+/**
+ * compute a supporting plane (represented by plane_normal and the value d) for the polygon
+ * Let \f$n\f$ be the plane normal and \f$d\f$ a parameter. Then for all points \f$p \in R^3\f$ of the plane
+ * it holds \f$ n \cdot p + d = 0\f$
+ * @param pnts points of a closed polyline describing a polygon
+ * @param plane_normal the normal of the plane the polygon is located in
+ * @param d parameter from the plane equation
+ */
+void getNewellPlane (const std::vector<GEOLIB::Point*>& pnts, MathLib::Vector &plane_normal, double& d);
+
+/**
+ *
+ * @param plane_normal
+ * @param pnts
+ */
+void rotatePointsToXY(MathLib::Vector &plane_normal, std::vector<GEOLIB::Point*> &pnts);
+
+bool isPointInTriangle (const GEOLIB::Point* p,
+		const GEOLIB::Point* a, const GEOLIB::Point* b, const GEOLIB::Point* c);
+
+/**
+ * test for intersections of the line segments of the Polyline
+ * @param ply the polyline
+ * @param idx0 beginning index of the first line segment that has an intersection
+ * @param idx1 beginning index of the second line segment that has an intersection
+ * @param intersection_pnt the intersection point if the line segments intersect
+ * @return true, if the polyline contains intersections
+ */
+bool lineSegmentsIntersect (const GEOLIB::Polyline* ply, size_t &idx0, size_t &idx1, GEOLIB::Point& intersection_pnt);
+
+/**
+ * A line segment is given by its two end-points. The function checks,
+ * if the two line segments (ab) and (cd) intersects. Up to now only
+ * 2D line segments are handled!
+ * @param a first end-point of the first line segment
+ * @param b second end-point of the first line segment
+ * @param c first end-point of the second line segment
+ * @param d second end-point of the second line segment
+ * @param s the intersection point
+ * @return true, if the line segments intersect, else false
+ */
+bool lineSegmentIntersect (const GEOLIB::Point& a, const GEOLIB::Point& b,
+		const GEOLIB::Point& c, const GEOLIB::Point& d, GEOLIB::Point& s);
+
+} // end namespace MathLib
+
+#endif /* MATHTOOLS_H_ */
diff --git a/MathLib/CMakeLists.txt b/MathLib/CMakeLists.txt
index fc1bdefbc3ea8368cf5108a0fbd84988f487c716..d36ba1f15b63244666ee1fdc9ae93a904dae4073 100644
--- a/MathLib/CMakeLists.txt
+++ b/MathLib/CMakeLists.txt
@@ -1,22 +1,50 @@
 # Source files
 SET( HEADERS
+	AnalyticalGeometry.h        
+	LinearInterpolation.h  
+	MathTools.h
+	Vector3.h
+	EarClippingTriangulation.h  
+	LinkedTriangle.h
+	max.h
+        sparse.h
+	vector_io.h
 	LinAlg/MatrixBase.h
+	LinAlg/VectorNorms.h
+	LinAlg/Dense/Matrix.h
+        LinAlg/Preconditioner/generateDiagPrecond.h
+        LinAlg/Solvers/LinearSolver.h
+        LinAlg/Solvers/DirectLinearSolver.h
+        LinAlg/Solvers/DenseDirectLinearSolver.h
+        LinAlg/Solvers/GaussAlgorithm.h
+        LinAlg/Solvers/TriangularSolve.h
+        LinAlg/Solvers/IterativeLinearSolver.h
+        LinAlg/Solvers/solver.h
 	LinAlg/Sparse/amuxCRS.h
         LinAlg/Sparse/CRSMatrix.h
         LinAlg/Sparse/CRSMatrixPThreads.h
         LinAlg/Sparse/CRSMatrixOpenMP.h
         LinAlg/Sparse/CRSSymMatrix.h
-        sparse.h
         LinAlg/Sparse/SparseMatrixBase.h
 )
 
 SET( SOURCES
+	AnalyticalGeometry.cpp        
+	LinearInterpolation.cpp  
+	MathTools.cpp
+	EarClippingTriangulation.cpp  
+	LinkedTriangle.cpp
         LinAlg/Sparse/amuxCRS.cpp
+        LinAlg/Solvers/CG.cpp
+	LinAlg/Solvers/GaussAlgorithm.cpp
+        LinAlg/Solvers/TriangularSolve.cpp
+	LinAlg/Preconditioner/generateDiagPrecond.cpp
 )
 
 INCLUDE_DIRECTORIES (
 	.
-	${PROJECT_BINARY_DIR}/Base
+	../Base
+	../GeoLib
 )
 
 # Create the library
diff --git a/MathLib/EarClippingTriangulation.cpp b/MathLib/EarClippingTriangulation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..45eb1fa5235506c7d2240fd8f5d4c7d495260f89
--- /dev/null
+++ b/MathLib/EarClippingTriangulation.cpp
@@ -0,0 +1,302 @@
+/*
+ * EarClippingTriangulation.cpp
+ *
+ *  Created on: Feb 23, 2011
+ *      Author: TF
+ */
+
+// STL
+#include <vector>
+
+// BASELIB
+#include "swap.h"
+#include "printList.h"
+#include "uniqueListInsert.h"
+
+// MathLib
+#include "EarClippingTriangulation.h"
+
+namespace MathLib {
+
+EarClippingTriangulation::EarClippingTriangulation(const GEOLIB::Polygon* polygon,
+		std::list<GEOLIB::Triangle> &triangles, bool rot)
+{
+	copyPolygonPoints (polygon);
+
+	if (rot) {
+		rotate ();
+		ensureCWOrientation ();
+	}
+
+	initVertexList ();
+	initLists ();
+	clipEars ();
+
+	std::vector<GEOLIB::Point*> const& ref_pnts_vec (polygon->getPointsVec());
+	std::list<GEOLIB::Triangle>::const_iterator it (_triangles.begin());
+	if (_original_orient == MathLib::CW) {
+		while (it != _triangles.end()) {
+			const size_t i0 (polygon->getPointID ((*it)[0]));
+			const size_t i1 (polygon->getPointID ((*it)[1]));
+			const size_t i2 (polygon->getPointID ((*it)[2]));
+			triangles.push_back (GEOLIB::Triangle (ref_pnts_vec, i0, i1, i2));
+			it++;
+		}
+	} else {
+		size_t n_pnts (_pnts.size()-1);
+		while (it != _triangles.end()) {
+			const size_t i0 (polygon->getPointID (n_pnts-(*it)[0]));
+			const size_t i1 (polygon->getPointID (n_pnts-(*it)[1]));
+			const size_t i2 (polygon->getPointID (n_pnts-(*it)[2]));
+			triangles.push_back (GEOLIB::Triangle (ref_pnts_vec, i0, i1, i2));
+			it++;
+		}
+	}
+}
+
+EarClippingTriangulation::~EarClippingTriangulation()
+{
+	const size_t n_pnts (_pnts.size());
+	for (size_t k(0); k<n_pnts; k++) {
+		delete _pnts[k];
+	}
+}
+
+void EarClippingTriangulation::copyPolygonPoints (const GEOLIB::Polygon* polygon)
+{
+	// copy points - last point is identical to the first
+	size_t n_pnts (polygon->getNumberOfPoints()-1);
+	for (size_t k(0); k < n_pnts; k++) {
+		_pnts.push_back (new GEOLIB::Point (*(polygon->getPoint(k))));
+	}
+}
+
+void EarClippingTriangulation::rotate ()
+{
+	// calculate supporting plane
+	Vector plane_normal;
+	double d;
+	// compute the plane normal
+	getNewellPlane(_pnts, plane_normal, d);
+
+	double tol (sqrt(std::numeric_limits<double>::min()));
+	if (fabs(plane_normal[0]) > tol || fabs(plane_normal[1]) > tol) {
+		// rotate copied points into x-y-plane
+		rotatePointsToXY(plane_normal, _pnts);
+	}
+
+	for (size_t k(0); k<_pnts.size(); k++)
+		(*(_pnts[k]))[2] = 0.0; // should be -= d but there are numerical errors
+}
+
+void EarClippingTriangulation::ensureCWOrientation ()
+{
+	size_t n_pnts (_pnts.size());
+	// get the left most upper point
+	size_t min_x_max_y_idx (0);	// for orientation check
+	for (size_t k(0); k<n_pnts; k++) {
+		if ((*(_pnts[k]))[0] <= (*(_pnts[min_x_max_y_idx]))[0]) {
+			if ((*(_pnts[k]))[0] < (*(_pnts[min_x_max_y_idx]))[0]) {
+				min_x_max_y_idx = k;
+			} else {
+				if ((*(_pnts[k]))[1] > (*(_pnts[min_x_max_y_idx]))[1]) {
+					min_x_max_y_idx = k;
+				}
+			}
+		}
+	}
+	// determine orientation
+	if (0 < min_x_max_y_idx && min_x_max_y_idx < n_pnts-1) {
+		_original_orient = MathLib::getOrientation (
+			_pnts[min_x_max_y_idx-1], _pnts[min_x_max_y_idx], _pnts[min_x_max_y_idx+1]);
+	} else {
+		if (0 == min_x_max_y_idx) {
+			_original_orient = MathLib::getOrientation (_pnts[n_pnts-1], _pnts[0], _pnts[1]);
+		} else {
+			_original_orient = MathLib::getOrientation (_pnts[n_pnts-2], _pnts[n_pnts-1], _pnts[0]);
+		}
+	}
+	if (_original_orient == MathLib::CCW) {
+		// switch orientation
+		for (size_t k(0); k<n_pnts/2; k++) {
+			BASELIB::swap (_pnts[k], _pnts[n_pnts-1-k]);
+		}
+	}
+}
+
+bool EarClippingTriangulation::isEar(size_t v0, size_t v1, size_t v2) const
+{
+	for (std::list<size_t>::const_iterator it (_vertex_list.begin ());
+		it != _vertex_list.end(); ++it) {
+		if (*it != v0 && *it != v1 && *it != v2) {
+			if (isPointInTriangle (_pnts[*it], _pnts[v0], _pnts[v1], _pnts[v2])) {
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
+void EarClippingTriangulation::initVertexList ()
+{
+	size_t n_pnts (_pnts.size());
+	for (size_t k(0); k<n_pnts; k++) _vertex_list.push_back (k);
+}
+
+void EarClippingTriangulation::initLists ()
+{
+	// go through points checking ccw, cw or collinear order and identifying ears
+	std::list<size_t>::iterator it (_vertex_list.begin()), prev(_vertex_list.end()), next;
+	prev--;
+	next = it;
+	next++;
+	MathLib::Orientation orientation;
+	while (next != _vertex_list.end()) {
+		orientation  = getOrientation (_pnts[*prev], _pnts[*it], _pnts[*next]);
+		if (orientation == COLLINEAR) {
+			it = _vertex_list.erase (it);
+			next++;
+		} else {
+			if (orientation == CW) {
+				_convex_vertex_list.push_back (*it);
+				if (isEar (*prev, *it, *next))
+					_ear_list.push_back (*it);
+			}
+			prev = it;
+			it = next;
+			next++;
+		}
+	}
+
+	next = _vertex_list.begin();
+	orientation = getOrientation (_pnts[*prev], _pnts[*it], _pnts[*next]);
+	if (orientation == COLLINEAR) {
+		it = _vertex_list.erase (it);
+	}
+	if (orientation == CW) {
+		_convex_vertex_list.push_back (*it);
+		if (isEar (*prev, *it, *next))
+			_ear_list.push_back (*it);
+	}
+}
+
+void EarClippingTriangulation::clipEars()
+{
+	std::list<size_t>::iterator it, prev, next;
+	// *** clip an ear
+	while (_vertex_list.size() > 3) {
+		// pop ear from list
+		size_t ear = _ear_list.front();
+		_ear_list.pop_front();
+		// remove ear tip from _convex_vertex_list
+		_convex_vertex_list.remove(ear);
+
+		// remove ear from vertex_list, apply changes to _ear_list, _convex_vertex_list
+		bool nfound(true);
+		it = _vertex_list.begin();
+		prev = _vertex_list.end();
+		prev--;
+		while (nfound && it != _vertex_list.end()) {
+			if (*it == ear) {
+				nfound = false;
+				it = _vertex_list.erase(it); // remove ear tip
+				next = it;
+				if (next == _vertex_list.end()) {
+					next = _vertex_list.begin();
+					prev = _vertex_list.end();
+					prev--;
+				}
+				// add triangle
+				_triangles.push_back(GEOLIB::Triangle(_pnts, *prev, ear, *next));
+
+				// check the orientation of prevprev, prev, next
+				std::list<size_t>::iterator prevprev;
+				if (prev == _vertex_list.begin()) {
+					prevprev = _vertex_list.end();
+				} else {
+					prevprev = prev;
+				}
+				prevprev--;
+
+				// apply changes to _convex_vertex_list and _ear_list looking "backward"
+				MathLib::Orientation orientation = getOrientation(_pnts[*prevprev], _pnts[*prev],
+						_pnts[*next]);
+				if (orientation == CW) {
+					BASELIB::uniqueListInsert(_convex_vertex_list, *prev);
+					// prev is convex
+					if (isEar(*prevprev, *prev, *next)) {
+						// prev is an ear tip
+						BASELIB::uniqueListInsert(_ear_list, *prev);
+					} else {
+						// if necessary remove prev
+						_ear_list.remove(*prev);
+					}
+				} else {
+					// prev is not convex => reflex or collinear
+					_convex_vertex_list.remove(*prev);
+					_ear_list.remove(*prev);
+					if (orientation == COLLINEAR) {
+						prev = _vertex_list.erase(prev);
+						if (prev == _vertex_list.begin()) {
+							prev = _vertex_list.end();
+							prev--;
+						} else {
+							prev--;
+						}
+					}
+				}
+
+				// check the orientation of prev, next, nextnext
+				std::list<size_t>::iterator nextnext,
+						help_it(_vertex_list.end());
+				help_it--;
+				if (next == help_it) {
+					nextnext = _vertex_list.begin();
+				} else {
+					nextnext = next;
+					nextnext++;
+				}
+
+				// apply changes to _convex_vertex_list and _ear_list looking "forward"
+				orientation = getOrientation(_pnts[*prev], _pnts[*next],
+						_pnts[*nextnext]);
+				if (orientation == CW) {
+					BASELIB::uniqueListInsert(_convex_vertex_list, *next);
+					// next is convex
+					if (isEar(*prev, *next, *nextnext)) {
+						// next is an ear tip
+						BASELIB::uniqueListInsert(_ear_list, *next);
+					} else {
+						// if necessary remove *next
+						_ear_list.remove(*next);
+					}
+				} else {
+					// next is not convex => reflex or collinear
+					_convex_vertex_list.remove(*next);
+					_ear_list.remove(*next);
+					if (orientation == COLLINEAR) {
+						next = _vertex_list.erase(next);
+						if (next == _vertex_list.end())
+							next = _vertex_list.begin();
+					}
+				}
+			} else {
+				prev = it;
+				it++;
+			}
+		}
+
+	}
+	// add last triangle
+	next = _vertex_list.begin();
+	prev = next;
+	next++;
+	it = next;
+	next++;
+	if (getOrientation(_pnts[*prev], _pnts[*it], _pnts[*next]) == CCW)
+		_triangles.push_back(GEOLIB::Triangle(_pnts, *prev, *next, *it));
+	else
+		_triangles.push_back(GEOLIB::Triangle(_pnts, *prev, *it, *next));
+}
+
+} // end namespace MathLib
diff --git a/MathLib/EarClippingTriangulation.h b/MathLib/EarClippingTriangulation.h
new file mode 100644
index 0000000000000000000000000000000000000000..77b8e6000fc17dbbadffd735d8e685324e63e07c
--- /dev/null
+++ b/MathLib/EarClippingTriangulation.h
@@ -0,0 +1,59 @@
+/*
+ * EarClippingTriangulation.h
+ *
+ *  Created on: Feb 23, 2011
+ *      Author: TF
+ */
+
+#ifndef EARCLIPPINGTRIANGULATION_H_
+#define EARCLIPPINGTRIANGULATION_H_
+
+// STL
+#include <list>
+
+// GEOLIB
+#include "Polygon.h"
+#include "Triangle.h"
+
+// MathLib
+#include "AnalyticalGeometry.h"
+
+namespace MathLib {
+
+class EarClippingTriangulation {
+public:
+	EarClippingTriangulation(const GEOLIB::Polygon* ply, std::list<GEOLIB::Triangle> &triangles, bool rot = true);
+	virtual ~EarClippingTriangulation();
+private:
+	/**
+	 * copies the points of the polygon to the vector _pnts
+	 */
+	inline void copyPolygonPoints (const GEOLIB::Polygon* polygon);
+	inline void rotate ();
+	inline void ensureCWOrientation ();
+
+	inline bool isEar(size_t v0, size_t v1, size_t v2) const;
+
+	inline void initVertexList ();
+	inline void initLists ();
+	inline void clipEars ();
+
+	/**
+	 * a copy of the polygon points
+	 */
+	std::vector<GEOLIB::Point*> _pnts;
+	std::list<size_t> _vertex_list;
+	std::list<size_t> _convex_vertex_list;
+	std::list<size_t> _ear_list;
+
+	/**
+	 * triangles of the triangulation (maybe in the wrong orientation)
+	 */
+	std::list<GEOLIB::Triangle> _triangles;
+
+	MathLib::Orientation _original_orient;
+};
+
+} // end namespace MathLib
+
+#endif /* EARCLIPPINGTRIANGULATION_H_ */
diff --git a/MathLib/LinAlg/Dense/Matrix.h b/MathLib/LinAlg/Dense/Matrix.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0a97fb5e087667095f0ad33ef878c8337e09bd3
--- /dev/null
+++ b/MathLib/LinAlg/Dense/Matrix.h
@@ -0,0 +1,291 @@
+/*
+ * \file Matrix.h
+ *
+ *  Created on: Mar 24, 2010
+ *      Author: TF
+ *  modified on:Jul 13, 2010
+ *      HS & ZC
+ */
+
+#ifndef MATRIX_H
+#define MATRIX_H
+
+#include <new>
+#include <exception>
+#include <stdexcept>
+#include <iostream>
+
+namespace MathLib {
+
+/**
+ * Matrix represents a dense matrix for a numeric data type.
+ */
+template <class T> class Matrix
+{
+public:
+   Matrix (size_t rows, size_t cols);
+   Matrix (size_t rows, size_t cols, const T& val);
+   Matrix (const Matrix &src);
+
+   ~Matrix ();
+
+   size_t getNRows () const { return nrows; }
+   size_t getNCols () const { return ncols; }
+   /**
+    * \f$ y = \alpha \cdot A x + \beta y\f$
+    */
+   void axpy ( T alpha, const T* x, T beta, T* y) const;
+
+   /**
+    * Matrix vector multiplication
+    * @param x
+    * @return
+    */
+   T* operator* (const T *x) const;
+   /**
+    * Matrix matrix addition.
+    * @param mat
+    * @return
+    */
+   Matrix<T>* operator+ (const Matrix<T>& mat) const throw (std::range_error);
+   /**
+    * Matrix matrix subtraction
+    * @param mat
+    * @return
+    */
+   Matrix<T>* operator- (const Matrix<T>& mat) const throw (std::range_error);
+
+   /**
+    * Matrix matrix multiplication \f$ C = A \cdot B\f$
+    * @param mat the matrix \f$ B \f$
+    * @return the matrix \f$ C \f$
+    */
+   Matrix<T>* operator* (const Matrix<T>& mat) const throw (std::range_error);
+
+   /**
+    * matrix transpose
+    * @return the transpose of the matrix
+    */
+   Matrix<T>* transpose() const; // HB & ZC
+
+   Matrix<T>* getSubMatrix (size_t b_row, size_t b_col, size_t e_row, size_t e_col) const throw (std::range_error);
+
+   /**
+    * overwrites values of the matrix with the given sub matrix
+    * @param b_row the first row
+    * @param b_col the first column
+    * @param sub_mat the sub matrix
+    */
+   void setSubMatrix (size_t b_row, size_t b_col, const Matrix<T>& sub_mat) throw (std::range_error);
+
+   inline T & operator() (size_t row, size_t col) throw (std::range_error);
+   inline T & operator() (size_t row, size_t col) const throw (std::range_error);
+
+   /**
+    * writes the matrix entries into the output stream
+    * @param out the output stream
+    */
+   void write (std::ostream& out) const;
+
+   T const* getData () { return data; }
+
+private:
+   // zero based addressing, but Fortran storage layout
+   //inline size_t address(size_t i, size_t j) const { return j*rows+i; };
+   // zero based addressing, C storage layout
+   inline size_t address(size_t i, size_t j) const { return i*ncols+j; };
+
+   size_t nrows;
+   size_t ncols;
+   T *data;
+};
+
+template<class T> Matrix<T>::Matrix (size_t rows, size_t cols)
+      : nrows (rows), ncols (cols), data (new T[nrows*ncols])
+{}
+
+template<class T> Matrix<T>::Matrix (const Matrix& src) :
+	nrows (src.getNRows ()), ncols (src.getNCols ()), data (new T[nrows * ncols])
+{
+   for (size_t i = 0; i < nrows; i++)
+      for (size_t j = 0; j < ncols; j++)
+         data[address(i,j)] = src (i, j);
+}
+
+template <class T> Matrix<T>::~Matrix ()
+{
+   delete [] data;
+}
+
+template<class T> void Matrix<T>::axpy ( T alpha, const T* x, T beta, T* y) const
+{
+   for (size_t i(0); i<nrows; i++) {
+      y[i] += beta * y[i];
+      for (size_t j(0); j<ncols; j++) {
+         y[i] += alpha * data[address(i,j)] * x[j];
+      }
+   }
+}
+
+template<class T> T* Matrix<T>::operator* (const T *x) const
+{
+	T *y (new T[nrows]);
+	for (size_t i(0); i < nrows; i++) {
+		y[i] = 0.0;
+		for (size_t j(0); j < ncols; j++) {
+			y[i] += data[address(i, j)] * x[j];
+		}
+	}
+
+	return y;
+}
+
+// HS initial implementation
+template<class T> Matrix<T>* Matrix<T>::operator+ (const Matrix<T>& mat) const throw (std::range_error)
+{
+	// make sure the two matrices have the same dimension.
+	if (nrows != mat.getNRows() || ncols != mat.getNCols())
+		throw std::range_error("Matrix::operator+, illegal matrix size!");
+
+	Matrix<T>* y(new Matrix<T> (nrows, ncols));
+	for (size_t i = 0; i < nrows; i++) {
+		for (size_t j = 0; j < ncols; j++) {
+			(*y)(i, j) = data[address(i, j)] + mat(i, j);
+		}
+	}
+
+	return y;
+}
+
+// HS initial implementation
+template<class T> Matrix<T>* Matrix<T>::operator- (const Matrix<T>& mat) const throw (std::range_error)
+{
+	// make sure the two matrices have the same dimension.
+	if (nrows != mat.getNRows() || ncols != mat.getNCols())
+		throw std::range_error("Matrix::operator-, illegal matrix size!");
+
+	Matrix<T>* y(new Matrix<T> (nrows, ncols));
+	for (size_t i = 0; i < nrows; i++) {
+		for (size_t j = 0; j < ncols; j++) {
+			(*y)(i, j) = data[address(i, j)] - mat(i, j);
+		}
+	}
+
+	return y;
+}
+
+// HS initial implementation
+template<class T> Matrix<T>* Matrix<T>::operator* (const Matrix<T>& mat) const throw (std::range_error)
+{
+	// make sure the two matrices have the same dimension.
+	if (ncols != mat.getNRows())
+		throw std::range_error(
+				"Matrix::operator*, number of rows and cols should be the same!");
+
+	size_t y_cols(mat.getNCols());
+	Matrix<T>* y(new Matrix<T> (nrows, y_cols, T(0)));
+
+	for (size_t i = 0; i < nrows; i++) {
+		for (size_t j = 0; j < y_cols; j++) {
+			for (size_t k = 0; k < ncols; k++)
+				(*y)(i, j) += data[address(i, k)] * mat(k, j);
+		}
+	}
+
+	return y;
+}
+
+// HS initial implementation
+template<class T> Matrix<T>* Matrix<T>::transpose() const
+{
+	Matrix<T>* y(new Matrix<T> (ncols, nrows));
+
+	for (size_t i = 0; i < nrows; i++) {
+		for (size_t j = 0; j < ncols; j++) {
+//			y->data[y->address(j, i)] = data[address(i, j)];
+			(*y)(j,i) = data[address(i, j)];
+		}
+	}
+	return y;
+}
+
+template<class T> Matrix<T>* Matrix<T>::getSubMatrix(
+		size_t b_row, size_t b_col,
+		size_t e_row, size_t e_col) const throw (std::range_error)
+{
+	if (b_row >= e_row | b_col >= e_col)
+		throw std::range_error ("Matrix::getSubMatrix() illegal sub matrix");
+	if (e_row > nrows | e_col > ncols)
+		throw std::range_error ("Matrix::getSubMatrix() illegal sub matrix");
+
+	Matrix<T>* y(new Matrix<T> (e_row-b_row, e_col-b_col));
+	for (size_t i=b_row; i<e_row; i++) {
+		for (size_t j=b_col; j<e_col; j++) {
+			(*y)(i-b_row, j-b_col) = data[address(i, j)];
+		}
+	}
+	return y;
+}
+
+template<class T> void Matrix<T>::setSubMatrix(
+		size_t b_row, size_t b_col, const Matrix<T>& sub_mat) throw (std::range_error)
+{
+	if (b_row + sub_mat.getNRows() > nrows | b_col + sub_mat.getNCols() > ncols)
+		throw std::range_error ("Matrix::setSubMatrix() sub matrix to big");
+
+	for (size_t i=0; i<sub_mat.getNRows(); i++) {
+		for (size_t j=0; j<sub_mat.getNCols(); j++) {
+			data[address(i+b_row, j+b_col)] = sub_mat(i,j);
+		}
+	}
+}
+
+template<class T> T& Matrix<T>::operator() (size_t row, size_t col)
+	throw (std::range_error)
+{
+   if ( (row >= nrows) | ( col >= ncols) )
+	  throw std::range_error ("Matrix: op() const range error");
+   return data [address(row,col)];
+}
+
+
+template<class T> T& Matrix<T>::operator() (size_t row, size_t col) const
+	throw (std::range_error)
+{
+   if ( (row >= nrows) | ( col >= ncols) )
+      throw std::range_error ("Matrix: op() const range error");
+   return data [address(row,col)];
+}
+
+template <class T> void Matrix<T>::write (std::ostream &out) const
+{
+	for (size_t i = 0; i < nrows; i++) {
+		for (size_t j = 0; j < ncols; j++) {
+			out << data[address(i, j)] << "\t";
+		}
+		out << std::endl;
+	}
+}
+
+template <class T> T sqrFrobNrm (const Matrix<T> &mat)
+{
+	T nrm ((T)(0));
+	size_t i,j;
+	for (j=0; j<mat.getNCols(); j++)
+		for (i=0; i<mat.getNRows(); i++)
+			nrm += mat(i,j) * mat(i,j);
+
+	return nrm;
+}
+
+/** overload the output operator for class Matrix */
+template <class T>
+std::ostream& operator<< (std::ostream &os, const Matrix<T> &mat)
+{
+	mat.write (os);
+	return os;
+}
+
+} // end namespace MathLib
+
+#endif
diff --git a/MathLib/LinAlg/Preconditioner/generateDiagPrecond.cpp b/MathLib/LinAlg/Preconditioner/generateDiagPrecond.cpp
index 4b52b83107b747b9cce5cd3bf43c64ff9bfd89c3..27ca8967a9d4839d8439913e34c9f1aa8d473d0a 100644
--- a/MathLib/LinAlg/Preconditioner/generateDiagPrecond.cpp
+++ b/MathLib/LinAlg/Preconditioner/generateDiagPrecond.cpp
@@ -1,6 +1,8 @@
 #include "sparse.h"
 
-bool generateDiagPrecond (unsigned n, double* A, unsigned* jA, unsigned* iA, 
+namespace MathLib {
+
+bool generateDiagPrecond (unsigned n, unsigned* iA, unsigned* jA, double* A,
 	double* diag)
 {
 	unsigned idx; // first idx of next row
@@ -26,4 +28,4 @@ bool generateDiagPrecond (unsigned n, double* A, unsigned* jA, unsigned* iA,
 	return true;
 }
 
-
+} // end namespace MathLib
diff --git a/MathLib/LinAlg/Preconditioner/generateDiagPrecond.h b/MathLib/LinAlg/Preconditioner/generateDiagPrecond.h
new file mode 100644
index 0000000000000000000000000000000000000000..66f7989650d4f24960fe4a60a975ffa53c7ae588
--- /dev/null
+++ b/MathLib/LinAlg/Preconditioner/generateDiagPrecond.h
@@ -0,0 +1,17 @@
+/*
+ * generateDiagPrecond.h
+ *
+ *  Created on: Sep 28, 2011
+ *      Author: TF
+ */
+
+#ifndef GENERATEDIAGPRECOND_H_
+#define GENERATEDIAGPRECOND_H_
+
+namespace MathLib {
+
+bool generateDiagPrecond (unsigned n, unsigned* iA, unsigned* jA, double* A, double* diag);
+
+} // end namespace MathLib
+
+#endif /* PRECONDITIONER_H_ */
diff --git a/MathLib/LinAlg/Solvers/CG.cpp b/MathLib/LinAlg/Solvers/CG.cpp
index 50cab766b9b6ea4c0cacb2620a3353b740bb155b..05c2f1d977f0943cf644b04b4473a172c4e55c39 100644
--- a/MathLib/LinAlg/Solvers/CG.cpp
+++ b/MathLib/LinAlg/Solvers/CG.cpp
@@ -12,10 +12,6 @@
 #include "../Sparse/CRSMatrix.h"
 #include "../Sparse/CRSMatrixDiagPrecond.h"
 
-#ifndef NDEBUG
-#include <iostream>
-#endif
-
 // CG solves the symmetric positive definite linear
 // system Ax=b using the Conjugate Gradient method.
 //
@@ -37,12 +33,12 @@ unsigned CG(CRSMatrix<double> const * mat, double const * const b,
 	unsigned N = mat->getNRows();
 	double *p, *q, *r, *rhat, rho, rho1 = 0.0;
 
-	p = new double[4* N ];
+	p = new double[4* N];
 	q = p + N;
 	r = q + N;
 	rhat = r + N;
 
-	double nrmb = sqrt(scpr(N, b, b, num_threads));
+	double nrmb = sqrt(scpr(b, b, N));
 	if (nrmb < std::numeric_limits<double>::epsilon()) {
 		blas::setzero(N, x);
 		eps = 0.0;
@@ -58,18 +54,15 @@ unsigned CG(CRSMatrix<double> const * mat, double const * const b,
 	}
 
 	double resid = blas::nrm2(N, r);
-	out << "0\t" << resid / nrmb << std::endl;
 	if (resid <= eps * nrmb) {
 		eps = resid / nrmb;
 		nsteps = 0;
 		delete[] p;
-		out.close();
 		return 0;
 	}
 
 	for (unsigned l = 1; l <= nsteps; ++l) {
 
-		out << l << "\t" << resid / nrmb << std::endl;
 #ifndef NDEBUG
 		std::cout << "Step " << l << ", resid=" << resid / nrmb << std::endl;
 #endif
@@ -97,7 +90,7 @@ unsigned CG(CRSMatrix<double> const * mat, double const * const b,
 		mat->amux(D_ONE, p, q);
 
 		// alpha = rho / p*q
-		double alpha = rho / scpr(N, p, q);
+		double alpha = rho / scpr(p, q, N);
 
 		// x += alpha * p
 		blas::axpy(N, alpha, p, x);
@@ -105,7 +98,7 @@ unsigned CG(CRSMatrix<double> const * mat, double const * const b,
 		// r -= alpha * q
 		blas::axpy(N, -alpha, q, r);
 
-		resid = sqrt(scpr(N, r, r));
+		resid = sqrt(scpr(r, r, N));
 
 		if (resid <= eps * nrmb) {
 			eps = resid / nrmb;
@@ -116,7 +109,6 @@ unsigned CG(CRSMatrix<double> const * mat, double const * const b,
 
 		rho1 = rho;
 	}
-	out.close();
 	eps = resid / nrmb;
 	delete[] p;
 	return 1;
diff --git a/MathLib/LinAlg/Solvers/CG.h b/MathLib/LinAlg/Solvers/CG.h
index 5cf6dbf38d1f4017647edb3964e9176de18acaf5..36cd6917402f478be69b95e0bc1f90878894dc9e 100644
--- a/MathLib/LinAlg/Solvers/CG.h
+++ b/MathLib/LinAlg/Solvers/CG.h
@@ -1,130 +1,21 @@
 /*
- * CG.h
+ * solver.h
  *
  *  Created on: Sep 27, 2011
  *      Author: TF
  */
 
-#include "blas.h"
-#include "CG.h"
-#include <limits>
-#include "CRSMatrix.h"
-#include "CRSMatrixDiagPrecond.h"
-#include "sparse.h"
+#ifndef CG_H_
+#define CG_H_
 
-#include <fstream>
-
-#ifndef NDEBUG
-#include <iostream>
-#endif
-
-// CG solves the symmetric positive definite linear
-// system Ax=b using the Conjugate Gradient method.
-//
-// The return value indicates convergence within max_iter (input)
-// iterations (0), or no convergence within max_iter iterations (1).
-//
-// Upon successful return, output arguments have the following values:
-//
-//      x  --  approximate solution to Ax = b
-// nsteps  --  the number of iterations performed before the
-//             tolerance was reached
-//    eps  --  the residual after the final iteration
+namespace MathLib {
 
+// forward declaration
+template <typename T> class CRSMatrix;
 
 unsigned CG(CRSMatrix<double> const * mat, double const * const b,
-	double* const x, double& eps, unsigned& nsteps, unsigned num_threads)
-{
-  unsigned N = mat->getNRows();
-  double *p, *q, *r, *rhat, rho, rho1 = 0.0;
-
-  p = new double[4*N];
-  q = p + N;
-  r = q + N;
-  rhat = r + N;
-
-  double nrmb = sqrt(scpr(N, b, b, num_threads));
-  if (nrmb < std::numeric_limits<double>::epsilon()) {
-    blas::setzero(N, x);
-    eps = 0.0;
-    nsteps = 0;
-    delete [] p;
-    return 0;
-  }
-
-  // r0 = b - Ax0
-  mat->amux (D_MONE, x, r);
-  for (unsigned k(0); k<N; k++) {
-  	r[k] = b[k] - r[k];
-  }
-
-  std::ofstream out ("residuen.txt");
-
-  double resid = blas::nrm2(N, r);
-  out << "0\t" << resid/nrmb << std::endl;
-  if (resid <= eps*nrmb) {
-    eps = resid / nrmb;
-    nsteps = 0;
-    delete [] p;
-    out.close();
-    return 0;
-  }
-
-  for (unsigned l=1; l<=nsteps; ++l) {
-
-	  out << l << "\t" << resid/nrmb << std::endl;
-#ifndef NDEBUG
-    std::cout << "Step " << l << ", resid=" << resid/nrmb << std::endl;
-#endif
-
-    // r^ = C r
-    blas::copy(N, r, rhat);
-    mat->precondApply(rhat);
-
-    // rho = r * r^;
-    rho = scpr(N, r, rhat, num_threads);
-
-    if (l>1) {
-	double beta = rho / rho1;
-	// p = r^ + beta * p
-	unsigned k;
-	omp_set_num_threads (num_threads);
-	#pragma omp parallel for
-	for(k=0; k<N; k++) {
-		p[k] = rhat[k] + beta * p[k];
-	}
-    }
-    else
-      blas::copy(N, rhat, p);
-
-    // q = Ap
-    blas::setzero(N, q);
-    mat->amux (D_ONE, p, q);
-
-    // alpha = rho / p*q
-    double alpha = rho / scpr(N, p, q);
-
-    // x += alpha * p
-    blas::axpy(N, alpha, p, x);
-
-    // r -= alpha * q
-    blas::axpy(N, -alpha, q, r);
-
-    resid = sqrt(scpr(N,r,r));
-
-    if (resid<=eps*nrmb) {
-      eps = resid/nrmb;
-      nsteps = l;
-      delete [] p;
-      return 0;
-    }
-
-    rho1 = rho;
-  }
-  out.close();
-  eps = resid / nrmb;
-  delete [] p;
-  return 1;
-}
+		double* const x, double& eps, unsigned& nsteps, unsigned num_threads = 1);
 
+} // end namespace MathLib
 
+#endif /* SOLVER_H_ */
diff --git a/MathLib/LinAlg/Solvers/DenseDirectLinearSolver.h b/MathLib/LinAlg/Solvers/DenseDirectLinearSolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..3ef0205c502fc07d7b133515a933f7fe1c504493
--- /dev/null
+++ b/MathLib/LinAlg/Solvers/DenseDirectLinearSolver.h
@@ -0,0 +1,23 @@
+/*
+ * DenseDirectLinearSolver.h
+ *
+ *  Created on: Jan 7, 2011
+ *      Author: TF
+ */
+
+#ifndef DENSEDIRECTLINEARSOLVER_H_
+#define DENSEDIRECTLINEARSOLVER_H_
+
+#include "DirectLinearSolver.h"
+
+namespace MathLib {
+
+class DenseDirectLinearSolver: public MathLib::DirectLinearSolver {
+public:
+	DenseDirectLinearSolver() {};
+	virtual ~DenseDirectLinearSolver() {};
+};
+
+}
+
+#endif /* DENSEDIRECTLINEARSOLVER_H_ */
diff --git a/MathLib/LinAlg/Solvers/DirectLinearSolver.h b/MathLib/LinAlg/Solvers/DirectLinearSolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..46daf3b2f4f20eebe85b60c8d9821dde345f0e95
--- /dev/null
+++ b/MathLib/LinAlg/Solvers/DirectLinearSolver.h
@@ -0,0 +1,24 @@
+/*
+ * DirectLinearSolver.h
+ *
+ *  Created on: Jan 7, 2011
+ *      Author: TF
+ */
+
+#ifndef DIRECTLINEARSOLVER_H_
+#define DIRECTLINEARSOLVER_H_
+
+#include "LinearSolver.h"
+
+namespace MathLib {
+
+class DirectLinearSolver : public MathLib::LinearSolver
+{
+public:
+	DirectLinearSolver() {};
+	virtual ~DirectLinearSolver() {};
+};
+
+}
+
+#endif /* DIRECTLINEARSOLVER_H_ */
diff --git a/MathLib/LinAlg/Solvers/GaussAlgorithm.cpp b/MathLib/LinAlg/Solvers/GaussAlgorithm.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..98007abaf93e22fa66e300f39ee437970208353b
--- /dev/null
+++ b/MathLib/LinAlg/Solvers/GaussAlgorithm.cpp
@@ -0,0 +1,66 @@
+/*
+ * GaussAlgorithm.cpp
+ *
+ *  Created on: May 6, 2010
+ *      Author: TF
+ */
+
+#include <cmath>
+#include "GaussAlgorithm.h"
+#include "swap.h"
+
+namespace MathLib {
+
+GaussAlgorithm::GaussAlgorithm (Matrix <double> &A) :
+	_mat (A), _n(_mat.getNRows()), _perm (new size_t [_n])
+{
+	size_t k, i, j, nr (_mat.getNRows()), nc(_mat.getNCols());
+	double l;
+
+	for (k=0; k<nc; k++) {
+		// search pivot
+		double t = fabs(_mat(k, k));
+		_perm[k] = k;
+		for (i=k+1; i<nr; i++) {
+			if (fabs(_mat(i,k)) > t) {
+				t = _mat(i,k);
+				_perm[k] = i;
+			}
+		}
+
+		// exchange rows
+		if (_perm[k] != k) {
+			for (j=0; j<nc; j++) BASELIB::swap (_mat(_perm[k],j), _mat(k,j));
+		}
+
+		// eliminate
+		for (i=k+1; i<nr; i++) {
+			l=_mat(i,k)/_mat(k,k);
+			for (j=k; j<nc; j++) {
+				_mat(i,j) -= _mat(k,j) * l;
+			}
+			_mat(i,k) = l;
+		}
+	}
+}
+
+GaussAlgorithm::~GaussAlgorithm()
+{
+	delete [] _perm;
+}
+
+void GaussAlgorithm::execute (double *b) const
+{
+	permuteRHS (b);
+	forwardSolve (_mat, b); // L z = b, b will be overwritten by z
+	backwardSolve (_mat, b); // U x = z, b (z) will be overwritten by x
+}
+
+void GaussAlgorithm::permuteRHS (double* b) const
+{
+	for (size_t i=0; i<_n; i++) {
+		if (_perm[i] != i) BASELIB::swap(b[i], b[_perm[i]]);
+	}
+}
+
+} // end namespace MathLib
diff --git a/MathLib/LinAlg/Solvers/GaussAlgorithm.h b/MathLib/LinAlg/Solvers/GaussAlgorithm.h
new file mode 100644
index 0000000000000000000000000000000000000000..ad1422593965c248090086d97fd6717b0550a62c
--- /dev/null
+++ b/MathLib/LinAlg/Solvers/GaussAlgorithm.h
@@ -0,0 +1,74 @@
+/*
+ * GaussAlgorithm.h
+ *
+ *  Created on: May 6, 2010
+ *      Author: TF
+ */
+
+#ifndef GAUSSALGORITHM_H_
+#define GAUSSALGORITHM_H_
+
+#include <cstddef>
+#include "../Dense/Matrix.h"
+#include "DenseDirectLinearSolver.h"
+#include "TriangularSolve.h"
+
+namespace MathLib {
+
+/**
+ * This is a class for the direct solution of (dense) systems of
+ * linear equations, \f$A x = b\f$. During the construction of
+ * the object the matrix A is factorized in matrices L and U using
+ * Gauss-Elimination with partial pivoting (rows are exchanged). In doing so
+ * the entries of A change! The solution for a specific
+ * right hand side is computed by the method execute().
+ */
+class GaussAlgorithm : public MathLib::DenseDirectLinearSolver {
+public:
+	/**
+	 * A direct solver for the (dense) linear system \f$A x = b\f$.
+	 * @param A at the beginning the matrix A, at the end of the construction
+	 * of the object the matrix contains the factor L (without the diagonal)
+	 * in the strictly lower part and the factor U in the upper part.
+	 * The diagonal entries of L are all 1.0 and are not explicitly stored.
+	 * Attention: the given matrix will be destroyed!
+	 * @return a object of type GaussAlgorithm
+	 */
+	GaussAlgorithm(Matrix<double> &A);
+	/**
+	 * destructor, deletes the permutation
+	 */
+	~GaussAlgorithm();
+
+	/**
+	 * Method solves the linear system \f$A x = b\f$ (based on the LU factorization)
+	 * using forward solve and backward solve
+	 * @param b at the beginning the right hand side, at the end the solution
+	 */
+	void execute (double *b) const;
+
+private:
+	/**
+	 * permute the right hand side vector according to the
+	 * row permutations of the LU factorization
+	 * @param b the entries of the vector b are permuted
+	 */
+	void permuteRHS (double* b) const;
+
+	/**
+	 * a reference to the matrix
+	 */
+	Matrix<double>& _mat;
+	/**
+	 * the size of the matrix
+	 */
+	size_t _n;
+	/**
+	 * the permutation of the rows
+	 */
+	size_t* _perm;
+};
+
+} // end namespace MathLib
+
+#endif /* GAUSSALGORITHM_H_ */
diff --git a/MathLib/LinAlg/Solvers/IterativeLinearSolver.h b/MathLib/LinAlg/Solvers/IterativeLinearSolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e8b9e39202287f5d31da85591a23f45e2a89d11
--- /dev/null
+++ b/MathLib/LinAlg/Solvers/IterativeLinearSolver.h
@@ -0,0 +1,23 @@
+/*
+ * IterativeLinearSolver.h
+ *
+ *  Created on: Jan 7, 2011
+ *      Author: TF
+ */
+
+#ifndef ITERATIVELINEARSOLVER_H_
+#define ITERATIVELINEARSOLVER_H_
+
+#include <LinearSolver.h>
+
+namespace MathLib {
+
+class IterativeLinearSolver: public MathLib::LinearSolver {
+public:
+	IterativeLinearSolver() {};
+	virtual ~IterativeLinearSolver() {};
+};
+
+}
+
+#endif /* ITERATIVELINEARSOLVER_H_ */
diff --git a/MathLib/LinAlg/Solvers/LinearSolver.h b/MathLib/LinAlg/Solvers/LinearSolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..1264649dc08598cad631767856a48ad77fb05264
--- /dev/null
+++ b/MathLib/LinAlg/Solvers/LinearSolver.h
@@ -0,0 +1,24 @@
+/*
+ * LinearSolver.h
+ *
+ *  Created on: Jan 7, 2011
+ *      Author: TF
+ */
+
+#ifndef LINEARSOLVER_H_
+#define LINEARSOLVER_H_
+
+namespace MathLib {
+
+/**
+ * Base class for all linear solver classes.
+ */
+class LinearSolver {
+public:
+	LinearSolver() {};
+	virtual ~LinearSolver() {};
+};
+
+}
+
+#endif /* LINEARSOLVER_H_ */
diff --git a/MathLib/LinAlg/Solvers/TriangularSolve.cpp b/MathLib/LinAlg/Solvers/TriangularSolve.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8fbfb5e3306162eacb258cafb8f74a85576bdd6e
--- /dev/null
+++ b/MathLib/LinAlg/Solvers/TriangularSolve.cpp
@@ -0,0 +1,53 @@
+/*
+ * TriangularSolve.cpp
+ *
+ *  Created on: May 5, 2010
+ *      Author: TF
+ */
+
+#include "../Dense/Matrix.h"
+
+namespace MathLib {
+
+void forwardSolve (const Matrix <double> &L, double* b)
+{
+	size_t m (L.getNRows());
+	double t;
+
+	for (size_t r=0; r<m; r++) {
+		t = 0.0;
+		for (size_t c=0; c<r; c++) {
+			t += L(r,c)*b[c];
+		}
+		b[r] = b[r]-t;
+	}
+}
+
+void backwardSolve (const Matrix <double> &mat, double* b)
+{
+	double t;
+	size_t m (mat.getNRows()), n(mat.getNCols());
+	for (int r=m-1; r>=0; r--) {
+		t = 0.0;
+		for (size_t c=r+1; c<n; c++) {
+			t += mat(r,c)*b[c];
+		}
+		b[r] = (b[r]-t) / mat(r,r);
+	}
+}
+
+void backwardSolve ( Matrix<double> const& mat, double* x, double* b)
+{
+	size_t n_cols (mat.getNCols());
+	for (int r = (n_cols - 1); r >= 0; r--) {
+		double t = 0.0;
+
+		for (size_t c = r+1; c < n_cols; c++) {
+			t += mat(r,c) * b[c];
+		}
+		x[r] = (b[r] - t) / mat(r, r);
+	}
+}
+
+
+} // end namespace MathLib
diff --git a/MathLib/LinAlg/Solvers/TriangularSolve.h b/MathLib/LinAlg/Solvers/TriangularSolve.h
new file mode 100644
index 0000000000000000000000000000000000000000..d7cd92664327f7e5246d905e3771da000c35d70b
--- /dev/null
+++ b/MathLib/LinAlg/Solvers/TriangularSolve.h
@@ -0,0 +1,43 @@
+/*
+ * TriangularSolve.h
+ *
+ *  Created on: May 6, 2010
+ *      Author: TF
+ */
+
+#ifndef TRIANGULARSOLVE_H_
+#define TRIANGULARSOLVE_H_
+
+#include "../Dense/Matrix.h"
+
+namespace MathLib {
+
+/**
+ * solves the \f$n \times n\f$ triangular linear system \f$L \cdot y = b\f$,
+ * assumes \f$L_{ii} = 1.0\f$, \f$i=1,...,n\f$, \f$b\f$ is destroyed
+ * @param L the lower triangular matrix
+ * @param b at beginning the right hand side vector, at the end the solution vector
+ */
+void forwardSolve (const Matrix <double> &L, double* b);
+
+/**
+ * solves the \f$n \times n\f$ triangular linear system \f$U \cdot x=y\f$,
+ * \f$U\f$, where \f$U\f$ is a upper triangular matrix.
+ * @param U upper triangular matrix
+ * @param y at beginning the right hand side, at the end the solution
+ */
+void backwardSolve (const Matrix <double> &U, double* y);
+
+// backwardSolve mat * x = y, mat ... upper triangular matrix
+/**
+ * backward solve the system of linear equations \f$ U \cdot x = y\f$,
+ * where \f$U\f$ is a upper triangular matrix
+ * @param mat the upper triangular matrix
+ * @param x the solution of the system of linear equations
+ * @param b the right hand side
+ */
+void backwardSolve ( Matrix<double> const& mat, double* x, double* b);
+
+} // end namespace MathLib
+
+#endif /* TRIANGULARSOLVE_H_ */
diff --git a/MathLib/LinAlg/Solvers/blas.h b/MathLib/LinAlg/Solvers/blas.h
index 231042bc9e3c2a26abd01a51777837ef7136740d..81513665b20ac717de6ea18beea5cee3423339fd 100644
--- a/MathLib/LinAlg/Solvers/blas.h
+++ b/MathLib/LinAlg/Solvers/blas.h
@@ -1,9 +1,8 @@
 #ifndef BLAS_H
 #define BLAS_H
 
-#include <assert.h>
-#include <stdlib.h>
-
+#include <cassert>
+#include <cstdlib>
 #include <cmath>
 
 #define SIGN(a) ((a) >= 0 ? 1.0 : -1.0)
@@ -303,13 +302,13 @@ namespace blas
 //  inline void conj(unsigned n, double* v) {}
 //  inline void conj(unsigned n, float* v) {}
 
-  inline void swap(const unsigned n, double* x, const unsigned incx, 
+  inline void swap(const unsigned n, double* x, const unsigned incx,
 		   double* y, const unsigned incy )
   {
     dswap_(&n, x, &incx, y, &incy);
   }
 
-  inline void swap(const unsigned n, float* x, const unsigned incx, 
+  inline void swap(const unsigned n, float* x, const unsigned incx,
 		   float* y, const unsigned incy )
   {
     sswap_(&n, x, &incx, y, &incy);
@@ -499,7 +498,7 @@ namespace blas
 
 
   // y = d Ax
-  inline void gemv(const unsigned m, const unsigned n, double d, 
+  inline void gemv(const unsigned m, const unsigned n, double d,
 		   const double* A, double *x, double *y)
   {
     dgemv_(JOB_STR, &m, &n, &d, A, &m, x, &N_ONE, &D_ZERO, y, &N_ONE);
@@ -582,16 +581,16 @@ namespace blas
   }
 
   // C = d A B, A is m x p, B is p x n
-  inline void gemm(const unsigned m, const unsigned p, const unsigned n, 
-		   const double d, const double* const A, const unsigned ldA, 
+  inline void gemm(const unsigned m, const unsigned p, const unsigned n,
+		   const double d, const double* const A, const unsigned ldA,
 		   const double* const B, const unsigned ldB,
 		   double* C, const unsigned ldC)
   {
     dgemm_(JOB_STR, JOB_STR, &m, &n, &p, &d, A, &ldA, B, &ldB,
 	   &D_ZERO, C, &ldC);
   }
-  inline void gemm(const unsigned m, const unsigned p, const unsigned n, 
-		   const float d, const float* const A, const unsigned ldA, 
+  inline void gemm(const unsigned m, const unsigned p, const unsigned n,
+		   const float d, const float* const A, const unsigned ldA,
 		   const float* const B, const unsigned ldB,
 		   float* C, const unsigned ldC)
   {
@@ -600,16 +599,16 @@ namespace blas
   }
 
   // C += d A B, A is m x p, B is p x n
-  inline void gemma(const unsigned m, const unsigned p, const unsigned n, 
-		    const double d, const double* const A, const unsigned ldA, 
+  inline void gemma(const unsigned m, const unsigned p, const unsigned n,
+		    const double d, const double* const A, const unsigned ldA,
 		    const double* const B, const unsigned ldB,
 		    double* C, const unsigned ldC)
   {
     dgemm_(JOB_STR, JOB_STR, &m, &n, &p, &d, A, &ldA, B, &ldB,
 	   &D_ONE, C, &ldC);
   }
-  inline void gemma(const unsigned m, const unsigned p, const unsigned n, 
-		    const float d, const float* const A, const unsigned ldA, 
+  inline void gemma(const unsigned m, const unsigned p, const unsigned n,
+		    const float d, const float* const A, const unsigned ldA,
 		    const float* const B, const unsigned ldB,
 		    float* C, const unsigned ldC)
   {
@@ -618,16 +617,16 @@ namespace blas
   }
 
   // C = d A^H B, A is m x p, B is m x n
-  inline void gemhm(const unsigned m, const unsigned p, const unsigned n, 
-		    const double d, const double* A, const unsigned ldA, 
+  inline void gemhm(const unsigned m, const unsigned p, const unsigned n,
+		    const double d, const double* A, const unsigned ldA,
 		    const double *B, const unsigned ldB,
 		    double* C, const unsigned ldC)
   {
     dgemm_(JOB_STR+1, JOB_STR, &p, &n, &m, &d, A, &ldA, B, &ldB,
 	   &D_ZERO, C, &ldC);
   }
-  inline void gemhm(const unsigned m, const unsigned p, const unsigned n, 
-		    const float d, const float* const A, const unsigned ldA, 
+  inline void gemhm(const unsigned m, const unsigned p, const unsigned n,
+		    const float d, const float* const A, const unsigned ldA,
 		    const float* const B, const unsigned ldB,
 		    float* C, const unsigned ldC)
   {
@@ -637,14 +636,14 @@ namespace blas
 
   // C += d A^H B, A is m x p, B is m x n
   inline void gemhma(unsigned m, unsigned p, unsigned n, double d,
-		     const double* const A, const unsigned ldA, const double* const B, 
+		     const double* const A, const unsigned ldA, const double* const B,
 		     const unsigned ldB, double* C, unsigned ldC)
   {
     dgemm_(JOB_STR+1, JOB_STR, &p, &n, &m, &d, A, &ldA, B, &ldB,
 	   &D_ONE, C, &ldC);
   }
   inline void gemhma(unsigned m, unsigned p, unsigned n, float d,
-		     const float* const A, const unsigned ldA, const float* const B, 
+		     const float* const A, const unsigned ldA, const float* const B,
 		     const unsigned ldB, float* C, unsigned ldC)
   {
     sgemm_(JOB_STR+1, JOB_STR, &p, &n, &m, &d, A, &ldA, B, &ldB,
@@ -652,16 +651,16 @@ namespace blas
   }
 
   // C = d A B^H, A is m x p, B is n x p
-  inline void gemmh(const unsigned m, const unsigned p, const unsigned n, 
-		    const double d, const double* const A, const unsigned ldA, 
+  inline void gemmh(const unsigned m, const unsigned p, const unsigned n,
+		    const double d, const double* const A, const unsigned ldA,
 		    const double* const B, const unsigned ldB,
 		    double* C, const unsigned ldC)
   {
     dgemm_(JOB_STR, JOB_STR+1, &m, &n, &p, &d, A, &ldA, B, &ldB,
 	   &D_ZERO, C, &ldC);
   }
-  inline void gemmh(const unsigned m, const unsigned p, const unsigned n, 
-		    const float d, const float* const A, const unsigned ldA, 
+  inline void gemmh(const unsigned m, const unsigned p, const unsigned n,
+		    const float d, const float* const A, const unsigned ldA,
 		    const float* const B, const unsigned ldB,
 		    float* C, const unsigned ldC)
   {
@@ -670,16 +669,16 @@ namespace blas
   }
 
   // C += d A B^H, A is m x p, B is n x p
-  inline void gemmha(const unsigned m, const unsigned p, const unsigned n, 
-		     const double d, const double* const A, const unsigned ldA, 
+  inline void gemmha(const unsigned m, const unsigned p, const unsigned n,
+		     const double d, const double* const A, const unsigned ldA,
 		     const double* const B, const unsigned ldB,
 		     double* C, const unsigned ldC)
   {
     dgemm_(JOB_STR, JOB_STR+1, &m, &n, &p, &d, A, &ldA, B, &ldB,
 	   &D_ONE, C, &ldC);
   }
-  inline void gemmha(const unsigned m, const unsigned p, const unsigned n, 
-		     const float d, const float* const A, const unsigned ldA, 
+  inline void gemmha(const unsigned m, const unsigned p, const unsigned n,
+		     const float d, const float* const A, const unsigned ldA,
 		     const float* const B, const unsigned ldB,
 		     float* C, const unsigned ldC)
   {
@@ -687,7 +686,7 @@ namespace blas
 	   &S_ONE, C, &ldC);
   }
   inline void gemmha(const unsigned m, const unsigned p, const unsigned n,
-		     const double* const A, const unsigned ldA, 
+		     const double* const A, const unsigned ldA,
 		     const double* const B, const unsigned ldB,
 		     double* C, const unsigned ldC)
   {
@@ -695,7 +694,7 @@ namespace blas
 	   &D_ONE, C, &ldC);
   }
   inline void gemmha(const unsigned m, const unsigned p, const unsigned n,
-		     const float* const A, const unsigned ldA, 
+		     const float* const A, const unsigned ldA,
 		     const float* const B, const unsigned ldB,
 		     float* C, const unsigned ldC)
   {
@@ -704,16 +703,16 @@ namespace blas
   }
 
   // C = d A^H B^H, A is p x m, B is n x p
-  inline void gemhmh(const unsigned m, const unsigned p, const unsigned n, 
-		     const double d, const double* const A, const unsigned ldA, 
+  inline void gemhmh(const unsigned m, const unsigned p, const unsigned n,
+		     const double d, const double* const A, const unsigned ldA,
 		     const double* const B, const unsigned ldB,
 		     double* C, const unsigned ldC)
   {
     dgemm_(JOB_STR+1, JOB_STR+1, &m, &n, &p, &d, A, &ldA, B, &ldB,
 	   &D_ZERO, C, &ldC);
   }
-  inline void gemhmh(const unsigned m, const unsigned p, const unsigned n, 
-		     const float d, const float* const A, const unsigned ldA, 
+  inline void gemhmh(const unsigned m, const unsigned p, const unsigned n,
+		     const float d, const float* const A, const unsigned ldA,
 		     const float* const B, const unsigned ldB,
 		     float* C, const unsigned ldC)
   {
@@ -722,8 +721,8 @@ namespace blas
   }
 
   //C += d*AB, A is mxm (packed upper half is stored), B is mxn and regular matrix
-  inline void sygemma(const unsigned m, const unsigned n, 
-		      const double* const A, const double* const B, 
+  inline void sygemma(const unsigned m, const unsigned n,
+		      const double* const A, const double* const B,
 		      const double d, double* const C)
   {
     for(unsigned i=0;i<m;i++){
@@ -739,8 +738,8 @@ namespace blas
       }
     }
   }
-  inline void sygemma(const unsigned m, const unsigned n, 
-		      const float* const A, const float* const B, 
+  inline void sygemma(const unsigned m, const unsigned n,
+		      const float* const A, const float* const B,
 		      const float d, float* const C)
   {
     for(unsigned i=0;i<m;i++){
@@ -794,7 +793,7 @@ namespace blas
   }
 
   // C += d A^H A, C is a symm. matrix (packed upper half is stored), A is mxn
-  inline void symhm(const unsigned m, const unsigned n, const double* const A, 
+  inline void symhm(const unsigned m, const unsigned n, const double* const A,
 		    const double d, double* C)
   {
     for (unsigned j=0; j<n; ++j) {
@@ -805,7 +804,7 @@ namespace blas
       }
     }
   }
-  inline void symhm(const unsigned m, const unsigned n, const float* const A, 
+  inline void symhm(const unsigned m, const unsigned n, const float* const A,
 		    const float d, float* C)
   {
     for (unsigned j=0; j<n; ++j) {
@@ -1002,7 +1001,7 @@ namespace blas
 		   const unsigned ldC, unsigned nwk, double* wk)
   {
     int INF;
-    dormqr_(JOB_STR+6, JOB_STR, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk, 
+    dormqr_(JOB_STR+6, JOB_STR, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk,
 	    &INF);
     return INF;
   }
@@ -1011,7 +1010,7 @@ namespace blas
 		   const unsigned ldC, unsigned nwk, float* wk)
   {
     int INF;
-    sormqr_(JOB_STR+6, JOB_STR, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk, 
+    sormqr_(JOB_STR+6, JOB_STR, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk,
 	    &INF);
     return INF;
   }
@@ -1022,7 +1021,7 @@ namespace blas
 		    const unsigned ldC, unsigned nwk, double* wk)
   {
     int INF;
-    dormqr_(JOB_STR+6, JOB_STR+1, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk, 
+    dormqr_(JOB_STR+6, JOB_STR+1, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk,
 	    &INF);
     return INF;
   }
@@ -1031,7 +1030,7 @@ namespace blas
 		    const unsigned ldC, unsigned nwk, float* wk)
   {
     int INF;
-    sormqr_(JOB_STR+6, JOB_STR+1, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk, 
+    sormqr_(JOB_STR+6, JOB_STR+1, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk,
 	    &INF);
     return INF;
   }
@@ -1041,7 +1040,7 @@ namespace blas
 		    unsigned nwk, double* wk)
   {
     int INF;
-    dormqr_(JOB_STR+6, JOB_STR+1, &m, &n, &p, A, &ldA, tau, C, &m, wk, &nwk, 
+    dormqr_(JOB_STR+6, JOB_STR+1, &m, &n, &p, A, &ldA, tau, C, &m, wk, &nwk,
 	    &INF);
     return INF;
   }
@@ -1050,7 +1049,7 @@ namespace blas
 		    unsigned nwk, float* wk)
   {
     int INF;
-    sormqr_(JOB_STR+6, JOB_STR+1, &m, &n, &p, A, &ldA, tau, C, &m, wk, &nwk, 
+    sormqr_(JOB_STR+6, JOB_STR+1, &m, &n, &p, A, &ldA, tau, C, &m, wk, &nwk,
 	    &INF);
     return INF;
   }
@@ -1076,7 +1075,7 @@ namespace blas
 		   const unsigned ldC, unsigned nwk, double* wk)
   {
     int INF;
-    dormqr_(JOB_STR+8, JOB_STR, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk, 
+    dormqr_(JOB_STR+8, JOB_STR, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk,
 	    &INF);
     return INF;
   }
@@ -1085,7 +1084,7 @@ namespace blas
 		   const unsigned ldC, unsigned nwk, float* wk)
   {
     int INF;
-    sormqr_(JOB_STR+8, JOB_STR, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk, 
+    sormqr_(JOB_STR+8, JOB_STR, &m, &n, &p, A, &ldA, tau, C, &ldC, wk, &nwk,
 	    &INF);
     return INF;
   }
@@ -1129,9 +1128,9 @@ namespace blas
   }
 
   // product of upper triangular and regular Matrix  M = R A, R mxp, A nxp
-  inline void utrgemmh(const unsigned m, const unsigned p, const unsigned n, 
-		       const double* const R, const unsigned ldR, 
-		       const double* const A, const unsigned ldA, 
+  inline void utrgemmh(const unsigned m, const unsigned p, const unsigned n,
+		       const double* const R, const unsigned ldR,
+		       const double* const A, const unsigned ldA,
 		       double* const M, const unsigned ldM)
   {
     for (unsigned i=0; i<m; ++i) {
@@ -1143,8 +1142,8 @@ namespace blas
       }
     }
   }
-  inline void utrgemmh(const unsigned m, const unsigned p, const unsigned n, 
-		       const float* const R, const unsigned ldR, 
+  inline void utrgemmh(const unsigned m, const unsigned p, const unsigned n,
+		       const float* const R, const unsigned ldR,
 		       const float* const A, const unsigned ldA,
 		       float* const M, const unsigned ldM)
   {
@@ -1160,14 +1159,14 @@ namespace blas
 
   // product of two upper triangular matrices M = R1 R2^T, R1 mxp, R2 nxp
   inline void utrmmh(const unsigned m, const unsigned p, const unsigned n,
-		     const double* const R1, const unsigned ldR1, 
+		     const double* const R1, const unsigned ldR1,
 		     const double* const R2, const unsigned ldR2,
 		     double* const M)
   {
     for (unsigned j=0; j<n; ++j) {
       for (unsigned i=0; i<m; ++i) {
 	double d = D_ZERO;
-	unsigned ij = MAX(i,j); 
+	unsigned ij = MAX(i,j);
 	for (unsigned l=ij; l<p; ++l)
 	  d += R1[i+l*ldR1]*R2[j+l*ldR2];
 	M[i+j*m] = d;
@@ -1175,7 +1174,7 @@ namespace blas
     }
   }
   inline void utrmmh(const unsigned m, const unsigned p, const unsigned n,
-		     const float* const R1, const unsigned ldR1, 
+		     const float* const R1, const unsigned ldR1,
 		     const float* const R2, const unsigned ldR2,
 		     float* const M)
   {
@@ -1187,11 +1186,11 @@ namespace blas
 	  d += R1[i+l*ldR1]*R2[j+l*ldR2];
 	M[i+j*m] = d;
       }
-    }	
+    }
   }
   // product of two upper triangular matrices M += R1 R2^T, R1 mxp, R2 nxp
   inline void utrmmha(const unsigned m, const unsigned p, const unsigned n,
-		      const double* const R1, const unsigned ldR1, 
+		      const double* const R1, const unsigned ldR1,
 		      const double* const R2, const unsigned ldR2,
 		      double* const M)
   {
@@ -1204,7 +1203,7 @@ namespace blas
     }
   }
   inline void utrmmha(const unsigned m, const unsigned p, const unsigned n,
-		      const float* const R1, const unsigned ldR1, 
+		      const float* const R1, const unsigned ldR1,
 		      const float* const R2, const unsigned ldR2,
 		      float* const M)
   {
@@ -1307,7 +1306,7 @@ namespace blas
     unsigned* ip = new unsigned[n];
     for(unsigned i=0;i<n;i++)
       ip[i]=L[((2*n-i+1)*i)/2];
-    
+
     for(unsigned j=0;j<n;j++){
       const unsigned ipj = ip[j];
       const unsigned idUj = (ipj*(ipj+1))/2;
@@ -1322,7 +1321,7 @@ namespace blas
 	  A[i]+=U[idUk+i]*t;
       }
       A+=n;
-    } 
+    }
     delete [] ip;
   }
 
@@ -1332,7 +1331,7 @@ namespace blas
     unsigned* ip = new unsigned[n];
     for(unsigned i=0;i<n;i++)
       ip[i]=L[((2*n-i+1)*i)/2];
-    
+
     for(unsigned j=0;j<n;j++){
       const unsigned ipj = ip[j];
       const unsigned idUj = (ipj*(ipj+1))/2;
@@ -1347,7 +1346,7 @@ namespace blas
 	  A[i]+=U[idUk+i]*t;
       }
       A+=n;
-    } 
+    }
     delete [] ip;
   }
 
@@ -1634,8 +1633,8 @@ namespace lapack
     dtrsm_(JOB_STR+8, JOB_STR+6, JOB_STR, JOB_STR+5, &n, &p, &D_ONE,
 	   LR, &ldLR, X, &ldX);
   }
-  
- 
+
+
   // unit lower triangular transposed solve (with L and R stored in one matrix)
   // XL^T=B, L is pxp, B is nxp
   inline void ltrhcs(const unsigned p, double* LR, const unsigned ldLR,
diff --git a/MathLib/LinAlg/Solvers/solver.h b/MathLib/LinAlg/Solvers/solver.h
index 79772ef87580ef1a84b8f90f26199a3223d7bd55..d89a01b897ba2a07e99a3539b26318241ef468d7 100644
--- a/MathLib/LinAlg/Solvers/solver.h
+++ b/MathLib/LinAlg/Solvers/solver.h
@@ -2,7 +2,7 @@
  * solver.h
  *
  *  Created on: Sep 27, 2011
- *      Author: fischeth
+ *      Author: TF
  */
 
 #ifndef SOLVER_H_
diff --git a/MathLib/LinAlg/Sparse/CRSMatrix.h b/MathLib/LinAlg/Sparse/CRSMatrix.h
index 977cc91b2bff7561125596e909b6caf0cd19fad6..a2c889cf3926acd1967fbdc0fadd95e299438283 100644
--- a/MathLib/LinAlg/Sparse/CRSMatrix.h
+++ b/MathLib/LinAlg/Sparse/CRSMatrix.h
@@ -14,6 +14,7 @@
 #include "SparseMatrixBase.h"
 #include "sparse.h"
 #include "amuxCRS.h"
+#include "../Preconditioner/generateDiagPrecond.h"
 
 namespace MathLib {
 
@@ -54,6 +55,9 @@ public:
 		amuxCRS(d, MatrixBase::_n_rows, _row_ptr, _col_idx, _data, x, y);
 	}
 
+    virtual void precondApply(T* x) const
+    {}
+
 protected:
 	unsigned *_row_ptr;
 	unsigned *_col_idx;
diff --git a/MathLib/LinAlg/Sparse/CRSMatrixDiagPrecond.h b/MathLib/LinAlg/Sparse/CRSMatrixDiagPrecond.h
index 2335eedf001f7cf4b6af353402fc9a9fd2fc2bf8..30c4f4b0cc301d4117751181dce255268e730614 100644
--- a/MathLib/LinAlg/Sparse/CRSMatrixDiagPrecond.h
+++ b/MathLib/LinAlg/Sparse/CRSMatrixDiagPrecond.h
@@ -5,12 +5,15 @@
 
 #include "CRSMatrix.h"
 #include "sparse.h"
+#include "../Preconditioner/generateDiagPrecond.h"
+
+namespace MathLib {
 
 class CRSMatrixDiagPrecond : public CRSMatrix<double>
 {
 public:
-	CRSMatrixDiagPrecond (std::string const &fname, unsigned num_of_threads=1) 
-		: CRSMatrix<double>(fname, num_of_threads), _inv_diag(NULL) 
+	CRSMatrixDiagPrecond (std::string const &fname)
+		: CRSMatrix<double>(fname), _inv_diag(NULL)
 	{
 		_inv_diag = new double[_n_rows];
 		if (!generateDiagPrecond (_n_rows, _row_ptr, _col_idx, _data, _inv_diag)) {
@@ -19,7 +22,6 @@ public:
 	}
 
 	void precondApply(double* x) const {
-		omp_set_num_threads( _num_of_threads );
 		{
 			unsigned k;
 			#pragma omp parallel for
@@ -36,5 +38,7 @@ private:
 	double *_inv_diag;
 };
 
+}
+
 #endif
 
diff --git a/MathLib/LinAlg/Sparse/amuxCRS.cpp b/MathLib/LinAlg/Sparse/amuxCRS.cpp
index 22e9aef84bdeddad579bcc320864ad62e6ad0929..a5f4e57f3924e5c74f9e88aa4f6d609dd5478fae 100644
--- a/MathLib/LinAlg/Sparse/amuxCRS.cpp
+++ b/MathLib/LinAlg/Sparse/amuxCRS.cpp
@@ -7,9 +7,10 @@
 
 #include "amuxCRS.h"
 #include <omp.h>
-#include <omp.h>
 #include <pthread.h>
 
+namespace MathLib {
+
 void amuxCRS (double a,
 	unsigned n, unsigned const * const iA, unsigned const * const jA,
         double const * const A, double const * const x, double* y)
@@ -153,3 +154,4 @@ void amuxCRSSym (double a,
 	}
 }
 
+} // end namespace MathLib
diff --git a/MathLib/LinAlg/Sparse/amuxCRS.h b/MathLib/LinAlg/Sparse/amuxCRS.h
index 24ec77d6fa41dac6530ab06821e5cf96a3213246..b1845218f8c5e8f3ad6f9a48c448b7e1eada5a67 100644
--- a/MathLib/LinAlg/Sparse/amuxCRS.h
+++ b/MathLib/LinAlg/Sparse/amuxCRS.h
@@ -1,16 +1,18 @@
 #ifndef AMUXCRS_H
 #define AMUXCRS_H
 
-void amuxCRS (double a, 
+namespace MathLib {
+
+void amuxCRS (double a,
 	unsigned n, unsigned const * const iA, unsigned const * const jA,
         double const * const A, double const * const x, double* y);
 
-void amuxCRSParallelPThreads (double a, 
+void amuxCRSParallelPThreads (double a,
 	unsigned n, unsigned const * const iA, unsigned const * const jA,
         double const * const A, double const * const x, double* y,
 	unsigned num_of_pthreads);
 
-void amuxCRSParallelOpenMP (double a, 
+void amuxCRSParallelOpenMP (double a,
 	unsigned n, unsigned const * const iA, unsigned const * const jA,
         double const * const A, double const * const x, double* y,
 	unsigned num_of_omp_threads);
@@ -19,4 +21,6 @@ void amuxCRSSym (double a,
 	unsigned n, unsigned const * const iA, unsigned const * const jA,
         double const * const A, double const * const x, double* y);
 
+} // end namespace MathLib
+
 #endif
diff --git a/MathLib/LinAlg/VectorNorms.h b/MathLib/LinAlg/VectorNorms.h
new file mode 100644
index 0000000000000000000000000000000000000000..31bbf802f8cd969b12b14f6f4f12d7cb94d89d66
--- /dev/null
+++ b/MathLib/LinAlg/VectorNorms.h
@@ -0,0 +1,24 @@
+/*
+ * VectorNorms.h
+ *
+ *  Created on: Jun 6, 2011
+ *      Author: TF
+ */
+
+#ifndef VECTORNORMS_H_
+#define VECTORNORMS_H_
+
+#include <cmath>
+
+#include "MathTools.h"
+
+namespace MathLib {
+
+double normEuklid (double const * const vec, size_t n)
+{
+	return sqrt (scpr (vec, vec, n));
+}
+
+} // end namespace MathLib
+
+#endif /* VECTORNORMS_H_ */
diff --git a/MathLib/LinearInterpolation.cpp b/MathLib/LinearInterpolation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6853843b6a69800d2e8c44c54d2769c5b5860b4d
--- /dev/null
+++ b/MathLib/LinearInterpolation.cpp
@@ -0,0 +1,55 @@
+/*
+ * LinearInterpolation.cpp
+ *
+ *  Created on: Sep 7, 2010
+ *      Author: TF
+ */
+
+#include "LinearInterpolation.h"
+#include "binarySearch.h"
+#include "swap.h"
+
+#include <iostream>
+
+namespace MathLib {
+
+LinearInterpolation::LinearInterpolation(const std::vector<double>& supporting_points, const std::vector<double>& values_at_supp_pnts)
+	: _supporting_points (supporting_points), _values_at_supp_pnts (values_at_supp_pnts)
+{}
+
+LinearInterpolation::LinearInterpolation(const std::vector<double>& supporting_points, const std::vector<double>& values_at_supp_pnts, const std::vector<double>& points_to_interpolate, std::vector<double>& values_at_interpol_pnts)
+	: _supporting_points (supporting_points), _values_at_supp_pnts (values_at_supp_pnts)
+{
+//	std::cout << "LinearInterpolation::LinearInterpolation support_points, values_at_supp_pnts: " << std::endl;
+//	for (size_t k(0); k<supporting_points.size(); k++) {
+//		std::cout << supporting_points[k] << " " << values_at_supp_pnts[k] << std::endl;
+//	}
+//	std::cout << std::endl;
+	values_at_interpol_pnts.clear();
+	for (size_t k(0); k<points_to_interpolate.size(); k++)
+		values_at_interpol_pnts.push_back (this->getValue (points_to_interpolate[k]));
+}
+
+LinearInterpolation::~LinearInterpolation()
+{}
+
+double LinearInterpolation::getValue ( double pnt_to_interpolate )
+{
+	// search interval that has the point inside
+	size_t interval_idx (std::numeric_limits<size_t>::max());
+	for (size_t k(1); k<_supporting_points.size() && interval_idx == std::numeric_limits<size_t>::max(); k++) {
+		if (_supporting_points[k-1] <= pnt_to_interpolate && pnt_to_interpolate <= _supporting_points[k]) {
+			interval_idx = k-1;
+		}
+	}
+
+	// compute linear interpolation polynom: y = m * x + n
+	long double m ((_values_at_supp_pnts[interval_idx+1] - _values_at_supp_pnts[interval_idx]) / (_supporting_points[interval_idx+1] - _supporting_points[interval_idx]));
+//	double m ((_values_at_supp_pnts[interval_idx] - _values_at_supp_pnts[interval_idx+1]) / (_supporting_points[interval_idx] - _supporting_points[interval_idx+1]));
+//	double n (_values_at_supp_pnts[interval_idx+1] - m * _supporting_points[interval_idx+1]);
+	long double n (_values_at_supp_pnts[interval_idx] - m * _supporting_points[interval_idx]);
+
+	return m * pnt_to_interpolate + n;
+}
+
+} // end MathLib
diff --git a/MathLib/LinearInterpolation.h b/MathLib/LinearInterpolation.h
new file mode 100644
index 0000000000000000000000000000000000000000..7e5f746cd621fcdadc530b3264ae578f05c61dfc
--- /dev/null
+++ b/MathLib/LinearInterpolation.h
@@ -0,0 +1,31 @@
+/*
+ * LinearInterpolation.h
+ *
+ *  Created on: Sep 7, 2010
+ *      Author: TF
+ */
+
+#ifndef LINEARINTERPOLATION_H_
+#define LINEARINTERPOLATION_H_
+
+#include <vector>
+#include <limits>
+
+namespace MathLib {
+
+class LinearInterpolation {
+public:
+	LinearInterpolation(const std::vector<double>& supporting_points, const std::vector<double>& values_at_supp_pnts);
+	LinearInterpolation(const std::vector<double>& supporting_points, const std::vector<double>& values_at_supp_pnts, const std::vector<double>& points_to_interpolate, std::vector<double>& values_at_interpol_pnts);
+	virtual ~LinearInterpolation();
+
+	double getValue ( double pnt_to_interpolate );
+
+private:
+	const std::vector<double>& _supporting_points;
+	const std::vector<double>& _values_at_supp_pnts;
+};
+
+} // end namespace MathLib
+
+#endif /* LINEARINTERPOLATION_H_ */
diff --git a/MathLib/LinkedTriangle.cpp b/MathLib/LinkedTriangle.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2207b967cff9f6b590ac39dd96d988809e360a2e
--- /dev/null
+++ b/MathLib/LinkedTriangle.cpp
@@ -0,0 +1,83 @@
+/*
+ * LinkedTriangle.cpp
+ *
+ *  Created on: Mar 25, 2010
+ *      Author: fischeth
+ */
+
+#include "LinkedTriangle.h"
+
+namespace MathLib {
+
+LinkedTriangle::LinkedTriangle(std::vector<GEOLIB::Point*> const &pnt_vec,
+		size_t pnt_a, size_t pnt_b, size_t pnt_c, LinkedTriangle* tri_a,
+		LinkedTriangle* tri_b, LinkedTriangle* tri_c) :
+	GEOLIB::Triangle(pnt_vec, pnt_a, pnt_b, pnt_c)
+{
+	if (tri_a) _neighbor_triangles[0] = tri_a;
+	else _neighbor_triangles[0] = NULL;
+	if (tri_b) _neighbor_triangles[1] = tri_b;
+	else _neighbor_triangles[1] = NULL;
+	if (tri_c) _neighbor_triangles[2] = tri_c;
+	else _neighbor_triangles[2] = NULL;
+}
+
+void LinkedTriangle::setNeighborTriangle(size_t idx, LinkedTriangle* tri)
+{
+	assert(idx < 3);
+	_neighbor_triangles[idx] = tri;
+}
+
+void LinkedTriangle::setNeighborTriangleByPointIdx (size_t idx, LinkedTriangle* tri)
+{
+	if (idx == _pnt_ids[0]) setNeighborTriangle (0, tri);
+	else {
+		if (idx == _pnt_ids[1]) setNeighborTriangle (1, tri);
+		else setNeighborTriangle (2, tri);
+	}
+}
+
+LinkedTriangle* LinkedTriangle::getNeighborTriangle(size_t idx)
+{
+	assert(idx < 3);
+	return _neighbor_triangles[idx];
+}
+
+size_t LinkedTriangle::getIdxOfNeighborTriangle(LinkedTriangle* tri)
+{
+	 if (tri == _neighbor_triangles[0]) return 0;
+	 if (tri == _neighbor_triangles[1]) return 1;
+	 if (tri == _neighbor_triangles[2]) return 2;
+	 return 3;
+}
+
+size_t LinkedTriangle::getIdxOfPoint (size_t i) const
+{
+	if (_pnt_ids[0] == i) return 0;
+	if (_pnt_ids[1] == i) return 1;
+	if (_pnt_ids[2] == i) return 2;
+	return 3;
+}
+
+void LinkedTriangle::writeNeighbor (std::ostream &os, size_t idx) const
+{
+	if (_neighbor_triangles[idx]) {
+		os << "[";
+		(_neighbor_triangles[idx])->write (os);
+		os << "]";
+	}
+	else os << "NULL";
+}
+
+LinkedTriangle::~LinkedTriangle()
+{
+	// TODO Auto-generated destructor stub
+}
+
+std::ostream& operator<< (std::ostream &os, const LinkedTriangle &tri)
+{
+	tri.write (os);
+	return os;
+}
+
+} // end namespace MathLib
diff --git a/MathLib/LinkedTriangle.h b/MathLib/LinkedTriangle.h
new file mode 100644
index 0000000000000000000000000000000000000000..46cdf8321be7e48a6c6cf8ae5421616b6694428a
--- /dev/null
+++ b/MathLib/LinkedTriangle.h
@@ -0,0 +1,54 @@
+/*
+ * LinkedTriangle.h
+ *
+ *  Created on: Mar 25, 2010
+ *      Author: fischeth
+ */
+
+#ifndef LINKEDTRIANGLE_H_
+#define LINKEDTRIANGLE_H_
+
+#include <vector>
+#include <iostream>
+
+// GEO
+#include "Triangle.h"
+#include "Point.h"
+
+namespace MathLib {
+
+class LinkedTriangle : public GEOLIB::Triangle {
+public:
+	LinkedTriangle(std::vector<GEOLIB::Point*> const&pnt_vec, size_t pnt_a,
+			size_t pnt_b, size_t pnt_c, LinkedTriangle* tri_a,
+			LinkedTriangle* tri_b, LinkedTriangle* tri_c);
+	virtual ~LinkedTriangle();
+
+	void setNeighborTriangle (size_t idx, LinkedTriangle* tri);
+	void setNeighborTriangleByPointIdx (size_t idx, LinkedTriangle* tri);
+
+	LinkedTriangle* getNeighborTriangle (size_t idx);
+	size_t getIdxOfNeighborTriangle(LinkedTriangle* tri);
+
+	size_t getIdxOfPoint (size_t i) const;
+
+	void write (std::ostream &os) const
+	{
+		os << _pnt_ids[0] << " " << _pnt_ids[1] << " " << _pnt_ids[2];
+	}
+
+	void writeNeighbor (std::ostream &os, size_t idx) const;
+
+private:
+	/**
+	 * pointers to the neighbor triangles
+	 */
+	LinkedTriangle* _neighbor_triangles[3];
+};
+
+/** overload the output operator for class LinkedTriangle */
+std::ostream& operator<< (std::ostream &os, const LinkedTriangle &tri);
+
+} // end namespace MathLib
+
+#endif /* LINKEDTRIANGLE_H_ */
diff --git a/MathLib/Vector3.h b/MathLib/Vector3.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd59d36f8567724555003068ecfb000f8ca0261f
--- /dev/null
+++ b/MathLib/Vector3.h
@@ -0,0 +1,160 @@
+/**
+ * \file Vector3.h
+ * 27/10/2009 LB Initial implementation
+ * From: http://www.strout.net/info/coding/classlib/intro.html
+ * with modifications to derive from TemplatePoint
+ */
+
+#ifndef VECTOR3_H
+#define VECTOR3_H
+
+// GEO
+#include "TemplatePoint.h"
+
+// MathLib
+#include "MathTools.h"
+
+#include <iostream>
+#include <cmath>
+
+namespace MathLib {
+
+/**
+ * The Vector class defines a three-dimensional vector, with appropriate
+ *	operators.  (* is cross product.)
+ */
+template <class T>
+class TemplateVector : public GEOLIB::TemplatePoint<T>
+{
+public:
+	TemplateVector() : GEOLIB::TemplatePoint<T>() {};
+	TemplateVector(T x1, T x2, T x3) : GEOLIB::TemplatePoint<T>(x1, x2, x3) {};
+ 	TemplateVector(const GEOLIB::TemplatePoint<T> & rhs) :
+ 		GEOLIB::TemplatePoint<T>(rhs[0], rhs[1], rhs[2])
+ 	{}
+ 	/** constructs a vector from the gien points */
+ 	TemplateVector(const GEOLIB::TemplatePoint<T> &a, const GEOLIB::TemplatePoint<T> &b) :
+ 	 	GEOLIB::TemplatePoint<T>(b[0]-a[0], b[1]-a[1], b[2]-a[2])
+ 	{}
+	~TemplateVector() {};
+
+	// vector arithmetic
+
+	TemplateVector operator+(const TemplateVector & pV) const
+	{
+		return TemplateVector(this->x[0]+pV[0], this->x[1]+pV[1], this->x[2]+pV[2] );
+	}
+
+	TemplateVector operator-(const TemplateVector & pV) const {
+		TemplateVector out( this->x[0]-pV[0], this->x[1]-pV[1], this->x[2]-pV[2] );
+		return out;
+	}
+
+	TemplateVector operator-() const
+	{ return TemplateVector (-this->x[0], -this->x[1], -this->x[2]); }
+
+	TemplateVector& operator+=(const TemplateVector & pV) {
+		for (size_t i(0); i<3; i++) this->x[i]+=pV[i];
+		return *this;
+	}
+
+	TemplateVector& operator+=(const GEOLIB::TemplatePoint<T>& pnt)
+	{
+		for (size_t i(0); i<3; i++) this->_x[i] += pnt[i];
+		return *this;
+	}
+
+	TemplateVector& operator-=(const TemplateVector & pV)
+	{
+		for (size_t i(0); i<3; i++) this->_x[i] -= pV[i];
+		return *this;
+	}
+
+	// Accessors
+	T X() const { return this->_x[0]; }
+	T Y() const { return this->_x[1]; }
+	T Z() const { return this->_x[2]; }
+	void setX(T value) { this->_x[0] = value; }
+	void setY(T value) { this->_x[1] = value; }
+	void setZ(T value) { this->_x[2] = value; }
+
+	/// Dot product with another vector
+	double Dot(const TemplateVector & pV) const
+	{
+		return this->_x[0]*pV[0] + this->_x[1]*pV[1] + this->_x[2]*pV[2];
+	}
+
+	/// Cross product as the multiplication operator
+	TemplateVector operator*(const TemplateVector & pV) const {
+		return TemplateVector (
+				this->_x[1]*pV[2]-this->_x[2]*pV[1],
+				this->_x[2]*pV[0]-this->_x[0]*pV[2],
+				this->_x[0]*pV[1]-this->_x[1]*pV[0] );
+	}
+
+	/// Cross product with another vector
+	TemplateVector Cross( const TemplateVector & pV ) const
+	{ return *this * pV; }
+
+	friend double Dot( const TemplateVector & p1, const TemplateVector & p2 )
+	{ return p1.Dot(p2); }
+
+	friend TemplateVector Cross( const TemplateVector & p1, const TemplateVector & p2 )
+	{ return p1 * p2; }
+
+	TemplateVector operator*(double pR) const		// * a scalar
+	{
+		return TemplateVector(this->x[0]*pR, this->x[1]*pR, this->x[2]*pR);
+	}
+
+	friend TemplateVector operator*(double pR, const TemplateVector & pV)
+	{
+		return TemplateVector ( pV[0]*pR, pV[1]*pR, pV[2]*pR );
+	}
+
+	TemplateVector& operator*=(double pR)
+	{
+		for (size_t i(0); i<3; i++) this->_x[i]*=pR;
+		return *this;
+	}
+
+	/// Returns the squared length
+	double LenSqr(void) const
+	{
+		return scpr (this->getData (), this->getData (), 3);
+	}
+
+	/// Returns the length
+	double Length(void) const
+	{ return sqrt(LenSqr()); }
+
+	/// Projection (component of *this parallel to pV).
+	/// Note: component perpendicular to pV is:  *this - Proj(pV)
+	TemplateVector Proj(const TemplateVector & pV)
+	{ TemplateVector out( pV * (this->Dot(pV) / pV.LenSqr()) ); return out; }
+
+	/// Cosine of the angle between two vectors:
+	double CosAng(const TemplateVector& pV)
+	{ return this->Dot(pV) / (Length() * pV.Length()); }
+
+	/// Comparison if equal
+	bool operator==( const TemplateVector & pV) const
+	{
+		return (std::fabs(this->_x[0] - pV[0]) < sqrt(std::numeric_limits<double>::min()) &&
+				std::fabs(this->_x[1] - pV[1]) < sqrt(std::numeric_limits<double>::min()) &&
+				std::fabs(this->_x[2] - pV[2]) < sqrt(std::numeric_limits<double>::min()));
+	}
+
+	/// Comparison if not equal
+	bool operator!=( const TemplateVector & pV) const
+	{
+		return (! (pV == this));
+//		this->_x[0]!=pV[0] || this->_x[1]!=pV[1] || this->_x[2]!=pV[2];
+	}
+};
+
+typedef TemplateVector<double> Vector;
+
+}
+
+#endif // VECTOR3_H
diff --git a/MathLib/max.h b/MathLib/max.h
new file mode 100644
index 0000000000000000000000000000000000000000..f98c375dd6d23236ab91c2c088e50348c2dc3d2b
--- /dev/null
+++ b/MathLib/max.h
@@ -0,0 +1,20 @@
+/*
+ * max.h
+ *
+ *  Created on: Apr 20, 2010
+ *      Author: TF
+ */
+
+#ifndef MAX_H_
+#define MAX_H_
+
+/**
+ * max returns the maximum of its arguments
+ */
+template<class T> T max(const T& arg0, const T& arg1)
+{
+  if (arg0 < arg1) return arg1;
+  return arg0;
+}
+
+#endif /* MAX_H_ */
diff --git a/MathLib/vector_io.h b/MathLib/vector_io.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab6ef2b935758c2c9af2ab43b1dfc27942c28722
--- /dev/null
+++ b/MathLib/vector_io.h
@@ -0,0 +1,95 @@
+#ifndef VECTOR_IO_H
+#define VECTOR_IO_H
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+// von http://www.zfx.info/Display/Thread.php?TID=177779
+#include <sstream>
+
+#ifdef UNICODE
+typedef std::wstringstream unistringstream;
+typedef std::wstring unistring;
+#else
+typedef std::stringstream unistringstream;
+typedef std::string unistring;
+#endif
+
+template<typename A, typename T> inline const A lexical_cast(const T& source)
+{
+	unistringstream s;
+
+	s << source;
+
+	A destination;
+	s >> destination;
+
+	return (destination);
+}
+
+/** reads the number of lines of non-binary stream */
+unsigned readLines ( std::istream &in )
+{
+	unsigned k = 0;
+	while (!in.eof()) {
+		std::string str;
+		getline (in, str);
+		k++;
+	}
+
+	return k;
+}
+
+/** reads N values of non-binary stream */
+template <class T> void read ( std::istream &in, unsigned N, T *a )
+{
+	unsigned k = 0;
+	std::string ws (" \t");
+
+	while (!in.eof () and k <= N) {
+		std::string t;
+		 getline (in, t);
+		size_t i1;
+		if (t.length () != 0) {
+			i1 = t.find_first_not_of (ws, 0);
+			if (i1 != std::string::npos) {
+				size_t i2 = t.find_first_of (ws, i1);
+				if (i2 != std::string::npos) {
+					a[k++] = lexical_cast<T> ( t.substr(i1, i2-i1) );
+				} else {
+					a[k++] = lexical_cast<T> ( t.substr(i1, t.size()-i1));
+				}
+			}
+		}
+	}
+}
+
+template <class T> int readArrays ( const std::string &fname, size_t &s,
+	size_t n, T* &arr )
+{
+	// open stream
+	std::ifstream in (fname.c_str());
+	// read number of rows
+	if (in) {
+		s = readLines(in)-1;
+		in.close();
+	} else {
+		std::cout << "could not open " << fname << std::endl;
+		return 1;
+	}
+	if (s > 0) {
+		arr = new T[s * n];
+		size_t j(0), l(0);
+		// read values
+		in.open (fname.c_str(), std::ios::in);
+		for (j=0; j<s; ++j) {
+			for (l=0; l<n; l++) in >> arr[l*s+j];
+		}
+		in.close ();
+	}
+	return 0;
+}
+
+#endif
+
diff --git a/SimpleTests/SolverTests/CMakeLists.txt b/SimpleTests/SolverTests/CMakeLists.txt
index 67123af78461ff0d22f9f63b1c480485bcfafedf..439de4a1d68c60c31c5d62213b7168bcf08e945f 100644
--- a/SimpleTests/SolverTests/CMakeLists.txt
+++ b/SimpleTests/SolverTests/CMakeLists.txt
@@ -27,7 +27,6 @@ ADD_EXECUTABLE( ConjugateGradientUnpreconditioned
 
 ADD_EXECUTABLE( ConjugateGradientDiagPrecond
         ConjugateGradientDiagonalPreconditioned.cpp
-        ../Preconditioner/generateDiagPrecond.cpp
         ${SOURCES}
         ${HEADERS}
 )
@@ -35,10 +34,14 @@ ADD_EXECUTABLE( ConjugateGradientDiagPrecond
 TARGET_LINK_LIBRARIES ( ConjugateGradientUnpreconditioned
         ${BLAS_LIBRARIES}
         ${LAPACK_LIBRARIES}
+	MathLib
+	Base
 )
 
 TARGET_LINK_LIBRARIES ( ConjugateGradientDiagPrecond
         ${BLAS_LIBRARIES}
         ${LAPACK_LIBRARIES}
+	MathLib
+	Base
 )
 
diff --git a/SimpleTests/SolverTests/ConjugateGradientDiagonalPreconditioned.cpp b/SimpleTests/SolverTests/ConjugateGradientDiagonalPreconditioned.cpp
index 263f9ffb57228140fe2f65b40fac052a33c0bb19..043afa1fce8f63f801f4860ed1d06bb5ec1d8204 100644
--- a/SimpleTests/SolverTests/ConjugateGradientDiagonalPreconditioned.cpp
+++ b/SimpleTests/SolverTests/ConjugateGradientDiagonalPreconditioned.cpp
@@ -1,12 +1,14 @@
 #include <fstream>
 #include <iostream>
 #include <cmath>
+#include <cstdlib>
 #include <omp.h>
-#include "CG.h"
-#include "CRSMatrixDiagPrecond.h"
+#include "LinAlg/Solvers/CG.h"
+#include "LinAlg/Sparse/CRSMatrixDiagPrecond.h"
 #include "sparse.h"
 #include "vector_io.h"
-#include "timeMeasurement.h"
+#include "RunTimeTimer.h"
+#include "CPUTimeTimer.h"
 
 int main(int argc, char *argv[])
 {
@@ -15,13 +17,13 @@ int main(int argc, char *argv[])
 		return -1;
 	}
 
-	// read number of threads       
+	// read number of threads
 	unsigned num_omp_threads (1);
 	num_omp_threads = atoi (argv[3]);
 
 	// *** reading matrix in crs format from file
 	std::string fname(argv[1]);
-	CRSMatrixDiagPrecond *mat (new CRSMatrixDiagPrecond(fname, num_omp_threads));
+	MathLib::CRSMatrixDiagPrecond *mat (new MathLib::CRSMatrixDiagPrecond(fname));
 
 	unsigned n (mat->getNRows());
 	bool verbose (true);
@@ -48,22 +50,27 @@ int main(int argc, char *argv[])
 		}
 	}
 
-	
+
 	if (verbose)
 		std::cout << "solving system with PCG method (diagonal preconditioner) ... " << std::flush;
-	time_t start_time, end_time;
-	time(&start_time);
-	double cg_time (cputime(0.0));
+
 	double eps (1.0e-6);
 	unsigned steps (4000);
-	CG (mat, b, x, eps, steps, num_omp_threads);
-	cg_time = cputime(cg_time);
-	time(&end_time);
+	RunTimeTimer run_timer;
+	CPUTimeTimer cpu_timer;
+	run_timer.start();
+	cpu_timer.start();
+
+	MathLib::CG (mat, b, x, eps, steps, num_omp_threads);
+
+	cpu_timer.stop();
+	run_timer.stop();
+
 	if (verbose) {
 		std::cout << " in " << steps << " iterations" << std::endl;
-		std::cout << "\t(residuum is " << eps << ") took " << cg_time << " sec time and " << (end_time-start_time) << " sec" << std::endl;
+		std::cout << "\t(residuum is " << eps << ") took " << cpu_timer.elapsed() << " sec time and " << run_timer.elapsed() << " sec" << std::endl;
 	} else {
-		std::cout << end_time-start_time << std::endl;
+		std::cout << cpu_timer.elapsed() << std::endl;
 	}
 
 	delete mat;
diff --git a/SimpleTests/SolverTests/ConjugateGradientUnpreconditioned.cpp b/SimpleTests/SolverTests/ConjugateGradientUnpreconditioned.cpp
index d24ccac97ec13afbff538c7c90f67e20618014b6..2413a1502def9a6f29460fd0d8bf7edd2f33532c 100644
--- a/SimpleTests/SolverTests/ConjugateGradientUnpreconditioned.cpp
+++ b/SimpleTests/SolverTests/ConjugateGradientUnpreconditioned.cpp
@@ -1,18 +1,18 @@
 #include <fstream>
 #include <iostream>
 #include <omp.h>
-#include "CG.h"
-#include "CRSMatrix.h"
+#include "LinAlg/Solvers/CG.h"
+#include "LinAlg/Sparse/CRSMatrix.h"
 #include "sparse.h"
 #include "vector_io.h"
-#include "timeMeasurement.h"
+//#include "timeMeasurement.h"
 
 int main(int argc, char *argv[])
 {
 	// *** reading matrix in crs format from file
 	std::string fname("/work/fischeth/data/testmat.bin");
 //	std::ifstream in(fname.c_str(), std::ios::binary);
-	CRSMatrix<double> *mat (new CRSMatrix<double>(fname, 1));
+	MathLib::CRSMatrix<double> *mat (new MathLib::CRSMatrix<double>(fname));
 /*	double *A(NULL);
 	unsigned *iA(NULL), *jA(NULL), n;
 	if (in) {
@@ -49,13 +49,13 @@ int main(int argc, char *argv[])
 	std::cout << "solving system with CG method ... " << std::flush;
 	time_t start_time, end_time;
 	time(&start_time);
-	double cg_time (cputime(0.0));
+//	double cg_time (cputime(0.0));
 	double eps (1.0e-6);
 	unsigned steps (4000);
 	CG (mat, b, x, eps, steps, 1);
-	cg_time = cputime(cg_time);
+//	cg_time = cputime(cg_time);
 	time(&end_time);
-	std::cout << " in " << steps << " iterations (residuum is " << eps << ") took " << cg_time << " sec time and " << (end_time-start_time) << " sec" << std::endl;
+	std::cout << " in " << steps << " iterations (residuum is " << eps << ") took " << /*cg_time <<*/ " sec time and " << (end_time-start_time) << " sec" << std::endl;
 
 	delete mat;
 	delete [] x;
diff --git a/cmake/FindBLAS.cmake b/cmake/FindBLAS.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..9827984332767385d8131fb9e1f4d1b6b3a0f06e
--- /dev/null
+++ b/cmake/FindBLAS.cmake
@@ -0,0 +1,462 @@
+# - Find BLAS library
+# This module finds an installed fortran library that implements the BLAS
+# linear-algebra interface (see http://www.netlib.org/blas/).
+# The list of libraries searched for is taken
+# from the autoconf macro file, acx_blas.m4 (distributed at
+# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
+#
+# This module sets the following variables:
+#  BLAS_FOUND - set to true if a library implementing the BLAS interface
+#    is found
+#  BLAS_LINKER_FLAGS - uncached list of required linker flags (excluding -l
+#    and -L).
+#  BLAS_LIBRARIES - uncached list of libraries (using full path name) to
+#    link against to use BLAS
+#  BLAS95_LIBRARIES - uncached list of libraries (using full path name)
+#    to link against to use BLAS95 interface
+#  BLAS95_FOUND - set to true if a library implementing the BLAS f95 interface
+#    is found
+#  BLA_STATIC  if set on this determines what kind of linkage we do (static)
+#  BLA_VENDOR  if set checks only the specified vendor, if not set checks
+#     all the possibilities
+#  BLA_F95     if set on tries to find the f95 interfaces for BLAS/LAPACK
+##########
+### List of vendors (BLA_VENDOR) valid in this module
+##  ATLAS, PhiPACK,CXML,DXML,SunPerf,SCSL,SGIMATH,IBMESSL,Intel10_32 (intel mkl v10 32 bit),Intel10_64lp (intel mkl v10 64 bit,lp thread model, lp64 model),
+##  Intel( older versions of mkl 32 and 64 bit), ACML,Apple, NAS, Generic
+# C/CXX should be enabled to use Intel mkl
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distributed this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+get_property(_LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES)
+include(CheckFunctionExists)
+
+macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _threads)
+# This macro checks for the existence of the combination of fortran libraries
+# given by _list.  If the combination is found, this macro checks (using the
+# Check_Fortran_Function_Exists macro) whether can link against that library
+# combination using the name of a routine given by _name using the linker
+# flags given by _flags.  If the combination of libraries is found and passes
+# the link test, LIBRARIES is set to the list of complete library paths that
+# have been found.  Otherwise, LIBRARIES is set to FALSE.
+
+# N.B. _prefix is the prefix applied to the names of all cached variables that
+# are generated internally and marked advanced by this macro.
+
+set(_libraries_work TRUE)
+set(${LIBRARIES})
+set(_combined_name)
+foreach(_library ${_list})
+  set(_combined_name ${_combined_name}_${_library})
+
+  if(_libraries_work)
+   if ( WIN32 )
+    if(BLA_STATIC)
+      set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll")
+    endif(BLA_STATIC)
+    find_library(${_prefix}_${_library}_LIBRARY
+    NAMES ${_library}
+    PATHS ENV LIB
+    )
+   endif ( WIN32 )
+
+   if ( APPLE )
+    if(BLA_STATIC)
+     set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll")
+    endif(BLA_STATIC)
+    find_library(${_prefix}_${_library}_LIBRARY
+    NAMES ${_library}
+    PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH
+    )
+
+   else ( APPLE )
+    if(BLA_STATIC)
+      set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so")
+    endif(BLA_STATIC)
+    find_library(${_prefix}_${_library}_LIBRARY
+    NAMES ${_library}
+    PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH
+    )
+   endif( APPLE )
+    mark_as_advanced(${_prefix}_${_library}_LIBRARY)
+    set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
+    set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+  endif(_libraries_work)
+endforeach(_library ${_list})
+if(_libraries_work)
+  # Test this combination of libraries.
+  set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_threads})
+  #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
+  check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
+  set(CMAKE_REQUIRED_LIBRARIES)
+  mark_as_advanced(${_prefix}${_combined_name}_WORKS)
+  set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
+endif(_libraries_work)
+if(NOT _libraries_work)
+  set(${LIBRARIES} FALSE)
+endif(NOT _libraries_work)
+#message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
+endmacro(Check_Fortran_Libraries)
+
+set(BLAS_LINKER_FLAGS)
+set(BLAS_LIBRARIES)
+set(BLAS95_LIBRARIES)
+if ($ENV{BLA_VENDOR} MATCHES ".+")
+  set(BLA_VENDOR $ENV{BLA_VENDOR})
+else ($ENV{BLA_VENDOR} MATCHES ".+")
+  if(NOT BLA_VENDOR)
+    set(BLA_VENDOR "All")
+  endif(NOT BLA_VENDOR)
+endif ($ENV{BLA_VENDOR} MATCHES ".+")
+
+if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  cblas_dgemm
+  ""
+  "cblas;f77blas;atlas"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
+if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  sgemm
+  ""
+  "sgemm;dgemm;blas"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in Alpha CXML library?
+if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  sgemm
+  ""
+  "cxml"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in Alpha DXML library? (now called CXML, see above)
+if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  sgemm
+  ""
+  "dxml"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in Sun Performance library?
+if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  sgemm
+  "-xlic_lib=sunperf"
+  "sunperf;sunmath"
+  ""
+  )
+  if(BLAS_LIBRARIES)
+    set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
+  endif(BLAS_LIBRARIES)
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in SCSL library?  (SGI/Cray Scientific Library)
+if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  sgemm
+  ""
+  "scsl"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in SGIMATH library?
+if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  sgemm
+  ""
+  "complib.sgimath"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
+
+# BLAS in IBM ESSL library? (requires generic BLAS lib, too)
+if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  sgemm
+  ""
+  "essl;blas"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
+
+#BLAS in acml library?
+if (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  sgemm
+  ""
+  "acml_mp;acml_mv"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "All")
+
+# Apple BLAS library?
+if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  cblas_dgemm
+  ""
+  "Accelerate"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+
+if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+ if ( NOT BLAS_LIBRARIES )
+    check_fortran_libraries(
+    BLAS_LIBRARIES
+    BLAS
+    cblas_dgemm
+    ""
+    "vecLib"
+    ""
+    )
+ endif ( NOT BLAS_LIBRARIES )
+endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+# Generic BLAS library?
+if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+  check_fortran_libraries(
+  BLAS_LIBRARIES
+  BLAS
+  sgemm
+  ""
+  "blas"
+  ""
+  )
+ endif(NOT BLAS_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+
+#BLAS in intel mkl 10 library? (em64t 64bit)
+if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+ if (NOT WIN32)
+	 set(LM "-lm")
+ endif ()
+ if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+  if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
+    find_package(Threads)
+  else(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
+    find_package(Threads REQUIRED)
+  endif(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
+  if (WIN32)
+  if(BLA_F95)
+    if(NOT BLAS95_LIBRARIES)
+    check_fortran_libraries(
+    BLAS95_LIBRARIES
+    BLAS
+    sgemm
+    ""
+    "mkl_blas95;mkl_intel_c;mkl_intel_thread;mkl_core;libguide40"
+    ""
+    )
+    endif(NOT BLAS95_LIBRARIES)
+  else(BLA_F95)
+    if(NOT BLAS_LIBRARIES)
+    check_fortran_libraries(
+    BLAS_LIBRARIES
+    BLAS
+    SGEMM
+    ""
+    "mkl_c_dll;mkl_intel_thread_dll;mkl_core_dll;libguide40"
+    ""
+    )
+    endif(NOT BLAS_LIBRARIES)
+  endif(BLA_F95)
+  else(WIN32)
+  if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+    if(BLA_F95)
+      if(NOT BLAS95_LIBRARIES)
+      check_fortran_libraries(
+      BLAS95_LIBRARIES
+      BLAS
+      sgemm
+      ""
+      "mkl_blas95;mkl_intel;mkl_intel_thread;mkl_core;guide"
+      "${CMAKE_THREAD_LIBS_INIT};${LM}"
+      )
+      endif(NOT BLAS95_LIBRARIES)
+    else(BLA_F95)
+    if(NOT BLAS_LIBRARIES)
+      check_fortran_libraries(
+      BLAS_LIBRARIES
+      BLAS
+      sgemm
+      ""
+      "mkl_intel;mkl_intel_thread;mkl_core;guide"
+      "${CMAKE_THREAD_LIBS_INIT}"
+      "${LM}"
+      )
+      endif(NOT BLAS_LIBRARIES)
+    endif(BLA_F95)
+  endif (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+  if (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
+   if(BLA_F95)
+    if(NOT BLAS95_LIBRARIES)
+      check_fortran_libraries(
+      BLAS95_LIBRARIES
+      BLAS
+      sgemm
+      ""
+      "mkl_blas95;mkl_intel_lp64;mkl_intel_thread;mkl_core;guide"
+      "${CMAKE_THREAD_LIBS_INIT};${LM}"
+      )
+    endif(NOT BLAS95_LIBRARIES)
+   else(BLA_F95)
+     if(NOT BLAS_LIBRARIES)
+      check_fortran_libraries(
+      BLAS_LIBRARIES
+      BLAS
+      sgemm
+      ""
+      "mkl_intel_lp64;mkl_intel_thread;mkl_core;guide"
+      "${CMAKE_THREAD_LIBS_INIT};${LM}"
+      )
+     endif(NOT BLAS_LIBRARIES)
+   endif(BLA_F95)
+  endif (BLA_VENDOR STREQUAL "Intel10_64lp" OR BLA_VENDOR STREQUAL "All")
+  endif (WIN32)
+  #older vesions of intel mkl libs
+  # BLAS in intel mkl library? (shared)
+  if(NOT BLAS_LIBRARIES)
+    check_fortran_libraries(
+    BLAS_LIBRARIES
+    BLAS
+    sgemm
+    ""
+    "mkl;guide"
+    "${CMAKE_THREAD_LIBS_INIT};${LM}"
+    )
+  endif(NOT BLAS_LIBRARIES)
+  #BLAS in intel mkl library? (static, 32bit)
+  if(NOT BLAS_LIBRARIES)
+    check_fortran_libraries(
+    BLAS_LIBRARIES
+    BLAS
+    sgemm
+    ""
+    "mkl_ia32;guide"
+    "${CMAKE_THREAD_LIBS_INIT};${LM}"
+    )
+  endif(NOT BLAS_LIBRARIES)
+  #BLAS in intel mkl library? (static, em64t 64bit)
+  if(NOT BLAS_LIBRARIES)
+    check_fortran_libraries(
+    BLAS_LIBRARIES
+    BLAS
+    sgemm
+    ""
+    "mkl_em64t;guide"
+    "${CMAKE_THREAD_LIBS_INIT};${LM}"
+    )
+  endif(NOT BLAS_LIBRARIES)
+ endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+endif (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+
+
+if(BLA_F95)
+ if(BLAS95_LIBRARIES)
+    set(BLAS95_FOUND TRUE)
+  else(BLAS95_LIBRARIES)
+    set(BLAS95_FOUND FALSE)
+  endif(BLAS95_LIBRARIES)
+
+  if(NOT BLAS_FIND_QUIETLY)
+    if(BLAS95_FOUND)
+      message(STATUS "A library with BLAS95 API found.")
+    else(BLAS95_FOUND)
+      if(BLAS_FIND_REQUIRED)
+        message(FATAL_ERROR
+        "A required library with BLAS95 API not found. Please specify library location.")
+      else(BLAS_FIND_REQUIRED)
+        message(STATUS
+        "A library with BLAS95 API not found. Please specify library location.")
+      endif(BLAS_FIND_REQUIRED)
+    endif(BLAS95_FOUND)
+  endif(NOT BLAS_FIND_QUIETLY)
+  set(BLAS_FOUND TRUE)
+  set(BLAS_LIBRARIES "${BLAS95_LIBRARIES}")
+else(BLA_F95)
+  if(BLAS_LIBRARIES)
+    set(BLAS_FOUND TRUE)
+  else(BLAS_LIBRARIES)
+    set(BLAS_FOUND FALSE)
+  endif(BLAS_LIBRARIES)
+
+  if(NOT BLAS_FIND_QUIETLY)
+    if(BLAS_FOUND)
+      message(STATUS "A library with BLAS API found.")
+    else(BLAS_FOUND)
+      if(BLAS_FIND_REQUIRED)
+        message(FATAL_ERROR
+        "A required library with BLAS API not found. Please specify library location."
+        )
+      else(BLAS_FIND_REQUIRED)
+        message(STATUS
+        "A library with BLAS API not found. Please specify library location."
+        )
+      endif(BLAS_FIND_REQUIRED)
+    endif(BLAS_FOUND)
+  endif(NOT BLAS_FIND_QUIETLY)
+endif(BLA_F95)
diff --git a/cmake/FindLAPACK.cmake b/cmake/FindLAPACK.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..bf45406772253f858fd68b04a933f3da9d2af678
--- /dev/null
+++ b/cmake/FindLAPACK.cmake
@@ -0,0 +1,302 @@
+# - Find LAPACK library
+# This module finds an installed fortran library that implements the LAPACK
+# linear-algebra interface (see http://www.netlib.org/lapack/).
+#
+# The approach follows that taken for the autoconf macro file, acx_lapack.m4
+# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
+#
+# This module sets the following variables:
+#  LAPACK_FOUND - set to true if a library implementing the LAPACK interface
+#    is found
+#  LAPACK_LINKER_FLAGS - uncached list of required linker flags (excluding -l
+#    and -L).
+#  LAPACK_LIBRARIES - uncached list of libraries (using full path name) to
+#    link against to use LAPACK
+#  LAPACK95_LIBRARIES - uncached list of libraries (using full path name) to
+#    link against to use LAPACK95
+#  LAPACK95_FOUND - set to true if a library implementing the LAPACK f95
+#    interface is found
+#  BLA_STATIC  if set on this determines what kind of linkage we do (static)
+#  BLA_VENDOR  if set checks only the specified vendor, if not set checks
+#     all the possibilities
+#  BLA_F95     if set on tries to find the f95 interfaces for BLAS/LAPACK
+### List of vendors (BLA_VENDOR) valid in this module
+##  Intel(mkl), ACML,Apple, NAS, Generic
+
+#=============================================================================
+# Copyright 2007-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+get_property(_LANGUAGES_ GLOBAL PROPERTY ENABLED_LANGUAGES)
+if (NOT _LANGUAGES_ MATCHES Fortran)
+include(CheckFunctionExists)
+else (NOT _LANGUAGES_ MATCHES Fortran)
+include(CheckFortranFunctionExists)
+endif (NOT _LANGUAGES_ MATCHES Fortran)
+
+set(LAPACK_FOUND FALSE)
+set(LAPACK95_FOUND FALSE)
+
+macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas _threads)
+# This macro checks for the existence of the combination of fortran libraries
+# given by _list.  If the combination is found, this macro checks (using the
+# Check_Fortran_Function_Exists macro) whether can link against that library
+# combination using the name of a routine given by _name using the linker
+# flags given by _flags.  If the combination of libraries is found and passes
+# the link test, LIBRARIES is set to the list of complete library paths that
+# have been found.  Otherwise, LIBRARIES is set to FALSE.
+
+# N.B. _prefix is the prefix applied to the names of all cached variables that
+# are generated internally and marked advanced by this macro.
+
+set(_libraries_work TRUE)
+set(${LIBRARIES})
+set(_combined_name)
+foreach(_library ${_list})
+  set(_combined_name ${_combined_name}_${_library})
+
+  if(_libraries_work)
+  IF (WIN32)
+    if(BLA_STATIC)
+      set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib;.dll")
+    endif(BLA_STATIC)
+    find_library(${_prefix}_${_library}_LIBRARY
+    NAMES ${_library}
+    PATHS ENV LIB
+    )
+  ENDIF (WIN32)
+
+  if(APPLE)
+    if(BLA_STATIC)
+      set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so;.dylib")
+    endif(BLA_STATIC)
+    find_library(${_prefix}_${_library}_LIBRARY
+    NAMES ${_library}
+    PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH
+    )
+    else(APPLE)
+    if(BLA_STATIC)
+     set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so")
+    endif(BLA_STATIC)
+    find_library(${_prefix}_${_library}_LIBRARY
+    NAMES ${_library}
+    PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH
+    )
+    endif(APPLE)
+
+    mark_as_advanced(${_prefix}_${_library}_LIBRARY)
+    set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
+    set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+  endif(_libraries_work)
+endforeach(_library ${_list})
+
+if(_libraries_work)
+  # Test this combination of libraries.
+  if(UNIX AND BLA_STATIC)
+    set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group ${${LIBRARIES}} ${_blas};-Wl,--end-group" ${_threads})
+  else(UNIX AND BLA_STATIC)
+    set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads})
+  endif(UNIX AND BLA_STATIC)
+#  message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
+  if (NOT _LANGUAGES_ MATCHES Fortran)
+    check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
+  else (NOT _LANGUAGES_ MATCHES Fortran)
+    check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS)
+  endif (NOT _LANGUAGES_ MATCHES Fortran)
+  set(CMAKE_REQUIRED_LIBRARIES)
+  mark_as_advanced(${_prefix}${_combined_name}_WORKS)
+  set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
+  #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
+endif(_libraries_work)
+
+ if(_libraries_work)
+   set(${LIBRARIES} ${${LIBRARIES}} ${_blas})
+ else(_libraries_work)
+    set(${LIBRARIES} FALSE)
+ endif(_libraries_work)
+
+endmacro(Check_Lapack_Libraries)
+
+
+set(LAPACK_LINKER_FLAGS)
+set(LAPACK_LIBRARIES)
+set(LAPACK95_LIBRARIES)
+
+
+if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+  find_package(BLAS)
+else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+  find_package(BLAS REQUIRED)
+endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+
+
+if(BLAS_FOUND)
+  set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
+  if ($ENV{BLA_VENDOR} MATCHES ".+")
+    set(BLA_VENDOR $ENV{BLA_VENDOR})
+  else ($ENV{BLA_VENDOR} MATCHES ".+")
+    if(NOT BLA_VENDOR)
+      set(BLA_VENDOR "All")
+    endif(NOT BLA_VENDOR)
+  endif ($ENV{BLA_VENDOR} MATCHES ".+")
+#acml lapack
+ if (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "All")
+  if(NOT LAPACK_LIBRARIES)
+   check_lapack_libraries(
+    LAPACK_LIBRARIES
+    LAPACK
+    cheev
+    ""
+    "acml;acml_mv"
+    ""
+    ""
+    )
+  endif(NOT LAPACK_LIBRARIES)
+  if(NOT LAPACK_LIBRARIES)
+   check_lapack_libraries(
+    LAPACK_LIBRARIES
+    LAPACK
+    cheev
+    ""
+    "acml_mp;acml_mv"
+    ""
+    ""
+    )
+  endif(NOT LAPACK_LIBRARIES)
+ endif (BLA_VENDOR STREQUAL "ACML" OR BLA_VENDOR STREQUAL "All")
+
+# Apple LAPACK library?
+if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+  check_lapack_libraries(
+  LAPACK_LIBRARIES
+  LAPACK
+  cheev
+  ""
+  "Accelerate"
+  "${BLAS_LIBRARIES}"
+  ""
+  )
+ endif(NOT LAPACK_LIBRARIES)
+endif (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+  if ( NOT LAPACK_LIBRARIES )
+    check_lapack_libraries(
+    LAPACK_LIBRARIES
+    LAPACK
+    cheev
+    ""
+    "vecLib"
+    "${BLAS_LIBRARIES}"
+    ""
+    )
+  endif ( NOT LAPACK_LIBRARIES )
+endif (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+# Generic LAPACK library?
+if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+  if ( NOT LAPACK_LIBRARIES )
+    check_lapack_libraries(
+    LAPACK_LIBRARIES
+    LAPACK
+    cheev
+    ""
+    "lapack"
+    "${BLAS_LIBRARIES}"
+    ""
+    )
+  endif ( NOT LAPACK_LIBRARIES )
+endif (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+#intel lapack
+ if (BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+  if (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+   if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+      find_PACKAGE(Threads)
+   else(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+       find_package(Threads REQUIRED)
+   endif(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+   if (BLA_F95)
+    if(NOT LAPACK95_LIBRARIES)
+     check_lapack_libraries(
+     LAPACK95_LIBRARIES
+     LAPACK
+     cheev
+     ""
+     "mkl_lapack95"
+     "${BLAS95_LIBRARIES}"
+     "${CMAKE_THREAD_LIBS_INIT}"
+     )
+    endif(NOT LAPACK95_LIBRARIES)
+   else(BLA_F95)
+    if(NOT LAPACK_LIBRARIES)
+     check_lapack_libraries(
+     LAPACK_LIBRARIES
+     LAPACK
+     cheev
+     ""
+     "mkl_lapack"
+     "${BLAS_LIBRARIES}"
+     "${CMAKE_THREAD_LIBS_INIT}"
+     )
+    endif(NOT LAPACK_LIBRARIES)
+   endif(BLA_F95)
+  endif (_LANGUAGES_ MATCHES C OR _LANGUAGES_ MATCHES CXX)
+ endif(BLA_VENDOR MATCHES "Intel*" OR BLA_VENDOR STREQUAL "All")
+else(BLAS_FOUND)
+  message(STATUS "LAPACK requires BLAS")
+endif(BLAS_FOUND)
+
+if(BLA_F95)
+ if(LAPACK95_LIBRARIES)
+  set(LAPACK95_FOUND TRUE)
+ else(LAPACK95_LIBRARIES)
+  set(LAPACK95_FOUND FALSE)
+ endif(LAPACK95_LIBRARIES)
+ if(NOT LAPACK_FIND_QUIETLY)
+  if(LAPACK95_FOUND)
+    message(STATUS "A library with LAPACK95 API found.")
+  else(LAPACK95_FOUND)
+    if(LAPACK_FIND_REQUIRED)
+      message(FATAL_ERROR
+      "A required library with LAPACK95 API not found. Please specify library location."
+      )
+    else(LAPACK_FIND_REQUIRED)
+      message(STATUS
+      "A library with LAPACK95 API not found. Please specify library location."
+      )
+    endif(LAPACK_FIND_REQUIRED)
+  endif(LAPACK95_FOUND)
+ endif(NOT LAPACK_FIND_QUIETLY)
+ set(LAPACK_FOUND "${LAPACK95_FOUND}")
+ set(LAPACK_LIBRARIES "${LAPACK95_LIBRARIES}")
+else(BLA_F95)
+ if(LAPACK_LIBRARIES)
+  set(LAPACK_FOUND TRUE)
+ else(LAPACK_LIBRARIES)
+  set(LAPACK_FOUND FALSE)
+ endif(LAPACK_LIBRARIES)
+
+ if(NOT LAPACK_FIND_QUIETLY)
+  if(LAPACK_FOUND)
+    message(STATUS "A library with LAPACK API found.")
+  else(LAPACK_FOUND)
+    if(LAPACK_FIND_REQUIRED)
+      message(FATAL_ERROR
+      "A required library with LAPACK API not found. Please specify library location."
+      )
+    else(LAPACK_FIND_REQUIRED)
+      message(STATUS
+      "A library with LAPACK API not found. Please specify library location."
+      )
+    endif(LAPACK_FIND_REQUIRED)
+  endif(LAPACK_FOUND)
+ endif(NOT LAPACK_FIND_QUIETLY)
+endif(BLA_F95)