diff --git a/build/BudgetMaster.exe b/build/BudgetMaster.exe
index adad21672f117432ecba5acc5880cd4de2b94f58..1615506ef0305ac54886c178beab441470a73f55 100644
Binary files a/build/BudgetMaster.exe and b/build/BudgetMaster.exe differ
diff --git a/build/BudgetMasterClient.jar b/build/BudgetMasterClient.jar
index 3fd4c2f6cf2308eab6c361001b09d5bb34572977..9bfc74a6eabb8c5f49012f35e1ebb3efb152a04d 100644
Binary files a/build/BudgetMasterClient.jar and b/build/BudgetMasterClient.jar differ
diff --git a/build/BudgetMasterServer.jar b/build/BudgetMasterServer.jar
index 7f2b0defbbc1662462382008db0793389329842a..19f220c3abad7970c1e5e5da95e622ac6799259b 100644
Binary files a/build/BudgetMasterServer.jar and b/build/BudgetMasterServer.jar differ
diff --git a/src/de/deadlocker8/budgetmaster/logic/CategoryInOutSum.java b/src/de/deadlocker8/budgetmaster/logic/CategoryInOutSum.java
new file mode 100644
index 0000000000000000000000000000000000000000..4b49c5b10d088b5b6a51ddf7c14a03d82e918c40
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/CategoryInOutSum.java
@@ -0,0 +1,82 @@
+package de.deadlocker8.budgetmaster.logic;
+
+import javafx.scene.paint.Color;
+
+public class CategoryInOutSum
+{
+	private int ID;
+	private String name;
+	private Color color;
+	private int budgetIN;
+	private int budgetOUT;	
+	
+	public CategoryInOutSum(int ID, String name, Color color, int budgetIN, int budgetOUT)
+	{		
+		this.ID = ID;
+		this.name = name;
+		this.color = color;
+		this.budgetIN = budgetIN;
+		this.budgetOUT = budgetOUT;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+	
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+
+	public Color getColor()
+	{
+		return color;
+	}
+	
+	public void setColor(Color color)
+	{
+		this.color = color;
+	}
+
+	public int getBudgetIN()
+	{
+		return budgetIN;
+	}
+
+	public void setBudgetIN(int budgetIN)
+	{
+		this.budgetIN = budgetIN;
+	}
+
+	public int getBudgetOUT()
+	{
+		return budgetOUT;
+	}
+
+	public void setBudgetOUT(int budgetOUT)
+	{
+		this.budgetOUT = budgetOUT;
+	}
+	
+	@Override
+	public boolean equals(Object obj)
+	{
+		if(this == obj)
+			return true;
+		if(obj == null)
+			return false;
+		if(getClass() != obj.getClass())
+			return false;
+		CategoryInOutSum other = (CategoryInOutSum)obj;
+		if(ID != other.ID)
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString()
+	{
+		return "CategoryInOutSum [ID=" + ID + ", name=" + name + ", color=" + color + ", budgetIN=" + budgetIN + ", budgetOUT=" + budgetOUT + "]";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/ExceptionHandler.java b/src/de/deadlocker8/budgetmaster/logic/ExceptionHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..40aa9bbc3f3b3087a356a9f710e16c893d4fd6a3
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/ExceptionHandler.java
@@ -0,0 +1,40 @@
+package de.deadlocker8.budgetmaster.logic;
+
+public class ExceptionHandler
+{
+	public static String getMessageForException(Exception e)
+	{
+		if(e instanceof ServerConnectionException)
+		{
+			return handleServerConnectionException(e);
+		}			
+		
+		if(e.getMessage() == null)
+		{
+			return "Unbekannter Fehler (" + e.getClass() + ")";
+		}
+				
+		if(e.getMessage().contains("Connection refused"))
+		{
+			return "Server nicht erreichbar.";
+		}
+		else if(e.getMessage().contains("HTTPS hostname wrong"))
+		{
+			return "Der Server verwendet ein selbst signiertes Zertifkat für die Verschlüsselung. "
+					+ "Aus Sicherheitsgründen werden diese Zertifikate standardmäßig blockiert. "
+					+ "Wenn du dem Zertifikat trotzdem vertrauen möchtest, dann füge den Hostnamen des Servers zur Liste der vertrauenswürdigen Hosts in den Einstellungen hinzu.";
+		}
+		return e.getMessage();
+	}
+	
+	private static String handleServerConnectionException(Exception e)
+	{
+		switch(e.getMessage())
+		{
+			case "400": return "Der Server erhielt eine fehlerhafte Anfrage oder ungültige Parameter.";
+			case "401": return "Ungültiges Passwort.";
+			case "500": return "Beim Ausführen der Anfrage ist ein interner Serverfehler ist aufgetreten.";
+			default: return e.getMessage();
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Helpers.java b/src/de/deadlocker8/budgetmaster/logic/Helpers.java
index a3761e796fd6ad0bd0a435ffe141d0d397e9fa34..9190df3577db8a5f28558da7a167bc9e24489ed6 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Helpers.java
+++ b/src/de/deadlocker8/budgetmaster/logic/Helpers.java
@@ -5,11 +5,16 @@ import java.net.URLEncoder;
 import java.text.DecimalFormat;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 
 public class Helpers
 {
 	public static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("0.00");
 	
+	public static final String COLOR_INCOME = "#22BAD9";
+	public static final String COLOR_PAYMENT = "#F2612D";
+	public static final String SALT = "ny9/Y+G|WrJ,82|oIYQQ X %i-sq#4,uA-qKPtwFPnw+s(k2`rV)^-a1|t{D3Z>S";
+
 	public static String getURLEncodedString(String input)
 	{
 		try
@@ -21,7 +26,7 @@ public class Helpers
 			return input;
 		}
 	}
-	
+
 	public static String getDateString(LocalDate date)
 	{
 		if(date == null)
@@ -31,4 +36,32 @@ public class Helpers
 		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 		return date.format(formatter);
 	}
+
+	public static ArrayList<String> getMonthList()
+	{
+		ArrayList<String> monthNames = new ArrayList<>();
+		monthNames.add("Januar");
+		monthNames.add("Februar");
+		monthNames.add("März");
+		monthNames.add("April");
+		monthNames.add("Mai");
+		monthNames.add("Juni");
+		monthNames.add("Juli");
+		monthNames.add("August");
+		monthNames.add("September");
+		monthNames.add("Oktober");
+		monthNames.add("November");
+		monthNames.add("Dezember");
+		return monthNames;
+	}
+
+	public static ArrayList<String> getYearList()
+	{
+		ArrayList<String> years = new ArrayList<>();
+		for(int i = 2000; i < 2100; i++)
+		{
+			years.add(String.valueOf(i));
+		}
+		return years;
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/MonthInOutSum.java b/src/de/deadlocker8/budgetmaster/logic/MonthInOutSum.java
new file mode 100644
index 0000000000000000000000000000000000000000..edc3d0f572bd1d87283f6d5dbcb0d56581e53fca
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/MonthInOutSum.java
@@ -0,0 +1,67 @@
+package de.deadlocker8.budgetmaster.logic;
+
+import java.util.ArrayList;
+
+import org.joda.time.DateTime;
+
+public class MonthInOutSum
+{
+	private int month;
+	private int year;
+	private ArrayList<CategoryInOutSum> sums;
+	
+	public MonthInOutSum(int month, int year, ArrayList<CategoryInOutSum> sums)
+	{
+		this.month = month;
+		this.year = year;
+		this.sums = sums;
+	}
+
+	public int getMonth()
+	{
+		return month;
+	}
+
+	public int getYear()
+	{
+		return year;
+	}
+
+	public ArrayList<CategoryInOutSum> getSums()
+	{
+		return sums;
+	}
+	
+	public DateTime getDate()
+	{
+		return DateTime.now().withYear(year).withMonthOfYear(month).withDayOfMonth(1);
+	}
+	
+	public int getBudgetIN()
+	{
+		int budget = 0;
+		for(CategoryInOutSum currentCategorySum : sums)
+		{
+			budget += currentCategorySum.getBudgetIN();
+		}
+			
+		return budget;
+	}
+	
+	public int getBudgetOUT()
+	{
+		int budget = 0;
+		for(CategoryInOutSum currentCategorySum : sums)
+		{
+			budget += currentCategorySum.getBudgetOUT();
+		}
+			
+		return budget;
+	}
+
+	@Override
+	public String toString()
+	{
+		return "MonthInOutSum [month=" + month + ", year=" + year + ", sums=" + sums + "]";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java b/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java
index b6a04d740c68c6fb6e90fed593d980613061aa22..8443d3fe84ee30432e7aa18f0aef4b840e1e7cd6 100644
--- a/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java
+++ b/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java
@@ -3,6 +3,7 @@ package de.deadlocker8.budgetmaster.logic;
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.PrintWriter;
 import java.lang.reflect.Type;
 import java.net.URL;
 import java.security.cert.X509Certificate;
@@ -13,9 +14,12 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 
+import org.joda.time.DateTime;
+
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 
+import de.deadlocker8.budgetmasterserver.logic.Database;
 import tools.ConvertTo;
 import tools.Read;
 
@@ -49,7 +53,9 @@ public class ServerConnection
 		SSLContext sc = SSLContext.getInstance("SSL");
 		sc.init(null, trustAllCerts, new java.security.SecureRandom());
 		HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
-		HttpsURLConnection.setDefaultHostnameVerifier((hostname, sslSession) -> hostname.equals("localhost"));
+
+		// check whitelist
+		HttpsURLConnection.setDefaultHostnameVerifier((hostname, sslSession) -> settings.getTrustedHosts().contains(hostname));
 	}
 
 	/*
@@ -73,10 +79,10 @@ public class ServerConnection
 		}
 		else
 		{
-			return null;
+			return new ArrayList<>();
 		}
 	}
-	
+
 	public Category getCategory(int ID) throws Exception
 	{
 		URL url = new URL(settings.getUrl() + "/category/single?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + ID);
@@ -101,9 +107,16 @@ public class ServerConnection
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setRequestMethod("POST");
 		httpsCon.setDoInput(true);
-		InputStream stream = httpsCon.getInputStream();
-		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-		reader.close();
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}		
 	}
 
 	public void updateCategory(Category category) throws Exception
@@ -112,9 +125,16 @@ public class ServerConnection
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setRequestMethod("PUT");
 		httpsCon.setDoInput(true);
-		InputStream stream = httpsCon.getInputStream();
-		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-		reader.close();
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}	
 	}
 
 	public void deleteCategory(int ID) throws Exception
@@ -123,11 +143,18 @@ public class ServerConnection
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setRequestMethod("DELETE");
 		httpsCon.setDoInput(true);
-		InputStream stream = httpsCon.getInputStream();
-		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-		reader.close();
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}
 	}
-	
+
 	/*
 	 * Payment
 	 */
@@ -137,7 +164,7 @@ public class ServerConnection
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setDoOutput(true);
 		httpsCon.setRequestMethod("GET");
-
+			
 		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
 		{
 			String result = Read.getStringFromInputStream(httpsCon.getInputStream());
@@ -149,7 +176,7 @@ public class ServerConnection
 		}
 		else
 		{
-			return null;
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
 		}
 	}
 
@@ -171,10 +198,10 @@ public class ServerConnection
 		}
 		else
 		{
-			return null;
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
 		}
 	}
-	
+
 	public RepeatingPayment getRepeatingPayment(int ID) throws Exception
 	{
 		URL url = new URL(settings.getUrl() + "/repeatingpayment/single?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + ID);
@@ -184,46 +211,51 @@ public class ServerConnection
 
 		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
 		{
-			String result = Read.getStringFromInputStream(httpsCon.getInputStream());		
+			String result = Read.getStringFromInputStream(httpsCon.getInputStream());
 			return gson.fromJson(result, RepeatingPayment.class);
 		}
 		else
 		{
-			return null;
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
 		}
 	}
 
 	public void addNormalPayment(NormalPayment payment) throws Exception
 	{
-		URL url = new URL(settings.getUrl() + "/payment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + 
-				"&amount=" + payment.getAmount() + 
-				"&date=" + payment.getDate() + 
-				"&categoryID=" + payment.getCategoryID() + 
-				"&name=" + Helpers.getURLEncodedString(payment.getName()) + 
-				"&description=" + Helpers.getURLEncodedString(payment.getDescription()));
+		URL url = new URL(settings.getUrl() + "/payment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&amount=" + payment.getAmount() + "&date=" + payment.getDate() + "&categoryID=" + payment.getCategoryID() + "&name=" + Helpers.getURLEncodedString(payment.getName())
+				+ "&description=" + Helpers.getURLEncodedString(payment.getDescription()));
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setRequestMethod("POST");
 		httpsCon.setDoInput(true);
-		InputStream stream = httpsCon.getInputStream();
-		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-		reader.close();
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}
 	}
 
 	public void updateNormalPayment(NormalPayment payment) throws Exception
 	{
-		 URL url = new URL(settings.getUrl() + "/payment?secret=" + settings.getSecret() + 
-				 "&id=" + payment.getID() + 
-				 "&amount=" + payment.getAmount() + 
-				 "&date=" + payment.getDate() +
-				 "&categoryID=" + payment.getCategoryID() + 
-				 "&name=" + Helpers.getURLEncodedString(payment.getName()) +
-				 "&description=" + Helpers.getURLEncodedString(payment.getDescription()));
-		 HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
-		 httpsCon.setRequestMethod("PUT");
-		 httpsCon.setDoInput(true);
-		 InputStream stream = httpsCon.getInputStream();
-		 BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-		 reader.close();
+		URL url = new URL(settings.getUrl() + "/payment?secret=" + settings.getSecret() + "&id=" + payment.getID() + "&amount=" + payment.getAmount() + "&date=" + payment.getDate() + "&categoryID=" + payment.getCategoryID() + "&name=" + Helpers.getURLEncodedString(payment.getName())
+				+ "&description=" + Helpers.getURLEncodedString(payment.getDescription()));
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setRequestMethod("PUT");
+		httpsCon.setDoInput(true);
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}
 	}
 
 	public void addRepeatingPayment(RepeatingPayment payment) throws Exception
@@ -235,21 +267,21 @@ public class ServerConnection
 			repeatEndDate = "A";
 		}
 
-		URL url = new URL(settings.getUrl() + "/repeatingpayment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + 
-				"&amount=" + payment.getAmount() + 
-				"&date=" + payment.getDate() + 
-				"&categoryID=" + payment.getCategoryID() + 
-				"&name=" + Helpers.getURLEncodedString(payment.getName()) + 
-				"&repeatInterval=" + payment.getRepeatInterval() +
-				"&repeatEndDate=" + repeatEndDate + 
-				"&repeatMonthDay=" + payment.getRepeatMonthDay() +
-				"&description=" + Helpers.getURLEncodedString(payment.getDescription()));				
+		URL url = new URL(settings.getUrl() + "/repeatingpayment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&amount=" + payment.getAmount() + "&date=" + payment.getDate() + "&categoryID=" + payment.getCategoryID() + "&name=" + Helpers.getURLEncodedString(payment.getName())
+				+ "&repeatInterval=" + payment.getRepeatInterval() + "&repeatEndDate=" + repeatEndDate + "&repeatMonthDay=" + payment.getRepeatMonthDay() + "&description=" + Helpers.getURLEncodedString(payment.getDescription()));
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setRequestMethod("POST");
 		httpsCon.setDoInput(true);
-		InputStream stream = httpsCon.getInputStream();
-		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-		reader.close();
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}
 	}
 
 	public void deleteNormalPayment(NormalPayment payment) throws Exception
@@ -258,22 +290,36 @@ public class ServerConnection
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setRequestMethod("DELETE");
 		httpsCon.setDoInput(true);
-		InputStream stream = httpsCon.getInputStream();
-		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-		reader.close();
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}
 	}
-	
+
 	public void deleteRepeatingPayment(RepeatingPaymentEntry payment) throws Exception
 	{
 		URL url = new URL(settings.getUrl() + "/repeatingpayment?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + "&id=" + payment.getRepeatingPaymentID());
 		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
 		httpsCon.setRequestMethod("DELETE");
 		httpsCon.setDoInput(true);
-		InputStream stream = httpsCon.getInputStream();
-		BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
-		reader.close();
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}
 	}
-	
+
 	/*
 	 * CATEGORYBUDGET
 	 */
@@ -295,10 +341,10 @@ public class ServerConnection
 		}
 		else
 		{
-			return null;
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
 		}
 	}
-	
+
 	/*
 	 * REST
 	 */
@@ -311,12 +357,129 @@ public class ServerConnection
 
 		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
 		{
-			String result = Read.getStringFromInputStream(httpsCon.getInputStream());		
+			String result = Read.getStringFromInputStream(httpsCon.getInputStream());
 			return gson.fromJson(result, Integer.class);
 		}
 		else
 		{
-			return 0;
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}
+	}
+
+	/*
+	 * DATABASE
+	 */
+	public void deleteDatabase() throws Exception
+	{
+		URL url = new URL(settings.getUrl() + "/database?secret=" + Helpers.getURLEncodedString(settings.getSecret()));
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setRequestMethod("DELETE");
+		httpsCon.setDoInput(true);
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}		
+	}
+
+	public String exportDatabase() throws Exception
+	{
+		URL url = new URL(settings.getUrl() + "/database?secret=" + Helpers.getURLEncodedString(settings.getSecret()));
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setDoOutput(true);
+		httpsCon.setRequestMethod("GET");
+
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			return Read.getStringFromInputStream(httpsCon.getInputStream());
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}
+	}
+
+	public void importDatabase(Database database) throws Exception
+	{
+		String databaseJSON = new Gson().toJson(database);
+		
+		URL url = new URL(settings.getUrl() + "/database?secret=" + Helpers.getURLEncodedString(settings.getSecret()));
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setRequestMethod("POST");
+		httpsCon.setRequestProperty("Content-Type", "application/json");
+		httpsCon.setRequestProperty("Accept", "application/json");		
+		httpsCon.setDoInput(true);
+		httpsCon.setDoOutput(true);
+		PrintWriter writer = new PrintWriter(httpsCon.getOutputStream());
+		writer.write(databaseJSON);
+		writer.flush();
+		writer.close();
+		
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			InputStream stream = httpsCon.getInputStream();
+			BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+			reader.close();
+		}
+		else
+		{
+			throw new ServerConnectionException(String.valueOf(httpsCon.getResponseCode()));
+		}
+	}
+	
+	/*
+	 * CHARTS
+	 */
+	public ArrayList<CategoryInOutSum> getCategoryInOutSumForMonth(DateTime startDate, DateTime endDate) throws Exception
+	{
+		URL url = new URL(settings.getUrl() + "/charts/categoryInOutSum?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + 
+				"&startDate=" + startDate.toString("yyyy-MM-dd") + 
+				"&endDate=" + endDate.toString("yyyy-MM-dd"));
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setDoOutput(true);
+		httpsCon.setRequestMethod("GET");
+
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			String result = Read.getStringFromInputStream(httpsCon.getInputStream());
+			// required by GSON
+			Type listType = new TypeToken<ArrayList<CategoryInOutSum>>()
+			{
+			}.getType();
+			return gson.fromJson(result, listType);
+		}
+		else
+		{
+			return null;
+		}
+	}
+	
+	public ArrayList<MonthInOutSum> getMonthInOutSum(DateTime startDate, DateTime endDate) throws Exception
+	{
+		URL url = new URL(settings.getUrl() + "/charts/monthInOutSum?secret=" + Helpers.getURLEncodedString(settings.getSecret()) + 
+				"&startDate=" + startDate.toString("yyyy-MM-dd") + 
+				"&endDate=" + endDate.toString("yyyy-MM-dd"));	
+		HttpsURLConnection httpsCon = (HttpsURLConnection)url.openConnection();
+		httpsCon.setDoOutput(true);
+		httpsCon.setRequestMethod("GET");
+
+		if(httpsCon.getResponseCode() == HttpsURLConnection.HTTP_OK)
+		{
+			String result = Read.getStringFromInputStream(httpsCon.getInputStream());
+			// required by GSON
+			Type listType = new TypeToken<ArrayList<MonthInOutSum>>()
+			{
+			}.getType();
+			return gson.fromJson(result, listType);
+		}
+		else
+		{
+			return null;
 		}
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/ServerConnectionException.java b/src/de/deadlocker8/budgetmaster/logic/ServerConnectionException.java
new file mode 100644
index 0000000000000000000000000000000000000000..c18a1663b3a6774129233997db6a08d99535f9e4
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/ServerConnectionException.java
@@ -0,0 +1,31 @@
+package de.deadlocker8.budgetmaster.logic;
+
+public class ServerConnectionException extends Exception
+{
+	private static final long serialVersionUID = 2784475774757068549L;
+
+	public ServerConnectionException()
+	{
+		super();	
+	}
+
+	public ServerConnectionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace)
+	{
+		super(message, cause, enableSuppression, writableStackTrace);		
+	}
+
+	public ServerConnectionException(String message, Throwable cause)
+	{
+		super(message, cause);
+	}
+
+	public ServerConnectionException(String message)
+	{
+		super(message);
+	}
+
+	public ServerConnectionException(Throwable cause)
+	{
+		super(cause);
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Settings.java b/src/de/deadlocker8/budgetmaster/logic/Settings.java
index 84a6b6ff524b6d19e94dcaf081e953e7ff75ab4e..f95ce96203ee507679c9ffb83ebc92efee79183a 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Settings.java
+++ b/src/de/deadlocker8/budgetmaster/logic/Settings.java
@@ -1,11 +1,14 @@
 package de.deadlocker8.budgetmaster.logic;
 
+import java.util.ArrayList;
+
 public class Settings
 {
 	private String url;
 	private String secret;
 	private String currency;
 	private boolean restActivated;
+	private ArrayList<String> trustedHosts;
 	
 	public Settings()
 	{
@@ -51,10 +54,20 @@ public class Settings
 	{
 		this.restActivated = restActivated;
 	}
+	
+	public ArrayList<String> getTrustedHosts()
+	{
+		return trustedHosts;
+	}
+
+	public void setTrustedHosts(ArrayList<String> trustedHosts)
+	{
+		this.trustedHosts = trustedHosts;
+	}
 
 	@Override
 	public String toString()
 	{
-		return "Settings [url=" + url + ", secret=" + secret + ", currency=" + currency + ", restActivated=" + restActivated + "]";
+		return "Settings [url=" + url + ", secret=" + secret + ", currency=" + currency + ", restActivated=" + restActivated + ", trustedHosts=" + trustedHosts + "]";
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Utils.java b/src/de/deadlocker8/budgetmaster/logic/Utils.java
index 55789dca5c6081740ca9e6a6fb2d427eda140c45..c9af40da56e4e6360256674d42ee8d139343969e 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Utils.java
+++ b/src/de/deadlocker8/budgetmaster/logic/Utils.java
@@ -12,6 +12,7 @@ import java.util.ResourceBundle;
 
 import com.google.gson.Gson;
 
+import de.deadlocker8.budgetmasterserver.logic.Database;
 import tools.PathUtils;
 
 public class Utils
@@ -23,8 +24,7 @@ public class Utils
 		Settings settings;
 		try
 		{
-			Gson gson = new Gson();
-			PathUtils.checkFolder(new File(PathUtils.getOSindependentPath() + bundle.getString("folder")));
+			Gson gson = new Gson();			
 			Reader reader = Files.newBufferedReader(Paths.get(PathUtils.getOSindependentPath() + bundle.getString("folder") + "/settings.json"), Charset.forName("UTF-8"));
 			settings = gson.fromJson(reader, Settings.class);	
 			reader.close();
@@ -40,9 +40,25 @@ public class Utils
 	{		
 		Gson gson = new Gson();
 		String jsonString = gson.toJson(settings);
-		
+		PathUtils.checkFolder(new File(PathUtils.getOSindependentPath() + bundle.getString("folder")));
 		Writer writer = Files.newBufferedWriter(Paths.get(PathUtils.getOSindependentPath() + bundle.getString("folder")  + "/settings.json"), Charset.forName("UTF-8"));
 		writer.write(jsonString);
 		writer.close();
 	}
+	
+	public static Database loadDatabaseJSON(File file) throws IOException
+	{	
+		Gson gson = new Gson();
+		Reader reader = Files.newBufferedReader(Paths.get(file.getAbsolutePath()), Charset.forName("UTF-8"));		
+		Database database = gson.fromJson(reader, Database.class);	
+		reader.close();
+		return database;		
+	}
+	
+	public static void saveDatabaseJSON(File file, String databaseJSON) throws IOException
+	{		
+		Writer writer = Files.newBufferedWriter(Paths.get(file.getAbsolutePath()), Charset.forName("UTF-8"));
+		writer.write(databaseJSON);
+		writer.close();
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/BarChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/BarChartGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..c3276887a3f8d70f7770ac4acf9f0b54c1e0fcb3
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/BarChartGenerator.java
@@ -0,0 +1,129 @@
+package de.deadlocker8.budgetmaster.logic.chartGenerators;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Set;
+
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
+import javafx.event.EventHandler;
+import javafx.geometry.Point2D;
+import javafx.scene.Node;
+import javafx.scene.chart.BarChart;
+import javafx.scene.chart.CategoryAxis;
+import javafx.scene.chart.NumberAxis;
+import javafx.scene.chart.XYChart;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tooltip;
+import javafx.scene.input.MouseEvent;
+
+@Deprecated
+public class BarChartGenerator
+{
+	private ArrayList<MonthInOutSum> monthInOutSums;
+	private String currency;
+
+	public BarChartGenerator(ArrayList<MonthInOutSum> monthInOutSums, String currency)
+	{
+		this.monthInOutSums = monthInOutSums;
+		this.currency = currency;
+	}
+
+	public BarChart<String, Number> generate()
+	{
+		final CategoryAxis xAxis = new CategoryAxis();
+		final NumberAxis yAxis = new NumberAxis();
+		final BarChart<String, Number> generatedChart = new BarChart<>(xAxis, yAxis);
+		generatedChart.setTitle(null);
+
+		xAxis.setLabel("");
+		yAxis.setLabel("Summe in " + currency);
+
+		XYChart.Series<String, Number> seriesIN = new XYChart.Series<String, Number>();
+		seriesIN.setName("Einnahmen");
+		XYChart.Series<String, Number> seriesOUT = new XYChart.Series<String, Number>();
+		seriesOUT.setName("Ausgaben");
+
+		for(MonthInOutSum currentItem : monthInOutSums)
+		{
+			String label = currentItem.getDate().toString("MMMM YY");
+
+			seriesIN.getData().add(new XYChart.Data<String, Number>(label, currentItem.getBudgetIN()/100.0));
+			seriesOUT.getData().add(new XYChart.Data<String, Number>(label, currentItem.getBudgetOUT()/100.0));
+		}
+
+		generatedChart.getData().add(seriesIN);
+		generatedChart.getData().add(seriesOUT);
+
+		generatedChart.setLegendVisible(true);
+		
+		// add tooltip to every segment
+		generatedChart.getData().stream().forEach(tool -> {
+			for(XYChart.Data<String, Number> data : tool.getData())
+			{
+				Tooltip tooltip = new Tooltip();
+
+				tooltip.setText(Helpers.NUMBER_FORMAT.format(data.getYValue()).replace(".", ",") + currency);
+				Tooltip.install(tool.getNode(), tooltip);
+				Node node = data.getNode();
+				node.setOnMouseEntered(new EventHandler<MouseEvent>()
+				{
+					@Override
+					public void handle(MouseEvent event)
+					{
+						Point2D p = node.localToScreen(event.getX() + 5, event.getY() + 7);
+						tooltip.show(node, p.getX(), p.getY());
+					}
+				});
+				node.setOnMouseExited(new EventHandler<MouseEvent>()
+				{
+
+					@Override
+					public void handle(MouseEvent event)
+					{
+						tooltip.hide();
+					}
+				});
+			}
+		});
+		
+		// style bar for incomes
+		for(Node n : generatedChart.lookupAll(".default-color0.chart-bar"))
+		{
+			n.setStyle("-fx-bar-fill: " + Helpers.COLOR_INCOME + ";");
+		}		
+		
+		// style bar for payments
+		for(Node n : generatedChart.lookupAll(".default-color1.chart-bar"))
+		{
+			n.setStyle("-fx-bar-fill: " + Helpers.COLOR_PAYMENT + ";");
+		}
+		
+		 //style legend item according to color
+		Set<Node> nodes = generatedChart.lookupAll(".chart-legend-item");
+		if(nodes.size() > 0)
+		{        	
+			Iterator<Node> iterator = nodes.iterator();
+			int counter = 0;
+			while(iterator.hasNext())
+			{
+    			Node node = iterator.next();	        			
+    			if(node instanceof Label)
+    			{
+    				Label labelLegendItem = (Label)node;     
+    				if(counter == 0)
+    				{
+    					labelLegendItem.getGraphic().setStyle("-fx-background-color: " + Helpers.COLOR_INCOME + ";");
+    				}
+    				else
+    				{
+    					labelLegendItem.getGraphic().setStyle("-fx-background-color: " + Helpers.COLOR_PAYMENT + ";");
+    				}
+    			}
+    			counter++;
+			}
+		}
+
+		return generatedChart;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChartGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..77efcd715afaed985db53c936ea3e37041b3d6fc
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChartGenerator.java
@@ -0,0 +1,154 @@
+package de.deadlocker8.budgetmaster.logic.chartGenerators;
+
+import java.util.ArrayList;
+
+import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tooltip;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import tools.ConvertTo;
+
+public class CategoriesChartGenerator
+{
+	private String title;
+	private ArrayList<CategoryInOutSum> categoryInOutSums;
+	private boolean useBudgetIN;
+	private String currency;
+	private double total;
+
+	public CategoriesChartGenerator(String title, ArrayList<CategoryInOutSum> categoryInOutSums, boolean useBudgetIN, String currency)
+	{
+		this.title = title;
+		if(categoryInOutSums == null)
+		{
+			this.categoryInOutSums = new ArrayList<>();
+		}
+		else
+		{
+			this.categoryInOutSums = categoryInOutSums;
+		}		
+		this.useBudgetIN = useBudgetIN;
+		this.currency = currency;
+		this.total = getTotal(this.categoryInOutSums, useBudgetIN);
+	}	
+
+	public VBox generate()
+	{
+		VBox generatedChart = new VBox();
+		HBox chart = new HBox();
+		chart.setMinHeight(30);
+
+		Label labelTitle = new Label(title);
+		labelTitle.setStyle("-fx-font-size: 16; -fx-font-weight: bold;");
+		generatedChart.getChildren().add(labelTitle);
+		VBox.setMargin(labelTitle, new Insets(0, 0, 10, 0));
+
+		for(CategoryInOutSum currentItem : categoryInOutSums)
+		{
+			Label currentPart = new Label();
+			currentPart.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(currentItem.getColor()));
+			currentPart.prefHeightProperty().bind(chart.heightProperty());
+			chart.getChildren().add(currentPart);
+
+			double value;
+			if(useBudgetIN)
+			{
+				value = currentItem.getBudgetIN() / 100.0;
+			}
+			else
+			{
+				value = -currentItem.getBudgetOUT() / 100.0;
+			}
+
+			double percentage = value / total;
+
+			currentPart.prefWidthProperty().bind(chart.widthProperty().multiply(percentage));
+
+			Tooltip tooltip = new Tooltip();
+			tooltip.setText(currentItem.getName() + "\n" + Helpers.NUMBER_FORMAT.format(percentage*100) + " %\n" + Helpers.NUMBER_FORMAT.format(value).replace(".", ",") + currency);//
+			currentPart.setTooltip(tooltip);
+		}
+
+		generatedChart.getChildren().add(chart);
+
+		return generatedChart;
+	}
+
+	public GridPane generateLegend()
+	{
+		GridPane legend = new GridPane();
+		legend.setPadding(new Insets(10));
+		legend.setHgap(20);
+		legend.setVgap(10);
+		legend.setAlignment(Pos.CENTER);
+		legend.setStyle("-fx-background-color: #EEEEEE; -fx-border-color: #212121; -fx-border-width: 1; -fx-border-radius: 5;");
+
+		if(categoryInOutSums.size() == 0)
+		{
+			return legend;
+		}	
+		
+		ArrayList<HBox> legendItems = new ArrayList<>();
+		for(CategoryInOutSum currentItem : categoryInOutSums)
+		{
+			String label = currentItem.getName();
+			if(label.equals("NONE"))
+			{
+				label = "Keine Kategorie";
+			}
+			legendItems.add(getLegendItem(label, currentItem.getColor()));
+		}
+
+		int legendWidth = (int)Math.ceil(Math.sqrt(legendItems.size()));
+		
+		for(int i = 0; i < legendItems.size(); i++)
+		{
+			int columnIndex = i % legendWidth;
+			int rowIndex = i / 4;
+			legend.add(legendItems.get(i), columnIndex, rowIndex);
+		}
+
+		return legend;
+	}
+
+	private HBox getLegendItem(String name, Color color)
+	{
+		HBox legendItem = new HBox();
+		Label labelCircle = new Label();
+		labelCircle.setMinWidth(20);
+		labelCircle.setMinHeight(20);
+		labelCircle.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(color) + "; -fx-background-radius: 50%; -fx-border-width: 1; -fx-border-color: black - fx-border-radius: 50%");
+
+		Label labelText = new Label(name);
+		labelText.setStyle("-fx-font-weight: bold;");
+
+		legendItem.getChildren().add(labelCircle);
+		legendItem.getChildren().add(labelText);
+		HBox.setMargin(labelText, new Insets(0, 0, 0, 5));
+
+		return legendItem;
+	}
+
+	private double getTotal(ArrayList<CategoryInOutSum> categoryInOutSums, boolean useBudgetIN)
+	{		
+		double total = 0;
+		for(CategoryInOutSum currentItem : categoryInOutSums)
+		{
+			if(useBudgetIN)
+			{
+				total += currentItem.getBudgetIN() / 100.0;
+			}
+			else
+			{
+				total += -currentItem.getBudgetOUT() / 100.0;
+			}
+		}
+		return total;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/LineChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/LineChartGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..8888a5bd140f83f962677215f344645f5326de5f
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/LineChartGenerator.java
@@ -0,0 +1,139 @@
+package de.deadlocker8.budgetmaster.logic.chartGenerators;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Set;
+
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
+import javafx.event.EventHandler;
+import javafx.geometry.Point2D;
+import javafx.scene.Node;
+import javafx.scene.chart.CategoryAxis;
+import javafx.scene.chart.LineChart;
+import javafx.scene.chart.NumberAxis;
+import javafx.scene.chart.XYChart;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tooltip;
+import javafx.scene.input.MouseEvent;
+
+public class LineChartGenerator
+{
+	private ArrayList<MonthInOutSum> monthInOutSums;
+	private String currency;
+
+	public LineChartGenerator(ArrayList<MonthInOutSum> monthInOutSums, String currency)
+	{
+		this.monthInOutSums = monthInOutSums;
+		this.currency = currency;
+	}
+
+	public LineChart<String, Number> generate()
+	{
+		final CategoryAxis xAxis = new CategoryAxis();
+		final NumberAxis yAxis = new NumberAxis();
+		final LineChart<String, Number> generatedChart = new LineChart<>(xAxis, yAxis);
+		generatedChart.setTitle(null);
+
+		xAxis.setLabel("");
+		yAxis.setLabel("Summe in " + currency);
+
+		XYChart.Series<String, Number> seriesIN = new XYChart.Series<String, Number>();
+		seriesIN.setName("Einnahmen");
+		XYChart.Series<String, Number> seriesOUT = new XYChart.Series<String, Number>();
+		seriesOUT.setName("Ausgaben");
+
+		for(MonthInOutSum currentItem : monthInOutSums)
+		{
+			String label = currentItem.getDate().toString("MMMM YY");
+
+			seriesIN.getData().add(new XYChart.Data<String, Number>(label, currentItem.getBudgetIN() / 100.0));
+			seriesOUT.getData().add(new XYChart.Data<String, Number>(label, -currentItem.getBudgetOUT() / 100.0));
+		}
+
+		generatedChart.getData().add(seriesIN);
+		generatedChart.getData().add(seriesOUT);
+
+		generatedChart.setLegendVisible(true);
+
+		// add tooltip to every segment
+		generatedChart.getData().stream().forEach(tool -> {
+			for(XYChart.Data<String, Number> data : tool.getData())
+			{
+				Tooltip tooltip = new Tooltip();
+
+				tooltip.setText(Helpers.NUMBER_FORMAT.format(data.getYValue()).replace(".", ",") + currency);
+				Tooltip.install(tool.getNode(), tooltip);
+				Node node = data.getNode();
+				node.setOnMouseEntered(new EventHandler<MouseEvent>()
+				{
+					@Override
+					public void handle(MouseEvent event)
+					{
+						Point2D p = node.localToScreen(event.getX() + 5, event.getY() + 7);
+						tooltip.show(node, p.getX(), p.getY());
+					}
+				});
+				node.setOnMouseExited(new EventHandler<MouseEvent>()
+				{
+					@Override
+					public void handle(MouseEvent event)
+					{
+						tooltip.hide();
+					}
+				});
+			}
+		});
+
+		// style line for incomes
+		for(Node n : generatedChart.lookupAll(".default-color0.chart-series-line"))
+		{
+			n.setStyle("-fx-stroke: " + Helpers.COLOR_INCOME + ";");
+		}
+		
+		// style line dots for incomes
+		for(Node n : generatedChart.lookupAll(".default-color0.chart-line-symbol"))
+		{
+			n.setStyle("-fx-background-color: " + Helpers.COLOR_INCOME + ", white;");
+		}
+
+		// style line for payments
+		for(Node n : generatedChart.lookupAll(".default-color1.chart-series-line"))
+		{
+			n.setStyle("-fx-stroke: " + Helpers.COLOR_PAYMENT + ";");
+		}
+		
+		// style line dots for payments
+		for(Node n : generatedChart.lookupAll(".default-color1.chart-line-symbol"))
+		{
+			n.setStyle("-fx-background-color: " + Helpers.COLOR_PAYMENT + ", white;");
+		}
+
+		// style legend item according to color
+		Set<Node> nodes = generatedChart.lookupAll(".chart-legend-item");
+		if(nodes.size() > 0)
+		{
+			Iterator<Node> iterator = nodes.iterator();
+			int counter = 0;
+			while(iterator.hasNext())
+			{
+				Node node = iterator.next();
+				if(node instanceof Label)
+				{
+					Label labelLegendItem = (Label)node;
+					if(counter == 0)
+					{
+						labelLegendItem.getGraphic().setStyle("-fx-background-color: " + Helpers.COLOR_INCOME + ";");
+					}
+					else
+					{
+						labelLegendItem.getGraphic().setStyle("-fx-background-color: " + Helpers.COLOR_PAYMENT + ";");
+					}
+				}
+				counter++;
+			}
+		}
+
+		return generatedChart;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/MonthChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/MonthChartGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..35ae4150cb591b96c5bab30029a588107b5f55d3
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/MonthChartGenerator.java
@@ -0,0 +1,212 @@
+package de.deadlocker8.budgetmaster.logic.chartGenerators;
+
+import java.util.ArrayList;
+
+import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
+import javafx.geometry.Insets;
+import javafx.geometry.Orientation;
+import javafx.geometry.Pos;
+import javafx.scene.control.Label;
+import javafx.scene.control.Separator;
+import javafx.scene.control.Tooltip;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.text.TextAlignment;
+import tools.ConvertTo;
+
+public class MonthChartGenerator
+{
+	private ArrayList<MonthInOutSum> monthInOutSums;
+	private String currency;
+
+	public MonthChartGenerator(ArrayList<MonthInOutSum> monthInOutSums, String currency)
+	{
+		if(monthInOutSums == null)
+		{
+			this.monthInOutSums = new ArrayList<>();
+		}
+		else
+		{
+			this.monthInOutSums = monthInOutSums;
+		}
+		this.currency = currency;
+	}
+
+	public HBox generate()
+	{
+		HBox generatedChart = new HBox();
+		generatedChart.setAlignment(Pos.TOP_CENTER);
+		generatedChart.setSpacing(25);
+
+		double total = getMaximum(monthInOutSums);
+			
+		for(MonthInOutSum currentMonthSum : monthInOutSums)
+		{
+			VBox chartPart = new VBox();
+			chartPart.setAlignment(Pos.TOP_CENTER);		
+
+			HBox hboxChart = new HBox();
+			hboxChart.setAlignment(Pos.BOTTOM_CENTER);
+			hboxChart.setSpacing(10);
+			VBox chartIncome = generateChart(currentMonthSum.getSums(), total, true);
+			hboxChart.getChildren().add(chartIncome);
+			HBox.setHgrow(chartIncome, Priority.ALWAYS);
+			VBox chartPayment = generateChart(currentMonthSum.getSums(), total, false);
+			hboxChart.getChildren().add(chartPayment);
+			HBox.setHgrow(chartPayment, Priority.ALWAYS);
+
+			chartPart.getChildren().add(hboxChart);
+			VBox.setVgrow(hboxChart, Priority.ALWAYS);
+
+			Label labelTitle = new Label(currentMonthSum.getDate().toString("MMMM \nYY"));
+			labelTitle.setStyle("-fx-font-size: 12;");
+			labelTitle.setTextAlignment(TextAlignment.CENTER);
+			chartPart.getChildren().add(labelTitle);
+			VBox.setMargin(labelTitle, new Insets(10, 0, 0, 0));
+
+			generatedChart.getChildren().add(chartPart);			
+			generatedChart.getChildren().add(new Separator(Orientation.VERTICAL));
+		}
+
+		return generatedChart;
+	}
+
+	private VBox generateChart(ArrayList<CategoryInOutSum> categoryInOutSums, double total, boolean useBudgetIN)
+	{
+		VBox result = new VBox();									
+		Label labelAmount = new Label(Helpers.NUMBER_FORMAT.format(getTotal(categoryInOutSums, useBudgetIN)).replace(".", ",") + currency);
+		labelAmount.setStyle("-fx-font-size: 12; -fx-font-weight: bold;");
+		result.getChildren().add(labelAmount);
+		VBox.setMargin(labelAmount, new Insets(0, 0, 10, 0));
+
+		VBox chart = new VBox();
+		chart.setAlignment(Pos.BOTTOM_CENTER);
+		
+		for(CategoryInOutSum currentItem : categoryInOutSums)
+		{
+			Label currentPart = new Label();
+			currentPart.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(currentItem.getColor()));
+			currentPart.prefWidthProperty().bind(chart.widthProperty());
+			chart.getChildren().add(currentPart);
+
+			double value;
+			if(useBudgetIN)
+			{
+				value = currentItem.getBudgetIN() / 100.0;
+			}
+			else
+			{
+				value = -currentItem.getBudgetOUT() / 100.0;
+			}
+
+			double percentage = value / total;	
+			
+			currentPart.setMinHeight(0);
+			currentPart.prefHeightProperty().bind(chart.heightProperty().multiply(percentage));	
+
+			Tooltip tooltip = new Tooltip();
+			tooltip.setText(currentItem.getName() + "\n"+ Helpers.NUMBER_FORMAT.format(percentage * 100) + " %\n" + Helpers.NUMBER_FORMAT.format(value).replace(".", ",") + currency);//
+			currentPart.setTooltip(tooltip);
+		}
+
+		result.getChildren().add(chart);
+		VBox.setVgrow(chart, Priority.ALWAYS);
+
+		return result;
+	}
+
+	public GridPane generateLegend()
+	{
+		GridPane legend = new GridPane();
+		legend.setPadding(new Insets(10));
+		legend.setHgap(20);
+		legend.setVgap(10);
+		legend.setAlignment(Pos.CENTER);
+		legend.setStyle("-fx-background-color: #EEEEEE; -fx-border-color: #212121; -fx-border-width: 1; -fx-border-radius: 5;");
+		
+		if(monthInOutSums.size() == 0)
+		{
+			return legend;
+		}		
+		
+		ArrayList<HBox> legendItems = new ArrayList<>();
+		for(CategoryInOutSum currentItem : monthInOutSums.get(0).getSums())
+		{
+			String label = currentItem.getName();
+			if(label.equals("NONE"))
+			{
+				label = "Keine Kategorie";
+			}
+			legendItems.add(getLegendItem(label, currentItem.getColor()));
+		}
+
+		int legendWidth = (int)Math.ceil(Math.sqrt(legendItems.size()));		
+
+		for(int i = 0; i < legendItems.size(); i++)
+		{
+			int columnIndex = i % legendWidth;
+			int rowIndex = i / 4;
+			legend.add(legendItems.get(i), columnIndex, rowIndex);
+		}
+
+		return legend;
+	}
+
+	private HBox getLegendItem(String name, Color color)
+	{
+		HBox legendItem = new HBox();
+		Label labelCircle = new Label();
+		labelCircle.setMinWidth(20);
+		labelCircle.setMinHeight(20);
+		labelCircle.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(color) + "; -fx-background-radius: 50%; -fx-border-width: 1; -fx-border-color: black - fx-border-radius: 50%");
+
+		Label labelText = new Label(name);
+		labelText.setStyle("-fx-font-weight: bold;");
+
+		legendItem.getChildren().add(labelCircle);
+		legendItem.getChildren().add(labelText);
+		HBox.setMargin(labelText, new Insets(0, 0, 0, 5));
+
+		return legendItem;
+	}
+
+	private double getTotal(ArrayList<CategoryInOutSum> categoryInOutSums, boolean useBudgetIN)
+	{
+		double total = 0;
+		for(CategoryInOutSum currentItem : categoryInOutSums)
+		{
+			if(useBudgetIN)
+			{
+				total += currentItem.getBudgetIN() / 100.0;
+			}
+			else
+			{
+				total += -currentItem.getBudgetOUT() / 100.0;
+			}
+		}
+		return total;
+	}
+
+	private double getMaximum(ArrayList<MonthInOutSum> monthInOutSums)
+	{		
+		double maximum = 0;
+		for(MonthInOutSum currentItem : monthInOutSums)
+		{
+			if(currentItem.getBudgetIN() > maximum)
+			{
+				maximum = currentItem.getBudgetIN();
+			}
+
+			if(Math.abs(currentItem.getBudgetOUT()) > maximum)
+			{
+				maximum = Math.abs(currentItem.getBudgetOUT());
+			}
+		}
+		return maximum / 100.0;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/PieChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/PieChartGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..382d0a77dfede19bc254cfa0f3f40387c2af5c5f
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/PieChartGenerator.java
@@ -0,0 +1,125 @@
+package de.deadlocker8.budgetmaster.logic.chartGenerators;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Set;
+
+import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.event.EventHandler;
+import javafx.geometry.Point2D;
+import javafx.scene.Node;
+import javafx.scene.chart.PieChart;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tooltip;
+import javafx.scene.input.MouseEvent;
+import tools.ConvertTo;
+
+@Deprecated
+public class PieChartGenerator
+{
+    private String title;
+    private ArrayList<CategoryInOutSum> categoryInOutSums;
+    private boolean useBudgetIN;
+    private String currency;
+
+    public PieChartGenerator(String title, ArrayList<CategoryInOutSum> categoryInOutSums, boolean useBudgetIN, String currency)
+    {
+        this.title = title;
+        this.categoryInOutSums = categoryInOutSums;
+        this.useBudgetIN = useBudgetIN;
+        this.currency = currency;
+    }
+  
+    public PieChart generate()
+    {
+        ArrayList<PieChart.Data> data = new ArrayList<>();
+        
+        for(CategoryInOutSum currentItem : categoryInOutSums)
+        {        	
+        	String label = currentItem.getName(); 
+        	if(label.equals("NONE"))
+        	{
+        		label = "Keine Kategorie";
+        	}
+        	
+        	if(useBudgetIN)
+        	{
+        		data.add(new PieChart.Data(label, currentItem.getBudgetIN()/100.0));
+        	}
+        	else
+        	{
+        		data.add(new PieChart.Data(label, -currentItem.getBudgetOUT()/100.0));
+        	}
+        }
+        
+        ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(data);
+
+        final PieChart chart = new PieChart(pieChartData);
+        chart.setTitle(title);
+
+        //add tooltip to every segment that shows percentage as double value
+        chart.getData().stream().forEach(tool ->
+        {
+            Tooltip tooltip = new Tooltip();
+
+            double total = 0;
+            for(int i = 0; i < chart.getData().size(); i++)
+            {
+            	PieChart.Data currentData = chart.getData().get(i);
+                total += currentData.getPieValue();
+                String currentColor = ConvertTo.toRGBHexWithoutOpacity(categoryInOutSums.get(i).getColor());
+                currentData.getNode().setStyle("-fx-pie-color: " + currentColor + ";");
+            }    
+            
+            //style legend item according to color
+    		Set<Node> nodes = chart.lookupAll(".chart-legend-item");
+    		if(nodes.size() > 0)
+    		{        	
+    			Iterator<Node> iterator = nodes.iterator();
+    			int counter = 0;
+    			while(iterator.hasNext())
+    			{
+        			Node node = iterator.next();	        			
+        			if(node instanceof Label)
+        			{
+        				Label labelLegendItem = (Label)node;        				
+        				labelLegendItem.getGraphic().setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(categoryInOutSums.get(counter).getColor()) + ";");
+        			}
+        			counter++;
+    			}
+    		}
+
+            double pieValue = tool.getPieValue();
+            double percentage = (pieValue / total) * 100;
+            String percent = String.valueOf(percentage);
+            percent = percent.substring(0, percent.indexOf(".") + 2);
+
+            tooltip.setText(percent + " %\n" + Helpers.NUMBER_FORMAT.format(pieValue).replace(".", ",") + currency);
+            Tooltip.install(tool.getNode(), tooltip);
+            Node node = tool.getNode();
+            node.setOnMouseEntered(new EventHandler<MouseEvent>()
+            {
+                @Override
+                public void handle(MouseEvent event)
+                {
+                    Point2D p = node.localToScreen(event.getX() + 5, event.getY() + 7);
+                    tooltip.show(node, p.getX(), p.getY());
+                }
+            });
+            node.setOnMouseExited(new EventHandler<MouseEvent>()
+            {
+
+                @Override
+                public void handle(MouseEvent event)
+                {
+                    tooltip.hide();
+                }
+            });
+        });
+
+        return chart;
+    }
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/main/Main.java b/src/de/deadlocker8/budgetmaster/main/Main.java
index de459fc7283f353dffd55a22b23e6ef6b476d50c..a2a24cf7e5355bfad397ae5afdc5b0ef628d1023 100644
--- a/src/de/deadlocker8/budgetmaster/main/Main.java
+++ b/src/de/deadlocker8/budgetmaster/main/Main.java
@@ -1,7 +1,6 @@
 package de.deadlocker8.budgetmaster.main;
 
 import java.io.File;
-import java.util.Arrays;
 import java.util.Locale;
 import java.util.ResourceBundle;
 
@@ -12,14 +11,14 @@ import javafx.scene.Parent;
 import javafx.scene.Scene;
 import javafx.scene.image.Image;
 import javafx.stage.Stage;
-import logger.LogLevel;
+import logger.FileOutputMode;
 import logger.Logger;
 import tools.PathUtils;
 
 public class Main extends Application
 {
 	public static ResourceBundle bundle = ResourceBundle.getBundle("de/deadlocker8/budgetmaster/main/", Locale.GERMANY);
-	
+
 	@Override
 	public void start(Stage stage)
 	{
@@ -28,13 +27,13 @@ public class Main extends Application
 			FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("de/deadlocker8/budgetmaster/ui/GUI.fxml"));
 			Parent root = (Parent)loader.load();
 
-			Scene scene = new Scene(root, 600, 650);			
+			Scene scene = new Scene(root, 650, 650);	
 
 			((Controller)loader.getController()).init(stage);
 
 			stage.setResizable(true);
-			stage.setMinHeight(600);
-			stage.setMinWidth(600);
+			stage.setMinHeight(650);
+			stage.setMinWidth(610);
 			stage.getIcons().add(new Image("/de/deadlocker8/budgetmaster/resources/icon.png"));
 			stage.setTitle(bundle.getString("app.name"));
 			stage.setScene(scene);
@@ -47,25 +46,22 @@ public class Main extends Application
 		}
 	}
 
-	public static void main(String[] args)
+	@Override
+	public void init() throws Exception
 	{
-		if(Arrays.asList(args).contains("debug"))
-		{
-			Logger.setLevel(LogLevel.ALL);
-			Logger.info("Running in Debug Mode");
-		}
-		else
-		{
-			Logger.setLevel(LogLevel.ERROR);			
-		}
+		Parameters params = getParameters();
+		String logLevelParam = params.getNamed().get("loglevel");
+		Logger.setLevel(logLevelParam);
 		
-		PathUtils.checkFolder(new File(PathUtils.getOSindependentPath() + bundle.getString("folder")));
-		File logFile = new File(PathUtils.getOSindependentPath() + bundle.getString("folder") + "/error.log");				
-		Logger.enableFileOutput(logFile);
-	
+		File logFolder = new File(PathUtils.getOSindependentPath() + bundle.getString("folder"));
+		PathUtils.checkFolder(logFolder);
+		Logger.enableFileOutput(logFolder, System.out, System.err, FileOutputMode.COMBINED);
+
 		Logger.appInfo(bundle.getString("app.name"), bundle.getString("version.name"), bundle.getString("version.code"), bundle.getString("version.date"));
-		
+	}
+
+	public static void main(String[] args)
+	{
 		launch(args);
 	}
-	
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/main/_de.properties b/src/de/deadlocker8/budgetmaster/main/_de.properties
index 4e7b83ceadac1175fddd4a734c5008a4c550d4d2..888ab9545116e080a8d428638a00977aa0605ebd 100644
--- a/src/de/deadlocker8/budgetmaster/main/_de.properties
+++ b/src/de/deadlocker8/budgetmaster/main/_de.properties
@@ -1,7 +1,7 @@
 app.name=BudgetMaster
-version.code=2
-version.name=1.1.0
-version.date=12.04.17
+version.code=3
+version.name=1.2.0
+version.date=25.05.17
 author=Robert Goldmann
 
 folder=Deadlocker/BudgetMaster
diff --git a/src/de/deadlocker8/budgetmaster/ui/CategoryController.java b/src/de/deadlocker8/budgetmaster/ui/CategoryController.java
index 0cdb686ec6f8cef2adb986699347810bbe9e468c..8a86686a8d5455a544882ddc0253e741c337d537 100644
--- a/src/de/deadlocker8/budgetmaster/ui/CategoryController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/CategoryController.java
@@ -5,6 +5,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 
 import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
 import de.deadlocker8.budgetmaster.logic.ServerConnection;
 import de.deadlocker8.budgetmaster.ui.cells.CategoryCell;
 import fontAwesome.FontIcon;
@@ -161,8 +162,8 @@ public class CategoryController implements Refreshable
 		}
 		catch(Exception e)
 		{
-			e.printStackTrace();
-			controller.showConnectionErrorAlert();
+			Logger.error(e);
+			controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
 		}
 	}
 	
diff --git a/src/de/deadlocker8/budgetmaster/ui/ChartController.java b/src/de/deadlocker8/budgetmaster/ui/ChartController.java
index 30931aa6ffecb297d4b9702206f16b8a18de25e3..6f9e336ddcd7a7a27f4a9e367f14103874b7e9b8 100644
--- a/src/de/deadlocker8/budgetmaster/ui/ChartController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/ChartController.java
@@ -1,11 +1,61 @@
 package de.deadlocker8.budgetmaster.ui;
 
+import java.time.LocalDate;
+import java.util.ArrayList;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+
+import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
+import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
+import de.deadlocker8.budgetmaster.logic.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.chartGenerators.CategoriesChartGenerator;
+import de.deadlocker8.budgetmaster.logic.chartGenerators.LineChartGenerator;
+import de.deadlocker8.budgetmaster.logic.chartGenerators.MonthChartGenerator;
+import fontAwesome.FontIcon;
+import fontAwesome.FontIconType;
+import javafx.collections.FXCollections;
 import javafx.fxml.FXML;
+import javafx.geometry.Insets;
+import javafx.scene.chart.LineChart;
+import javafx.scene.control.Accordion;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.DateCell;
+import javafx.scene.control.DatePicker;
+import javafx.scene.control.RadioButton;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.ScrollPane.ScrollBarPolicy;
+import javafx.scene.control.ToggleGroup;
 import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.util.Callback;
+import logger.Logger;
+import tools.AlertGenerator;
 
 public class ChartController implements Refreshable
 {
 	@FXML private AnchorPane anchorPaneMain;
+	@FXML private Accordion accordion;
+	@FXML private DatePicker datePickerStart;
+	@FXML private VBox vboxChartCategories;
+	@FXML private DatePicker datePickerEnd;
+	@FXML private VBox vboxChartMonth;
+	@FXML private Button buttonChartCategoriesShow;
+	@FXML private ComboBox<String> comboBoxStartMonth;
+	@FXML private ComboBox<String> comboBoxStartYear;
+	@FXML private ComboBox<String> comboBoxEndMonth;
+	@FXML private ComboBox<String> comboBoxEndYear;
+	@FXML private Button buttonChartMonthShow;
+	@FXML private RadioButton radioButtonBars;
+	@FXML private RadioButton radioButtonLines;
 
 	private Controller controller;
 
@@ -14,12 +64,165 @@ public class ChartController implements Refreshable
 		this.controller = controller;
 
 		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
+		vboxChartCategories.setStyle("-fx-background-color: #F4F4F4;");
+		vboxChartCategories.setSpacing(20);
+		vboxChartMonth.setStyle("-fx-background-color: #F4F4F4;");
+		FontIcon iconShow = new FontIcon(FontIconType.CHECK);
+		iconShow.setSize(16);
+		iconShow.setColor(Color.WHITE);
+		buttonChartCategoriesShow.setStyle("-fx-background-color: #2E79B9;");
+		buttonChartCategoriesShow.setGraphic(iconShow);
+		
+		FontIcon iconShow2 = new FontIcon(FontIconType.CHECK);
+		iconShow2.setSize(16);
+		iconShow2.setColor(Color.WHITE);
+		buttonChartMonthShow.setStyle("-fx-background-color: #2E79B9;");
+		buttonChartMonthShow.setGraphic(iconShow2);		
+		
+		datePickerEnd.setDayCellFactory(new Callback<DatePicker, DateCell>()
+		{
+			@Override
+			public DateCell call(DatePicker param)
+			{
+				return new DateCell()
+				{
+					@Override
+					public void updateItem(LocalDate item, boolean empty)
+					{
+						super.updateItem(item, empty);
+						if(item.isBefore(datePickerStart.getValue().plusDays(1)))
+						{
+							setDisable(true);
+							setStyle("-fx-background-color: #ffc0cb;");
+						}
+					}
+				};
+			}
+		});
+
+		comboBoxStartMonth.setItems(FXCollections.observableArrayList(Helpers.getMonthList()));
+		comboBoxStartMonth.setValue(controller.getCurrentDate().minusMonths(5).toString("MMMM"));
+		
+		comboBoxStartYear.setItems(FXCollections.observableArrayList(Helpers.getYearList()));
+		comboBoxStartYear.setValue(String.valueOf(controller.getCurrentDate().minusMonths(5).getYear()));
+		
+		comboBoxEndMonth.setItems(FXCollections.observableArrayList(Helpers.getMonthList()));
+		comboBoxEndMonth.setValue(controller.getCurrentDate().plusMonths(6).toString("MMMM"));
+		
+		comboBoxEndYear.setItems(FXCollections.observableArrayList(Helpers.getYearList()));
+		comboBoxEndYear.setValue(String.valueOf(controller.getCurrentDate().plusMonths(6).getYear()));
+
+		final ToggleGroup toggleGroup = new ToggleGroup();
+		radioButtonBars.setToggleGroup(toggleGroup);
+		radioButtonBars.setSelected(true);
+		radioButtonLines.setToggleGroup(toggleGroup);
+		
+		accordion.setExpandedPane(accordion.getPanes().get(0));
+		vboxChartMonth.setSpacing(15);
+	}
+
+	public void chartCategoriesShow()
+	{
+		DateTime startDate = DateTime.parse(datePickerStart.getValue().toString());
+		DateTime endDate = DateTime.parse(datePickerEnd.getValue().toString());
+
+		try
+		{
+			ServerConnection connection = new ServerConnection(controller.getSettings());
+			ArrayList<CategoryInOutSum> sums = connection.getCategoryInOutSumForMonth(startDate, endDate);
+
+			vboxChartCategories.getChildren().clear();
+			
+			CategoriesChartGenerator generator = new CategoriesChartGenerator("Einnahmen nach Kategorien", sums, true, controller.getSettings().getCurrency());			
+			vboxChartCategories.getChildren().add(generator.generate());
+			generator = new CategoriesChartGenerator("Ausgaben nach Kategorien", sums, false, controller.getSettings().getCurrency());
+			vboxChartCategories.getChildren().add(generator.generate());
+			
+			Region spacer = new Region();
+			vboxChartCategories.getChildren().add(spacer);
+			VBox.setVgrow(spacer, Priority.ALWAYS);
+			
+			vboxChartCategories.getChildren().add(generator.generateLegend());
+		}
+		catch(Exception e)
+		{
+			Logger.error(e);
+			controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
+		}
+	}
+
+	public void chartMonthShow()
+	{
+		vboxChartMonth.getChildren().clear();
+		
+		String startMonth = comboBoxStartMonth.getValue();
+		String startYear = comboBoxStartYear.getValue();
+		String endMonth = comboBoxEndMonth.getValue();
+		String endYear = comboBoxEndYear.getValue();		
+		
+		String startDateString = "01-" + startMonth + "-" + startYear;		
+		DateTime startDate = DateTime.parse(startDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY"));
+		
+		String endDateString = "01-" + endMonth + "-" + endYear;		
+		DateTime endDate = DateTime.parse(endDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY"));	
+			
+		if(endDate.isBefore(startDate))
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Enddatum darf nicht vor dem Startdatum liegen.", controller.getIcon(), controller.getStage(), null, false);
+			return;
+		}
+		
+		try
+		{			
+			ServerConnection connection = new ServerConnection(controller.getSettings());
+			ArrayList<MonthInOutSum> sums = connection.getMonthInOutSum(startDate, endDate);
+		
+			vboxChartMonth.getChildren().clear();
+			
+			if(radioButtonBars.isSelected())
+			{
+				ScrollPane scrollPane = new ScrollPane();				
+				scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);
+				scrollPane.setFocusTraversable(false);
+				scrollPane.setStyle("-fx-background-color: transparent; -fx-background-insets: 0; -fx-border-color: transparent; -fx-border-width: 0; -fx-border-insets: 0;");
+				scrollPane.setPadding(new Insets(0, 0, 10, 0));
+				
+				MonthChartGenerator generator = new MonthChartGenerator(sums, controller.getSettings().getCurrency());
+				HBox generatedChart = generator.generate();
+				scrollPane.setContent(generatedChart);				
+				generatedChart.prefHeightProperty().bind(scrollPane.heightProperty().subtract(30));
+				vboxChartMonth.getChildren().add(scrollPane);
+				VBox.setVgrow(scrollPane, Priority.ALWAYS);
+				vboxChartMonth.getChildren().add(generator.generateLegend());
+			}
+			else
+			{				
+				LineChartGenerator generator = new LineChartGenerator(sums, controller.getSettings().getCurrency());
+				LineChart<String, Number> chartMonth = generator.generate();
+				vboxChartMonth.getChildren().add(chartMonth);	
+				VBox.setVgrow(chartMonth, Priority.ALWAYS);
+			}
+		}
+		catch(Exception e)
+		{
+			Logger.error(e);
+			controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
+		}
 	}
 
 	@Override
 	public void refresh()
 	{
-		//TODO Auto-generated method stub
-		
+		// chart categories
+		LocalDate startDate = LocalDate.parse(controller.getCurrentDate().withDayOfMonth(1).toString("yyyy-MM-dd"));
+		LocalDate endDate = LocalDate.parse(controller.getCurrentDate().dayOfMonth().withMaximumValue().toString("yyy-MM-dd"));
+
+		datePickerStart.setValue(startDate);
+		datePickerEnd.setValue(endDate);
+
+		chartCategoriesShow();
+
+		// chart month
+		chartMonthShow();
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/ChartTab.fxml b/src/de/deadlocker8/budgetmaster/ui/ChartTab.fxml
index e4461f90a25c86b4af4d245e8fd3e8d015bb083f..7ffa60128c56a3f29617e506560b0eef6f6963ad 100644
--- a/src/de/deadlocker8/budgetmaster/ui/ChartTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/ChartTab.fxml
@@ -1,10 +1,141 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Accordion?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.ComboBox?>
+<?import javafx.scene.control.DatePicker?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.RadioButton?>
+<?import javafx.scene.control.TitledPane?>
 <?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.layout.HBox?>
 <?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Font?>
 
 <AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.ChartController">
    <children>
-      <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0" />
+      <Accordion fx:id="accordion" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0">
+        <panes>
+          <TitledPane animated="false" text="Einnahmen/Ausgaben nach Kategorien">
+               <content>
+                  <VBox spacing="20.0">
+                     <children>
+                        <HBox alignment="CENTER" prefHeight="8.0" prefWidth="750.0">
+                           <children>
+                              <HBox alignment="CENTER_RIGHT" spacing="10.0" HBox.hgrow="ALWAYS">
+                                 <children>
+                                    <Label text="Von:">
+                                       <font>
+                                          <Font name="System Bold" size="16.0" />
+                                       </font>
+                                    </Label>
+                                    <DatePicker fx:id="datePickerStart" />
+                                 </children>
+                                 <HBox.margin>
+                                    <Insets right="15.0" />
+                                 </HBox.margin>
+                              </HBox>
+                              <HBox alignment="CENTER_LEFT" spacing="10.0" HBox.hgrow="ALWAYS">
+                                 <children>
+                                    <Label text="Bis:">
+                                       <font>
+                                          <Font name="System Bold" size="16.0" />
+                                       </font>
+                                    </Label>
+                                    <DatePicker fx:id="datePickerEnd" />
+                                    <Button fx:id="buttonChartCategoriesShow" mnemonicParsing="false" onAction="#chartCategoriesShow">
+                                       <font>
+                                          <Font name="System Bold" size="12.0" />
+                                       </font>
+                                       <HBox.margin>
+                                          <Insets left="15.0" />
+                                       </HBox.margin>
+                                    </Button>
+                                 </children>
+                                 <HBox.margin>
+                                    <Insets left="15.0" />
+                                 </HBox.margin>
+                              </HBox>
+                           </children>
+                        </HBox>
+                        <VBox fx:id="vboxChartCategories" VBox.vgrow="ALWAYS">
+                           <VBox.margin>
+                              <Insets />
+                           </VBox.margin>
+                           <padding>
+                              <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
+                           </padding></VBox>
+                     </children>
+                  </VBox>
+               </content>
+               <font>
+                  <Font name="System Bold" size="12.0" />
+               </font>
+          </TitledPane>
+          <TitledPane animated="false" text="Einnahmen/Ausgaben pro Monat">
+               <font>
+                  <Font name="System Bold" size="12.0" />
+               </font>
+               <content>
+                  <VBox spacing="20.0">
+                     <children>
+                        <HBox alignment="CENTER_LEFT" prefHeight="8.0" prefWidth="750.0" spacing="50.0">
+                           <children>
+                              <VBox spacing="15.0">
+                                 <children>
+                                    <HBox alignment="CENTER_RIGHT" spacing="10.0">
+                                       <children>
+                                          <Label prefHeight="25.0" prefWidth="45.0" text="Von:">
+                                             <font>
+                                                <Font name="System Bold" size="16.0" />
+                                             </font>
+                                          </Label>
+                                          <ComboBox fx:id="comboBoxStartMonth" prefHeight="25.0" prefWidth="110.0" />
+                                          <ComboBox fx:id="comboBoxStartYear" prefWidth="70.0" />
+                                       </children>
+                                    </HBox>
+                                    <HBox alignment="CENTER_LEFT" spacing="10.0">
+                                       <children>
+                                          <Label prefWidth="45.0" text="Bis:">
+                                             <font>
+                                                <Font name="System Bold" size="16.0" />
+                                             </font>
+                                          </Label>
+                                          <ComboBox fx:id="comboBoxEndMonth" prefWidth="110.0" />
+                                          <ComboBox fx:id="comboBoxEndYear" prefWidth="70.0" />
+                                       </children>
+                                    </HBox>
+                                 </children>
+                              </VBox>
+                              <HBox alignment="CENTER_LEFT" spacing="15.0" HBox.hgrow="ALWAYS">
+                                 <children>
+                                    <RadioButton fx:id="radioButtonBars" mnemonicParsing="false" text="Balken">
+                                       <font>
+                                          <Font size="14.0" />
+                                       </font></RadioButton>
+                                    <RadioButton fx:id="radioButtonLines" mnemonicParsing="false" text="Linien">
+                                       <font>
+                                          <Font size="14.0" />
+                                       </font></RadioButton>
+                                    <Button fx:id="buttonChartMonthShow" mnemonicParsing="false" onAction="#chartMonthShow">
+                                       <font>
+                                          <Font name="System Bold" size="12.0" />
+                                       </font>
+                                       <HBox.margin>
+                                          <Insets left="10.0" />
+                                       </HBox.margin>
+                                    </Button>
+                                 </children>
+                              </HBox>
+                           </children>
+                        </HBox>
+                        <VBox fx:id="vboxChartMonth" prefHeight="200.0" prefWidth="100.0" VBox.vgrow="ALWAYS" />
+                     </children>
+                  </VBox>
+               </content>
+          </TitledPane>
+        </panes>
+      </Accordion>
    </children>
 </AnchorPane>
diff --git a/src/de/deadlocker8/budgetmaster/ui/Controller.java b/src/de/deadlocker8/budgetmaster/ui/Controller.java
index 0c7c7cbf73a750e58bcba1ea941896bd5f470cc6..408d23943441fc9ab15b41c4f58e3cae847b9362 100644
--- a/src/de/deadlocker8/budgetmaster/ui/Controller.java
+++ b/src/de/deadlocker8/budgetmaster/ui/Controller.java
@@ -9,6 +9,7 @@ import org.joda.time.DateTime;
 
 import de.deadlocker8.budgetmaster.logic.CategoryBudget;
 import de.deadlocker8.budgetmaster.logic.CategoryHandler;
+import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
 import de.deadlocker8.budgetmaster.logic.FilterSettings;
 import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.PaymentHandler;
@@ -104,9 +105,7 @@ public class Controller
 			Parent nodeTabChart = (Parent)fxmlLoader.load();
 			chartController = fxmlLoader.getController();
 			chartController.init(this);
-			tabCharts.setContent(nodeTabChart);
-			//TODO
-			tabCharts.setDisable(true);
+			tabCharts.setContent(nodeTabChart);			
 
 			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml"));
 			Parent nodeTabSettings = (Parent)fxmlLoader.load();
@@ -144,6 +143,7 @@ public class Controller
 		{			
 			Platform.runLater(() -> {
 				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gibt zuerst deine Serverdaten ein!", icon, stage, null, false);
+				toggleAllTabsExceptSettings(true);
 				tabPane.getSelectionModel().select(tabSettings);
 			});
 		}
@@ -228,23 +228,34 @@ public class Controller
 		return currentDate;
 	}
 
-	public void showConnectionErrorAlert()
-	{
+	public void showConnectionErrorAlert(String errorMessage)
+	{		
 		if(!alertIsShowing)
 		{
+			alertIsShowing = true;
 			Platform.runLater(() -> {
+				toggleAllTabsExceptSettings(true);
+				tabPane.getSelectionModel().select(tabSettings);	
+				
 				alertIsShowing = true;
 				Alert alert = new Alert(AlertType.ERROR);
 				alert.setTitle("Fehler");
 				alert.setHeaderText("");
-				alert.setContentText("Beim Herstellen der Verbindung zum Server ist ein Fehler aufgetreten. Bitte überprüfe deine Einstellungen und ob der Server läuft.");
+				if(errorMessage == null)
+				{
+					alert.setContentText("Beim Herstellen der Verbindung zum Server ist ein Fehler aufgetreten. Bitte überprüfe deine Einstellungen.");
+				}
+				else
+				{
+					alert.setContentText("Beim Herstellen der Verbindung zum Server ist ein Fehler aufgetreten. Bitte überprüfe deine Einstellungen.\n\n"
+							+ "Fehlerdetails:\n" + errorMessage);
+				}
+				
 				Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow();
 				dialogStage.getIcons().add(icon);
 				dialogStage.initOwner(stage);
-				dialogStage.setOnCloseRequest((event) -> {
-					alertIsShowing = false;
-				});
 				alert.showAndWait();
+				alertIsShowing = false;
 			});
 		}
 	}
@@ -281,6 +292,14 @@ public class Controller
 	{
 		this.filterSettings = filterSettings;
 	}
+	
+	public void toggleAllTabsExceptSettings(boolean disable)
+	{
+		tabHome.setDisable(disable);
+		tabPayments.setDisable(disable);
+		tabCategories.setDisable(disable);
+		tabCharts.setDisable(disable);	
+	}
 
 	public void about()
 	{
@@ -291,7 +310,7 @@ public class Controller
 	{
 		try
 		{
-			ServerConnection connection = new ServerConnection(settings);			
+			ServerConnection connection = new ServerConnection(settings);
 			
 			paymentHandler = new PaymentHandler();
 			paymentHandler.getPayments().addAll(connection.getPayments(currentDate.getYear(), currentDate.getMonthOfYear()));
@@ -308,12 +327,14 @@ public class Controller
 			
 			categoryBudgets = connection.getCategoryBudgets(currentDate.getYear(), currentDate.getMonthOfYear());	
 			paymentHandler.filter(newFilterSettings);
+			
+			toggleAllTabsExceptSettings(false);
 		}
 		catch(Exception e)
 		{
 			Logger.error(e);
-			categoryHandler = new CategoryHandler(null);			
-			showConnectionErrorAlert();
+			categoryHandler = new CategoryHandler(null);	
+			showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
 		}
 
 		refreshAllTabs();		
diff --git a/src/de/deadlocker8/budgetmaster/ui/HomeController.java b/src/de/deadlocker8/budgetmaster/ui/HomeController.java
index ab2bb352069d6ad6a76237b90cd55989d57e64f4..a17c5d1effb508eaa3c5b2fafacf6e9ca34024ed 100644
--- a/src/de/deadlocker8/budgetmaster/ui/HomeController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/HomeController.java
@@ -77,7 +77,12 @@ public class HomeController implements Refreshable
 		{
 			Budget budget = new Budget(controller.getPaymentHandler().getPayments());	
 			double remaining = budget.getIncomeSum() + budget.getPaymentSum();
-			labelBudget.setText(String.valueOf(Helpers.NUMBER_FORMAT.format(remaining).replace(".", ",")) + " " + controller.getSettings().getCurrency());
+			String currency = "€";
+			if(controller.getSettings() != null)
+			{
+				currency = controller.getSettings().getCurrency();
+			}
+			labelBudget.setText(String.valueOf(Helpers.NUMBER_FORMAT.format(remaining).replace(".", ",")) + " " + currency);
 			if(remaining <= 0)
 			{
 				labelBudget.setStyle("-fx-text-fill: #CC0000");
@@ -86,7 +91,7 @@ public class HomeController implements Refreshable
 			{
 				labelBudget.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
 			}
-			labelStartBudget.setText("von " + String.valueOf(Helpers.NUMBER_FORMAT.format(budget.getIncomeSum()).replace(".", ",")) + " " + controller.getSettings().getCurrency() + " verbleibend");
+			labelStartBudget.setText("von " + String.valueOf(Helpers.NUMBER_FORMAT.format(budget.getIncomeSum()).replace(".", ",")) + " " + currency + " verbleibend");
 			
 			double factor = remaining / budget.getIncomeSum();
 			if(factor < 0)
diff --git a/src/de/deadlocker8/budgetmaster/ui/Modal.fxml b/src/de/deadlocker8/budgetmaster/ui/Modal.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..33759ff9bb89cf861f75e900f957f48ee27a25fd
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/ui/Modal.fxml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.ProgressIndicator?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.text.Font?>
+
+<AnchorPane fx:id="anchorPaneMain" prefHeight="100.0" prefWidth="375.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.ModalController">
+   <children>
+      <HBox alignment="CENTER_LEFT" spacing="10.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
+         <children>
+            <Label fx:id="labelMessage" maxWidth="1.7976931348623157E308" HBox.hgrow="ALWAYS">
+               <font>
+                  <Font size="15.0" />
+               </font>
+            </Label>
+            <ProgressIndicator prefHeight="72.0" prefWidth="34.0" />
+         </children>
+      </HBox>
+   </children>
+</AnchorPane>
diff --git a/src/de/deadlocker8/budgetmaster/ui/ModalController.java b/src/de/deadlocker8/budgetmaster/ui/ModalController.java
new file mode 100644
index 0000000000000000000000000000000000000000..042c7345a46f1f688df26dc19bf4eaf82a317c42
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/ui/ModalController.java
@@ -0,0 +1,18 @@
+package de.deadlocker8.budgetmaster.ui;
+
+import javafx.fxml.FXML;
+import javafx.scene.control.Label;
+import javafx.stage.Stage;
+
+public class ModalController
+{
+	@FXML private Label labelMessage;	
+	
+	public void init(Stage stage, String message)
+	{
+		labelMessage.setText(message);
+		stage.setOnCloseRequest((e)->{
+			e.consume();
+		});
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java b/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java
index 4a94063bfc834cc950c48a9956a696740eb65fb2..d0ab8dd13f7a575c5765ed274ec99d023d3b1534 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java
@@ -6,6 +6,7 @@ import org.controlsfx.control.PopOver;
 import org.controlsfx.control.PopOver.ArrowLocation;
 
 import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
 import de.deadlocker8.budgetmaster.logic.ServerConnection;
 import fontAwesome.FontIcon;
 import fontAwesome.FontIconType;
@@ -135,6 +136,12 @@ public class NewCategoryController
 			return;
 		}
 		
+		if(name.length() > 45)
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Der Name darf maximal 45 Zeichen lang sein.", controller.getIcon(), controller.getStage(), null, false);
+			return;
+		}
+		
 		if(edit)
 		{
 			category.setName(name);
@@ -147,7 +154,7 @@ public class NewCategoryController
 			}
 			catch(Exception e)
 			{
-				controller.showConnectionErrorAlert();
+				controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
 			}			
 		}
 		else
@@ -161,7 +168,7 @@ public class NewCategoryController
 			}
 			catch(Exception e)
 			{				
-				controller.showConnectionErrorAlert();
+				controller.showConnectionErrorAlert(e.getMessage());
 			}	
 		}
 		
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewCategoryGUI.fxml b/src/de/deadlocker8/budgetmaster/ui/NewCategoryGUI.fxml
index 9a6736f6a807a48ae2359b47ada1e91e2bfb6277..203d4acb88da4931ec70ca307d61d331d061861c 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewCategoryGUI.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/NewCategoryGUI.fxml
@@ -15,11 +15,20 @@
          <children>
             <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0">
                <children>
-                  <Label prefHeight="29.0" prefWidth="125.0" text="Name:">
-                     <font>
-                        <Font name="System Bold" size="14.0" />
-                     </font>
-                  </Label>
+                  <VBox>
+                     <children>
+                        <Label prefHeight="29.0" prefWidth="125.0" text="Name:">
+                           <font>
+                              <Font name="System Bold" size="14.0" />
+                           </font>
+                        </Label>
+                        <Label prefHeight="29.0" prefWidth="125.0" text="(max. 45 Zeichen)">
+                           <font>
+                              <Font size="11.0" />
+                           </font>
+                        </Label>
+                     </children>
+                  </VBox>
                   <TextField fx:id="textFieldName" prefHeight="29.0" HBox.hgrow="ALWAYS">
                      <font>
                         <Font size="13.0" />
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java b/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java
index 51355b5c2be6edac9a67530244c1cdb6299c48b4..1cdd2f05dc59b1c6400127ab386abcfa60e34f2b 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java
@@ -6,6 +6,7 @@ import java.util.ArrayList;
 import org.joda.time.DateTime;
 
 import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
 import de.deadlocker8.budgetmaster.logic.Helpers;
 import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.Payment;
@@ -17,7 +18,6 @@ import de.deadlocker8.budgetmaster.ui.cells.RepeatingDayCell;
 import de.deadlocker8.budgetmaster.ui.cells.SmallCategoryCell;
 import fontAwesome.FontIcon;
 import fontAwesome.FontIconType;
-import javafx.application.Platform;
 import javafx.fxml.FXML;
 import javafx.scene.control.Alert.AlertType;
 import javafx.scene.control.Button;
@@ -107,6 +107,7 @@ public class NewPaymentController
 		comboBoxCategory.setCellFactory((view) -> {
 			return new SmallCategoryCell();
 		});
+		comboBoxRepeatingDay.setValue(1);
 		buttonCategoryCell = new ButtonCategoryCell(Color.WHITE);
 		comboBoxCategory.setButtonCell(buttonCategoryCell);
 		comboBoxCategory.setStyle("-fx-border-color: #000000; -fx-border-width: 2; -fx-border-radius: 5; -fx-background-radius: 5;");
@@ -138,7 +139,7 @@ public class NewPaymentController
 		}
 		catch(Exception e)
 		{
-			controller.showConnectionErrorAlert();
+			controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
 			stage.close();
 			return;
 		}
@@ -213,9 +214,18 @@ public class NewPaymentController
 			toggleRepeatingArea(false);			
 
 			//preselect correct month and year
-			DateTime currentDate = controller.getCurrentDate();
-			datePicker.setValue(LocalDate.now().withYear(currentDate.getYear()).withMonth(currentDate.getMonthOfYear()).withDayOfMonth(currentDate.getDayOfMonth()));
-			Platform.runLater(()->{datePicker.getEditor().clear();});
+			DateTime currentDate = controller.getCurrentDate();		
+			if(DateTime.now().getDayOfMonth() > currentDate.dayOfMonth().withMaximumValue().getDayOfMonth())
+			{
+				currentDate = currentDate.dayOfMonth().withMaximumValue();				
+			}		
+			
+			LocalDate currentLocalDate = LocalDate.now().withYear(currentDate.getYear())
+			.withMonth(currentDate.getMonthOfYear())
+			.withDayOfMonth(currentDate.getDayOfMonth());
+			datePicker.setValue(currentLocalDate);
+			datePicker.setEditable(false);			
+			//Platform.runLater(()->{datePicker.getEditor().clear();});
 		}
 	}
 
@@ -227,6 +237,12 @@ public class NewPaymentController
 			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld für den Namen darf nicht leer sein.", controller.getIcon(), controller.getStage(), null, false);
 			return;
 		}
+		
+		if(name.length() > 150)
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Der Name darf maximal 150 Zeichen lang sein.", controller.getIcon(), controller.getStage(), null, false);
+			return;
+		}
 
 		String amountText = textFieldAmount.getText();
 		if(!amountText.matches("^-?\\d+(,\\d+)*(\\.\\d+(e\\d+)?)?$"))
@@ -308,7 +324,7 @@ public class NewPaymentController
 				catch(Exception e)
 				{
 					Logger.error(e);
-					controller.showConnectionErrorAlert();
+					controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
 				}
 			}
 			else
@@ -322,7 +338,7 @@ public class NewPaymentController
 				catch(Exception e)
 				{
 					Logger.error(e);
-					controller.showConnectionErrorAlert();
+					controller.showConnectionErrorAlert(e.getMessage());
 				}
 			}
 		}
@@ -348,7 +364,7 @@ public class NewPaymentController
 				catch(Exception e)
 				{
 					Logger.error(e);
-					controller.showConnectionErrorAlert();
+					controller.showConnectionErrorAlert(e.getMessage());
 				}
 			}
 			else
@@ -362,7 +378,7 @@ public class NewPaymentController
 				catch(Exception e)
 				{
 					Logger.error(e);
-					controller.showConnectionErrorAlert();
+					controller.showConnectionErrorAlert(e.getMessage());
 				}
 			}
 		}
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewPaymentGUI.fxml b/src/de/deadlocker8/budgetmaster/ui/NewPaymentGUI.fxml
index 9235231a6402291bd989eb171cb5cfe6d0d201aa..31366e41dd3bded01be30e3b15e6ab06cdce95be 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewPaymentGUI.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/NewPaymentGUI.fxml
@@ -22,11 +22,20 @@
          <children>
             <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="465.0">
                <children>
-                  <Label prefHeight="29.0" prefWidth="125.0" text="Name:">
-                     <font>
-                        <Font name="System Bold" size="14.0" />
-                     </font>
-                  </Label>
+                  <VBox>
+                     <children>
+                        <Label prefHeight="29.0" prefWidth="125.0" text="Name:">
+                           <font>
+                              <Font name="System Bold" size="14.0" />
+                           </font>
+                        </Label>
+                        <Label prefHeight="29.0" prefWidth="125.0" text="(max. 150 Zeichen)">
+                           <font>
+                              <Font size="11.0" />
+                           </font>
+                        </Label>
+                     </children>
+                  </VBox>
                   <TextField fx:id="textFieldName" prefHeight="29.0" HBox.hgrow="ALWAYS">
                      <font>
                         <Font size="13.0" />
diff --git a/src/de/deadlocker8/budgetmaster/ui/PaymentController.java b/src/de/deadlocker8/budgetmaster/ui/PaymentController.java
index db5adcc84d3d952eae84f269b1acce9e1e9d976e..c4b7cc52c7d3ea25d3030b59c9c2c4c165637487 100644
--- a/src/de/deadlocker8/budgetmaster/ui/PaymentController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/PaymentController.java
@@ -4,6 +4,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 
 import de.deadlocker8.budgetmaster.logic.Budget;
+import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
 import de.deadlocker8.budgetmaster.logic.FilterSettings;
 import de.deadlocker8.budgetmaster.logic.Helpers;
 import de.deadlocker8.budgetmaster.logic.NormalPayment;
@@ -74,6 +75,7 @@ public class PaymentController implements Refreshable
 						}
 					}
 				});
+				cell.prefWidthProperty().bind(listView.widthProperty().subtract(2));
 				return cell;
 			}
 		});
@@ -204,7 +206,7 @@ public class PaymentController implements Refreshable
 		catch(Exception e)
 		{
 			e.printStackTrace();
-			controller.showConnectionErrorAlert();
+			controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
 		}
 	}
 
@@ -219,7 +221,7 @@ public class PaymentController implements Refreshable
 		catch(Exception e)
 		{
 			e.printStackTrace();
-			controller.showConnectionErrorAlert();
+			controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
 		}
 	}
 
@@ -238,7 +240,7 @@ public class PaymentController implements Refreshable
 		catch(Exception e)
 		{
 			e.printStackTrace();
-			controller.showConnectionErrorAlert();
+			controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
 		}
 	}
 	
diff --git a/src/de/deadlocker8/budgetmaster/ui/SettingsController.java b/src/de/deadlocker8/budgetmaster/ui/SettingsController.java
index 471619dc9dbe1c4788c6de5b70a64e7354e13d9f..76e98b0784ff7d04fcf25ccf4e5e9b44328b4803 100644
--- a/src/de/deadlocker8/budgetmaster/ui/SettingsController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/SettingsController.java
@@ -1,19 +1,43 @@
 package de.deadlocker8.budgetmaster.ui;
 
+import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Optional;
 
+import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.ServerConnection;
 import de.deadlocker8.budgetmaster.logic.Settings;
 import de.deadlocker8.budgetmaster.logic.Utils;
+import de.deadlocker8.budgetmasterserver.logic.Database;
+import javafx.application.Platform;
 import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Alert;
 import javafx.scene.control.Alert.AlertType;
 import javafx.scene.control.Button;
+import javafx.scene.control.ButtonBar.ButtonData;
+import javafx.scene.control.ButtonType;
 import javafx.scene.control.Label;
 import javafx.scene.control.RadioButton;
+import javafx.scene.control.TextArea;
 import javafx.scene.control.TextField;
+import javafx.scene.control.TextInputDialog;
 import javafx.scene.control.ToggleGroup;
 import javafx.scene.layout.AnchorPane;
+import javafx.stage.FileChooser;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
 import logger.Logger;
 import tools.AlertGenerator;
+import tools.BASE58Type;
+import tools.ConvertTo;
+import tools.HashUtils;
+import tools.RandomCreations;
+import tools.Worker;
 
 public class SettingsController
 {
@@ -25,8 +49,12 @@ public class SettingsController
 	@FXML private TextField textFieldCurrency;
 	@FXML private Label labelCurrency;
 	@FXML private Button buttonSave;
+	@FXML private Button buttonExportDB;
+	@FXML private Button buttonImportDB;
+	@FXML private Button buttonDeleteDB;
 	@FXML private RadioButton radioButtonRestActivated;
 	@FXML private RadioButton radioButtonRestDeactivated;
+	@FXML private TextArea textAreaTrustedHosts;
 
 	private Controller controller;
 
@@ -36,7 +64,7 @@ public class SettingsController
 		if(controller.getSettings() != null)
 		{
 			textFieldURL.setText(controller.getSettings().getUrl());
-			textFieldSecret.setText(controller.getSettings().getSecret());
+			textFieldSecret.setText("******");
 			textFieldCurrency.setText(controller.getSettings().getCurrency());
 			if(controller.getSettings().isRestActivated())
 			{
@@ -46,74 +74,326 @@ public class SettingsController
 			{
 				radioButtonRestDeactivated.setSelected(true);
 			}
+			setTextAreaTrustedHosts(controller.getSettings().getTrustedHosts());
 		}
-		
+
 		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
 		labelSecret.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
 		labelURL.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
 		labelCurrency.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
-		buttonSave.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;");	
+		buttonSave.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;");
+		buttonExportDB.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;");
+		buttonImportDB.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;");
+		buttonDeleteDB.setStyle("-fx-background-color: #FF5047; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;");
 		textFieldURL.setPromptText("z.B. https://yourdomain.de");
 		textFieldCurrency.setPromptText("z.B. €, CHF, $");
-		
+		textAreaTrustedHosts.setPromptText("z.B. localhost");
+
 		ToggleGroup toggleGroup = new ToggleGroup();
 		radioButtonRestActivated.setToggleGroup(toggleGroup);
 		radioButtonRestDeactivated.setToggleGroup(toggleGroup);
 	}
-	
+
+	private void setTextAreaTrustedHosts(ArrayList<String> trustedHosts)
+	{
+		StringBuilder trustedHostsString = new StringBuilder();
+		if(trustedHosts != null)
+		{
+			for(String currentHost : trustedHosts)
+			{
+				trustedHostsString.append(currentHost);
+				trustedHostsString.append("\n");
+			}
+			textAreaTrustedHosts.setText(trustedHostsString.toString());
+		}
+		else
+		{
+			textAreaTrustedHosts.setText("");
+		}
+	}
+
 	public void save()
 	{
 		String url = textFieldURL.getText().trim();
 		String secret = textFieldSecret.getText().trim();
 		String currency = textFieldCurrency.getText().trim();
-		if(url != null && !url.equals(""))
+		if(url == null || url.equals(""))
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld für die Server URL darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
+			return;
+		}
+
+		if(secret == null || secret.equals(""))
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Server Passwortfeld darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
+			return;
+		}
+
+		if(currency == null || currency.equals(""))
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gib deine gewünschte Währung ein!", controller.getIcon(), controller.getStage(), null, false);
+			return;
+		}
+
+		ArrayList<String> trustedHosts = new ArrayList<>();
+		String trustedHostText = textAreaTrustedHosts.getText();
+		String[] trustedHostsArray = trustedHostText.split("\n");
+		for(String currentHost : trustedHostsArray)
+		{
+			currentHost = currentHost.trim();
+			if(!currentHost.equals(""))
+			{
+				trustedHosts.add(currentHost);
+			}
+		}
+		setTextAreaTrustedHosts(trustedHosts);
+
+		if(controller.getSettings() != null)
 		{
-			if(secret != null && !secret.equals(""))
+			if(!secret.equals("******"))
 			{
-				if(currency != null && !currency.equals(""))
+				controller.getSettings().setSecret(HashUtils.hash(secret, Helpers.SALT));
+			}
+			controller.getSettings().setUrl(url);
+			controller.getSettings().setCurrency(currency);
+			controller.getSettings().setRestActivated(radioButtonRestActivated.isSelected());
+			controller.getSettings().setTrustedHosts(trustedHosts);
+		}
+		else
+		{
+			Settings settings = new Settings();
+			settings.setUrl(url);
+			settings.setSecret(HashUtils.hash(secret, Helpers.SALT));
+			settings.setCurrency(currency);
+			settings.setRestActivated(radioButtonRestActivated.isSelected());
+			settings.setTrustedHosts(trustedHosts);
+			controller.setSettings(settings);
+		}
+
+		try
+		{
+			Utils.saveSettings(controller.getSettings());
+		}
+		catch(IOException e)
+		{
+			Logger.error(e);
+			AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Speichern der Einstellungen ist ein Fehler aufgetreten", controller.getIcon(), controller.getStage(), null, false);
+		}
+
+		textFieldSecret.setText("******");
+
+		controller.refresh(controller.getFilterSettings());
+		controller.showNotification("Erfolgreich gespeichert");
+	}
+
+	public void exportDB()
+	{
+		FileChooser fileChooser = new FileChooser();
+		fileChooser.setTitle("Datenbank exportieren");
+		FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("JSON (*.json)", "*.json");
+		fileChooser.getExtensionFilters().add(extFilter);
+		File file = fileChooser.showSaveDialog(controller.getStage());
+		if(file != null)
+		{
+			Stage modalStage = showModal("Vorgang läuft", "Die Datenbank wird exportiert, bitte warten...");
+
+			Worker.runLater(() -> {
+				try
 				{
-					if(controller.getSettings() != null)
-					{
-						controller.getSettings().setUrl(url);
-						controller.getSettings().setSecret(secret);	
-						controller.getSettings().setCurrency(currency);
-						controller.getSettings().setRestActivated(radioButtonRestActivated.isSelected());
-					}
-					else
-					{
-						Settings settings = new Settings();
-						settings.setUrl(url);
-						settings.setSecret(secret);
-						settings.setCurrency(currency);
-						settings.setRestActivated(radioButtonRestActivated.isSelected());
-						controller.setSettings(settings);
-					}
-					
+					ServerConnection connection = new ServerConnection(controller.getSettings());
+					String databaseJSON = connection.exportDatabase();
+					Utils.saveDatabaseJSON(file, databaseJSON);
+
+					Platform.runLater(() -> {
+						if(modalStage != null)
+						{
+							modalStage.close();
+						}
+						AlertGenerator.showAlert(AlertType.INFORMATION, "Erfolgreich exportiert", "", "Die Datenbank wurder erfolgreich exportiert.", controller.getIcon(), controller.getStage(), null, false);
+					});
+				}
+				catch(Exception e)
+				{
+					Logger.error(e);
+					Platform.runLater(() -> {
+						if(modalStage != null)
+						{
+							modalStage.close();
+						}
+						controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));						
+					});
+				}
+			});
+		}
+	}
+	
+	private void importDatabase()
+	{
+		FileChooser fileChooser = new FileChooser();
+		fileChooser.setTitle("Datenbank importieren");
+		FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("JSON (*.json)", "*.json");
+		fileChooser.getExtensionFilters().add(extFilter);
+		File file = fileChooser.showOpenDialog(controller.getStage());
+		if(file != null)
+		{
+			Database database;
+			try
+			{
+				database = Utils.loadDatabaseJSON(file);
+				if(database.getCategories() == null || database.getNormalPayments() == null || database.getRepeatingPayments() == null)
+				{
+					AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Die angegebene Datei enthält kein gültiges BudgetMaster-Datenformat und kann daher nicht importiert werden.", controller.getIcon(), controller.getStage(), null, false);
+					return;
+				}
+			}
+			catch(IOException e1)
+			{
+				Logger.error(e1);
+				AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Einlesen der Datei ist ein Fehler aufgetreten.", controller.getIcon(), controller.getStage(), null, false);
+				return;
+			}
+
+			Stage modalStage = showModal("Vorgang läuft", "Die Datenbank wird importiert, bitte warten...");
+
+			Worker.runLater(() -> {
+				try
+				{
+					ServerConnection connection = new ServerConnection(controller.getSettings());
+					connection.importDatabase(database);
+
+					Platform.runLater(() -> {
+						if(modalStage != null)
+						{
+							modalStage.close();
+						}
+						AlertGenerator.showAlert(AlertType.INFORMATION, "Erfolgreich exportiert", "", "Die Datenbank wurder erfolgreich importiert.", controller.getIcon(), controller.getStage(), null, false);
+					});
+				}
+				catch(Exception e)
+				{
+					Logger.error(e);
+					Platform.runLater(() -> {
+						if(modalStage != null)
+						{
+							modalStage.close();
+						}
+						controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
+					});
+				}
+			});
+		}
+	}
+
+	public void importDB()
+	{
+		Alert alert = new Alert(AlertType.CONFIRMATION);
+		alert.setTitle("Datenbank importieren");
+		alert.setHeaderText("");		
+		alert.setContentText("Soll die Datenbank vor dem Importieren gelöscht werden?");
+		Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow();
+		dialogStage.getIcons().add(controller.getIcon());
+		dialogStage.initOwner(controller.getStage());
+
+		ButtonType buttonTypeDelete = new ButtonType("Ja, Datenbank löschen");
+		ButtonType buttonTypeAppend = new ButtonType("Nein, Daten hinzufügen");
+		ButtonType buttonTypeCancel = new ButtonType("Abbrechen", ButtonData.CANCEL_CLOSE);
+
+		alert.getButtonTypes().setAll(buttonTypeDelete, buttonTypeAppend, buttonTypeCancel);
+		Optional<ButtonType> result = alert.showAndWait();
+		if(result.get() == buttonTypeDelete)
+		{
+			deleteDatabase(true);
+		}	
+		else if(result.get() == buttonTypeAppend)
+		{	
+			importDatabase();
+		}
+	}
+	
+	public void deleteDB()
+	{
+		deleteDatabase(false);
+	}
+
+	public void deleteDatabase(boolean importPending)
+	{
+		String verificationCode = ConvertTo.toBase58(RandomCreations.generateRandomMixedCaseString(4, true), true, BASE58Type.UPPER);
+
+		TextInputDialog dialog = new TextInputDialog();
+		dialog.setTitle("Datenbank löschen");
+		dialog.setHeaderText("Soll die Datenbank wirklich gelöscht werden?");
+		dialog.setContentText("Zur Bestätigung gib folgenden Code ein:\t" + verificationCode);
+		Stage dialogStage = (Stage)dialog.getDialogPane().getScene().getWindow();
+		dialogStage.getIcons().add(controller.getIcon());
+		dialogStage.initOwner(controller.getStage());
+
+		Optional<String> result = dialog.showAndWait();
+		if(result.isPresent())
+		{
+			if(result.get().equals(verificationCode))
+			{
+				Stage modalStage = showModal("Vorgang läuft", "Die Datenbank wird gelöscht, bitte warten...");
+
+				Worker.runLater(() -> {
 					try
 					{
-						Utils.saveSettings(controller.getSettings());
+						ServerConnection connection = new ServerConnection(controller.getSettings());
+						connection.deleteDatabase();
+						Platform.runLater(() -> {
+							if(modalStage != null)
+							{
+								modalStage.close();
+								if(importPending)
+								{
+									importDatabase();
+								}
+							}
+						});
 					}
-					catch(IOException e)
+					catch(Exception e)
 					{
 						Logger.error(e);
-						AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Speichern der Einstellungen ist ein Fehler aufgetreten", controller.getIcon(), controller.getStage(), null, false);
-					}	
-					controller.refresh(controller.getFilterSettings());
-					controller.showNotification("Erfolgreich gespeichert");
-				}
-				else
-				{
-					AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gib deine gewünschte Währung ein!", controller.getIcon(), controller.getStage(), null, false);
-				}
+						Platform.runLater(() -> {
+							if(modalStage != null)
+							{
+								modalStage.close();
+							}
+							controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
+						});
+					}
+				});
 			}
 			else
 			{
-				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Server Passwortfeld darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
+				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Die Eingabe stimmt nicht mit dem Bestätigungscode überein.", controller.getIcon(), controller.getStage(), null, false);
+				deleteDB();
 			}
 		}
-		else
+	}
+
+	private Stage showModal(String title, String message)
+	{
+		try
 		{
-			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld für die Server URL darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
+			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/Modal.fxml"));
+			Parent root = (Parent)fxmlLoader.load();
+			Stage newStage = new Stage();
+			newStage.initOwner(controller.getStage());
+			newStage.initModality(Modality.APPLICATION_MODAL);
+			newStage.setTitle(title);
+			newStage.setScene(new Scene(root));
+			newStage.getIcons().add(controller.getIcon());
+			newStage.setResizable(false);
+			ModalController newController = fxmlLoader.getController();
+			newController.init(newStage, message);
+			newStage.show();
+
+			return newStage;
+		}
+		catch(IOException e)
+		{
+			Logger.error(e);
+			return null;
 		}
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml b/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml
index 0fc94536e52887e64a3a83aaab44298d89253d10..8014a8cab8429d648976e326a52d09a1abbe935d 100644
--- a/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml
@@ -4,9 +4,11 @@
 <?import javafx.scene.control.Button?>
 <?import javafx.scene.control.Label?>
 <?import javafx.scene.control.RadioButton?>
+<?import javafx.scene.control.TextArea?>
 <?import javafx.scene.control.TextField?>
 <?import javafx.scene.layout.AnchorPane?>
 <?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.Region?>
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
@@ -14,7 +16,7 @@
    <children>
       <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0">
          <children>
-            <HBox prefHeight="70.0">
+            <HBox prefHeight="359.0" prefWidth="722.0">
                <children>
                   <VBox alignment="CENTER_RIGHT" prefHeight="25.0" prefWidth="158.0" spacing="20.0">
                      <children>
@@ -41,6 +43,39 @@
                               <Font name="System Bold" size="16.0" />
                            </font>
                         </Label>
+                        <Label fx:id="labelSecret111" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" minHeight="60.0" prefWidth="158.0" text="Vertrauenswürdige Hosts:" textAlignment="RIGHT" wrapText="true">
+                           <font>
+                              <Font name="System Bold" size="16.0" />
+                           </font>
+                           <VBox.margin>
+                              <Insets top="-5.0" />
+                           </VBox.margin>
+                        </Label>
+                        <Label fx:id="labelSecret1111" alignment="CENTER" contentDisplay="CENTER" maxHeight="-Infinity" text="(ein Host pro Zeile)" textAlignment="CENTER" wrapText="true" VBox.vgrow="ALWAYS">
+                           <font>
+                              <Font size="14.0" />
+                           </font>
+                           <VBox.margin>
+                              <Insets top="-20.0" />
+                           </VBox.margin>
+                        </Label>
+                        <Label fx:id="labelSecret1112" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" text="Datenbank:" textAlignment="RIGHT" wrapText="true">
+                           <font>
+                              <Font name="System Bold" size="16.0" />
+                           </font>
+                           <VBox.margin>
+                              <Insets top="35.0" />
+                           </VBox.margin>
+                        </Label>
+                        <Label fx:id="labelSecret11121" alignment="CENTER_RIGHT" contentDisplay="RIGHT" maxHeight="-Infinity" prefWidth="158.0" textAlignment="RIGHT" wrapText="true">
+                           <font>
+                              <Font name="System Bold" size="16.0" />
+                           </font>
+                           <VBox.margin>
+                              <Insets top="15.0" />
+                           </VBox.margin>
+                        </Label>
+                        <Region prefHeight="19.0" prefWidth="158.0" VBox.vgrow="ALWAYS" />
                      </children>
                      <HBox.margin>
                         <Insets right="25.0" />
@@ -51,14 +86,14 @@
                         <TextField fx:id="textFieldURL" />
                         <TextField fx:id="textFieldSecret" />
                         <TextField fx:id="textFieldCurrency" />
-                        <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
+                        <HBox alignment="CENTER" prefHeight="11.0" prefWidth="539.0" spacing="30.0">
                            <children>
                               <RadioButton fx:id="radioButtonRestActivated" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="aktiviert">
                                  <font>
                                     <Font size="14.0" />
                                  </font>
                                  <HBox.margin>
-                                    <Insets right="30.0" />
+                                    <Insets />
                                  </HBox.margin>
                               </RadioButton>
                               <RadioButton fx:id="radioButtonRestDeactivated" maxWidth="1.7976931348623157E308" mnemonicParsing="false" text="deaktiviert" HBox.hgrow="ALWAYS">
@@ -68,15 +103,45 @@
                               </RadioButton>
                            </children>
                         </HBox>
+                        <TextArea fx:id="textAreaTrustedHosts" minHeight="110.0" prefHeight="148.0" prefWidth="539.0" VBox.vgrow="ALWAYS">
+                           <VBox.margin>
+                              <Insets />
+                           </VBox.margin></TextArea>
+                        <HBox alignment="CENTER_LEFT" prefHeight="11.0" prefWidth="539.0" spacing="30.0">
+                           <children>
+                              <Button fx:id="buttonExportDB" mnemonicParsing="false" onAction="#exportDB" text="Exportieren">
+                                 <font>
+                                    <Font name="System Bold" size="14.0" />
+                                 </font>
+                              </Button>
+                              <Button fx:id="buttonImportDB" mnemonicParsing="false" onAction="#importDB" text="Importieren">
+                                 <font>
+                                    <Font name="System Bold" size="14.0" />
+                                 </font>
+                              </Button>
+                              <Button fx:id="buttonDeleteDB" mnemonicParsing="false" onAction="#deleteDB" text="Löschen">
+                                 <font>
+                                    <Font name="System Bold" size="14.0" />
+                                 </font>
+                              </Button>
+                           </children>
+                           <VBox.margin>
+                              <Insets />
+                           </VBox.margin>
+                        </HBox>
+                        <Button fx:id="buttonSave" mnemonicParsing="false" onAction="#save" text="Speichern">
+                           <font>
+                              <Font name="System Bold" size="14.0" />
+                           </font>
+                           <VBox.margin>
+                              <Insets top="15.0" />
+                           </VBox.margin>
+                        </Button>
+                        <Region prefWidth="158.0" VBox.vgrow="ALWAYS" />
                      </children>
                   </VBox>
                </children>
             </HBox>
-            <Button fx:id="buttonSave" mnemonicParsing="false" onAction="#save" text="Speichern">
-               <font>
-                  <Font name="System Bold" size="14.0" />
-               </font>
-            </Button>
          </children>
          <padding>
             <Insets right="50.0" />
diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java b/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java
index 8a6b957911d7bf78d4bb359eb197b4e8c737f39b..e096c9a72a0c14fdabd8972136b64e235e739ac2 100644
--- a/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java
+++ b/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java
@@ -69,6 +69,7 @@ public class PaymentCell extends ListCell<Payment>
 			labelDate.setAlignment(Pos.CENTER);
 			labelDate.getStyleClass().add("greylabel");
 			labelDate.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #212121");
+			labelDate.setMinWidth(75);
 			hbox.getChildren().add(labelDate);
 
 			FontIcon iconRepeating = new FontIcon(FontIconType.CALENDAR);
@@ -88,7 +89,7 @@ public class PaymentCell extends ListCell<Payment>
 			labelRepeating.setAlignment(Pos.CENTER);
 			labelRepeating.getStyleClass().add("greylabel");
 			hbox.getChildren().add(labelRepeating);
-			HBox.setMargin(labelRepeating, new Insets(0, 30, 0, 15));
+			HBox.setMargin(labelRepeating, new Insets(0, 20, 0, 15));
 
 			String categoryName = category.getName();
 			if(categoryName.equals("NONE"))
@@ -97,8 +98,8 @@ public class PaymentCell extends ListCell<Payment>
 			}
 
 			Label labelCircle = new Label(categoryName.substring(0, 1).toUpperCase());
-			labelCircle.setPrefWidth(HEIGHT);
-			labelCircle.setPrefHeight(HEIGHT);
+			labelCircle.setMinWidth(HEIGHT);
+			labelCircle.setMinHeight(HEIGHT);
 			labelCircle.setAlignment(Pos.CENTER);
 			labelCircle.getStyleClass().add("greylabel");
 			String textColor = ConvertTo.toRGBHex(ConvertTo.getAppropriateTextColor(category.getColor()));
@@ -106,14 +107,13 @@ public class PaymentCell extends ListCell<Payment>
 			Tooltip tooltip = new Tooltip(categoryName);
 			tooltip.setStyle("-fx-font-size: 14");
 			labelCircle.setTooltip(tooltip);
-			hbox.getChildren().add(labelCircle);
-			
+			hbox.getChildren().add(labelCircle);			
 
 			Label labelName = new Label(item.getName());
 			labelName.setPrefHeight(HEIGHT);
 			labelName.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #212121");
 			labelName.setAlignment(Pos.CENTER);
-			labelName.getStyleClass().add("greylabel");
+			labelName.getStyleClass().add("greylabel");			
 			hbox.getChildren().add(labelName);
 			HBox.setMargin(labelName, new Insets(0, 0, 0, 20));
 
@@ -126,6 +126,7 @@ public class PaymentCell extends ListCell<Payment>
 			labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #247A2D");
 			labelBudget.setAlignment(Pos.CENTER);
 			labelBudget.getStyleClass().add("greylabel");
+			labelBudget.setMinWidth(90);
 			hbox.getChildren().add(labelBudget);
 			HBox.setMargin(labelBudget, new Insets(0, 0, 0, 20));
 
@@ -150,17 +151,17 @@ public class PaymentCell extends ListCell<Payment>
 				Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
 				alert.setTitle("Zahlung löschen");
 				alert.setHeaderText("");
-				alert.setContentText("Diese Zahlung wirklich unwiederruflich löschen?");
+				alert.setContentText("Diese Zahlung wirklich unwiderruflich löschen?");
 				Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow();
 				dialogStage.getIcons().add(paymentController.getController().getIcon());
 				dialogStage.centerOnScreen();
 
 				if(item instanceof RepeatingPaymentEntry)
 				{
-					alert.setContentText("Es handelt sich um eine wiederkehrende Zahlung. Wie soll gelöscht werden?");
+					alert.setContentText("Es handelt sich um eine wiederkehrende Zahlung. Welche Zahlungen sollen gelöscht werden?");
 					
-					ButtonType buttonTypeOne = new ButtonType("Komplett löschen");
-					ButtonType buttonTypeTwo = new ButtonType("Alle zukünftigen Löschen");				
+					ButtonType buttonTypeOne = new ButtonType("Alle");
+					ButtonType buttonTypeTwo = new ButtonType("Alle zukünftigen");				
 					ButtonType buttonTypeCancel = new ButtonType("Abbrechen", ButtonData.CANCEL_CLOSE);
 
 					alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeCancel);
@@ -185,14 +186,14 @@ public class PaymentCell extends ListCell<Payment>
 				}
 			});
 			hbox.getChildren().add(buttonDelete);
-			HBox.setMargin(buttonDelete, new Insets(0, 0, 0, 25));
+			HBox.setMargin(buttonDelete, new Insets(0, 0, 0, 10));
 			// don't allow "Übertrag" to be deleted
 			if(item.getID() == -1)
 			{
 				buttonDelete.setVisible(false);
 			}
 
-			hbox.setPadding(new Insets(10));
+			hbox.setPadding(new Insets(10, 8, 10, 5));
 			setStyle("-fx-background: transparent; -fx-border-color: #545454; -fx-border-width: 0 0 1 0");
 			setGraphic(hbox);
 			setAlignment(Pos.CENTER);
diff --git a/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickGUI.fxml b/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickGUI.fxml
index c96c6768ced8598de0f3758b2a23d8c5133879c3..7b0f539542397085a05f4febd10d01875ca5c498 100644
--- a/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickGUI.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorPickGUI.fxml
@@ -90,12 +90,12 @@
                   </HBox>
                   <HBox alignment="BOTTOM_CENTER" prefHeight="0.0" prefWidth="299.0" spacing="25.0" VBox.vgrow="ALWAYS">
                      <children>
-                        <Button fx:id="buttonSave" mnemonicParsing="false" onAction="#save" text="Speichern">
+                        <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#cancel" text="Abbrechen">
                            <font>
                               <Font name="System Bold" size="14.0" />
                            </font>
                         </Button>
-                        <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#cancel" text="Abbrechen">
+                        <Button fx:id="buttonSave" mnemonicParsing="false" onAction="#save" text="Speichern">
                            <font>
                               <Font name="System Bold" size="14.0" />
                            </font>
diff --git a/src/de/deadlocker8/budgetmasterserver/logic/Database.java b/src/de/deadlocker8/budgetmasterserver/logic/Database.java
new file mode 100644
index 0000000000000000000000000000000000000000..05740dae2752cab71a041f93dcfd08911e4d5088
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/logic/Database.java
@@ -0,0 +1,41 @@
+package de.deadlocker8.budgetmasterserver.logic;
+
+import java.util.ArrayList;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+
+public class Database
+{
+	private ArrayList<Category> categories;
+	private ArrayList<NormalPayment> normalPayments;
+	private ArrayList<RepeatingPayment> repeatingPayments;
+	
+	public Database()
+	{
+	    
+	}
+	
+	public Database(ArrayList<Category> categories, ArrayList<NormalPayment> normalPayments, ArrayList<RepeatingPayment> repeatingPayments)
+	{
+	    this.categories = categories;
+	    this.normalPayments = normalPayments;
+	    this.repeatingPayments = repeatingPayments;
+	}
+	
+	public ArrayList<Category> getCategories()
+	{
+	    return categories;
+	}
+	
+	public ArrayList<NormalPayment> getNormalPayments()
+    {
+        return normalPayments;
+    }
+	
+	public ArrayList<RepeatingPayment> getRepeatingPayments()
+    {
+        return repeatingPayments;
+    }
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/main/DatabaseCreator.java b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseCreator.java
similarity index 96%
rename from src/de/deadlocker8/budgetmasterserver/main/DatabaseCreator.java
rename to src/de/deadlocker8/budgetmasterserver/logic/DatabaseCreator.java
index 7a512f12e66f69b9d9b4a4a98e7a0794ad959f34..398629d7b146d0aee5a4b3d3bbac5451b2b39f05 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/DatabaseCreator.java
+++ b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseCreator.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmasterserver.main;
+package de.deadlocker8.budgetmasterserver.logic;
 
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
@@ -109,7 +109,7 @@ public class DatabaseCreator
 		Statement stmt = null;
 		String query = "CREATE TABLE `payment` (" +
 					 "`ID` int(11) NOT NULL COMMENT 'ID'," +
-					 "`Name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'payment name (description)'," +
+					 "`Name` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'payment name (description)'," +
 					 "`CategoryID` int(11) DEFAULT NULL COMMENT 'category ID'," +
 					 "`Amount` int(11) DEFAULT NULL COMMENT 'amount in cents'," +
 					 "`Date` date DEFAULT NULL COMMENT 'payment date',"	 +
@@ -190,7 +190,7 @@ public class DatabaseCreator
 		Statement stmt = null;
 		String query = "CREATE TABLE `repeating_payment` (" +
 					  "`ID` int(11) NOT NULL COMMENT 'ID'," +
-					  "`Name` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'payment name (description)'," +
+					  "`Name` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'payment name (description)'," +
 					  "`CategoryID` int(11) DEFAULT NULL COMMENT 'category ID'," +
 					  "`Amount` int(11) DEFAULT NULL COMMENT 'amount in cents'," +
 					  "`Date` date DEFAULT NULL COMMENT 'payment date'," +
diff --git a/src/de/deadlocker8/budgetmasterserver/logic/DatabaseExporter.java b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseExporter.java
new file mode 100644
index 0000000000000000000000000000000000000000..eeda5e9593b00b74b71a76672598123af4467320
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseExporter.java
@@ -0,0 +1,171 @@
+package de.deadlocker8.budgetmasterserver.logic;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+import javafx.scene.paint.Color;
+import logger.Logger;
+
+public class DatabaseExporter
+{
+	private Connection connection;
+	
+	public DatabaseExporter(Settings settings) throws IllegalStateException
+    {
+        try
+        {
+            this.connection = DriverManager.getConnection(settings.getDatabaseUrl() + settings.getDatabaseName() + "?useLegacyDatetimeCode=false&serverTimezone=Europe/Berlin", settings.getDatabaseUsername(), settings.getDatabasePassword());
+        }
+        catch(Exception e)
+        {
+            Logger.error(e);
+            throw new IllegalStateException("Cannot connect the database!", e);
+        }
+    }
+	
+	public Database exportDatabase()
+	{
+	    ArrayList<Category> categories = getAllCategories();
+	    ArrayList<NormalPayment> normalPayments = getAllNormalPayments();
+	    ArrayList<RepeatingPayment> repeatingPayments = getAllRepeatingPayments();
+	    
+	    return new Database(categories, normalPayments, repeatingPayments);
+	}
+	
+	private ArrayList<Category> getAllCategories()
+	{	   
+        Statement stmt = null;
+        String query = "SELECT * FROM category ORDER BY category.ID";
+        ArrayList<Category> results = new ArrayList<>();
+        try
+        {
+            stmt = connection.createStatement();
+            ResultSet rs = stmt.executeQuery(query);
+            while(rs.next())
+            {
+                int id = rs.getInt("ID");
+                String name = rs.getString("Name");
+                String color = rs.getString("Color");
+
+                results.add(new Category(id, name, Color.web(color)));
+            }
+        }
+        catch(SQLException e)
+        {
+            Logger.error(e);
+        }
+        finally
+        {
+            if(stmt != null)
+            {
+                try
+                {
+                    stmt.close();
+                }
+                catch(SQLException e)
+                {
+                }
+            }
+        }
+
+        return results;    
+	}
+	
+	private ArrayList<NormalPayment> getAllNormalPayments()
+    {
+	    Statement stmt = null;
+        String query = "SELECT * FROM payment;";
+
+        ArrayList<NormalPayment> results = new ArrayList<>();
+        try
+        {
+            stmt = connection.createStatement();
+            ResultSet rs = stmt.executeQuery(query);
+
+            while(rs.next())
+            {
+                int resultID = rs.getInt("ID");             
+                String name = rs.getString("Name");
+                int amount = rs.getInt("amount");
+                String date = rs.getString("Date");             
+                int categoryID = rs.getInt("CategoryID");
+                String description = rs.getString("Description");
+            
+                results.add(new NormalPayment(resultID, amount, date, categoryID, name, description));
+            }
+        }
+        catch(SQLException e)
+        {
+            Logger.error(e);
+        }
+        finally
+        {
+            if(stmt != null)
+            {
+                try
+                {
+                    stmt.close();
+                }
+                catch(SQLException e)
+                {
+                }
+            }
+        }
+
+        return results;
+    }
+	
+	private ArrayList<RepeatingPayment> getAllRepeatingPayments()
+    {
+	    Statement stmt = null;
+        String query = "SELECT * FROM repeating_payment;";
+
+        ArrayList<RepeatingPayment> results = new ArrayList<>();
+        try
+        {
+            stmt = connection.createStatement();
+            ResultSet rs = stmt.executeQuery(query);
+
+            while(rs.next())
+            {
+                int resultID = rs.getInt("ID");                               
+                String name = rs.getString("Name");
+                String description = rs.getString("Description");
+                int amount = rs.getInt("amount");
+                String date = rs.getString("Date");             
+                int categoryID = rs.getInt("CategoryID");
+                int repeatInterval = rs.getInt("RepeatInterval");
+                String repeatEndDate = rs.getString("RepeatEndDate");
+                int repeatMonthDay = rs.getInt("RepeatMonthDay");       
+            
+                results.add(new RepeatingPayment(resultID, amount, date, categoryID, name, description, repeatInterval, repeatEndDate, repeatMonthDay));
+            }
+        }
+        catch(SQLException e)
+        {
+            Logger.error(e);
+        }
+        finally
+        {
+            if(stmt != null)
+            {
+                try
+                {
+                    stmt.close();
+                }
+                catch(SQLException e)
+                {
+                }
+            }
+        }
+
+        return results;
+    }	
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/main/DatabaseHandler.java b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseHandler.java
similarity index 62%
rename from src/de/deadlocker8/budgetmasterserver/main/DatabaseHandler.java
rename to src/de/deadlocker8/budgetmasterserver/logic/DatabaseHandler.java
index 61b8ee0401aa153b527c1fd2b34190075e333a88..328d6ee8226b84f57f3d758d0b2c929262960b51 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/DatabaseHandler.java
+++ b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseHandler.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmasterserver.main;
+package de.deadlocker8.budgetmasterserver.logic;
 
 import java.sql.Connection;
 import java.sql.DriverManager;
@@ -30,7 +30,7 @@ public class DatabaseHandler
 	{
 		try
 		{
-			this.connection = DriverManager.getConnection(settings.getDatabaseUrl() + settings.getDatabaseName() + "?useLegacyDatetimeCode=false&serverTimezone=Europe/Berlin", settings.getDatabaseUsername(), settings.getDatabasePassword());
+			this.connection = DriverManager.getConnection(settings.getDatabaseUrl() + settings.getDatabaseName() + "?useLegacyDatetimeCode=false&serverTimezone=Europe/Berlin&autoReconnect=true&wait_timeout=86400", settings.getDatabaseUsername(), settings.getDatabasePassword());
 			new DatabaseCreator(connection, settings);
 			Logger.info("Successfully initialized database (" + settings.getDatabaseUrl() + settings.getDatabaseName() + ")");
 		}
@@ -40,15 +40,29 @@ public class DatabaseHandler
 			throw new IllegalStateException("Cannot connect the database!", e);
 		}
 	}
+	
+	private void closeConnection(Statement statement)
+	{
+		if(statement != null)
+		{
+			try
+			{
+				statement.close();
+			}
+			catch(SQLException e)
+			{
+			}
+		}
+	}
 
 	/*
 	 * GET
 	 */
-	public DateTime getFirstNormalPaymentDate()
+	public int getLastInsertID()
 	{
 		Statement stmt = null;
-		String query = "SELECT MIN(Date) as \"min\" FROM payment";
-		DateTime dateTime = null;
+		String query = "SELECT LAST_INSERT_ID();";
+		int lastInsertID = 0;
 		try
 		{
 			stmt = connection.createStatement();
@@ -56,7 +70,7 @@ public class DatabaseHandler
 
 			while(rs.next())
 			{
-				dateTime = formatter.parseDateTime(rs.getString("min"));
+				lastInsertID = rs.getInt("LAST_INSERT_ID()");				
 			}
 		}
 		catch(SQLException e)
@@ -65,21 +79,47 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
+			closeConnection(stmt);
+		}
+
+		return lastInsertID;
+	}
+	
+	public DateTime getFirstNormalPaymentDate()
+	{
+		Statement stmt = null;
+		String query = "SELECT MIN(Date) as \"min\" FROM payment";
+		DateTime dateTime = null;
+		try
+		{
+			stmt = connection.createStatement();
+			ResultSet rs = stmt.executeQuery(query);
+
+			while(rs.next())
 			{
-				try
+				String min = rs.getString("min");
+				if(min == null)
 				{
-					stmt.close();
+					dateTime = null;
 				}
-				catch(SQLException e)
+				else
 				{
+					dateTime = formatter.parseDateTime(rs.getString("min"));
 				}
 			}
 		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			closeConnection(stmt);
+		}
 
 		return dateTime;
 	}
-	
+
 	public DateTime getFirstRepeatingPaymentDate()
 	{
 		Statement stmt = null;
@@ -92,7 +132,15 @@ public class DatabaseHandler
 
 			while(rs.next())
 			{
-				dateTime = formatter.parseDateTime(rs.getString("min"));
+				String min = rs.getString("min");
+				if(min == null)
+				{
+					dateTime = null;
+				}
+				else
+				{
+					dateTime = formatter.parseDateTime(rs.getString("min"));
+				}
 			}
 		}
 		catch(SQLException e)
@@ -101,36 +149,35 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 
 		return dateTime;
 	}
 
 	public int getRestForAllPreviousMonths(int year, int month)
-	{		
+	{
+		DateTimeFormatter formatter = DateTimeFormat.forPattern("MM.yyyy");
+		String dateString = String.valueOf(month) + "." + year;
+		DateTime currentDate = formatter.parseDateTime(dateString);
+
 		DateTime firstNormalPaymentDate = getFirstNormalPaymentDate();
+		if(firstNormalPaymentDate == null)
+		{
+			firstNormalPaymentDate = currentDate;
+		}
 		DateTime firstRepeatingPaymentDate = getFirstRepeatingPaymentDate();
-		
+		if(firstRepeatingPaymentDate == null)
+		{
+			firstRepeatingPaymentDate = currentDate;
+		}
+
 		DateTime firstDate = firstNormalPaymentDate;
 		if(firstRepeatingPaymentDate.isBefore(firstNormalPaymentDate))
 		{
 			firstDate = firstRepeatingPaymentDate;
 		}
-		
-		DateTimeFormatter formatter = DateTimeFormat.forPattern("MM.yyyy");
-		String dateString = String.valueOf(month) + "." + year;
-		DateTime currentDate = formatter.parseDateTime(dateString);//	
-	
+
 		if(firstDate.isAfter(currentDate))
 		{
 			return 0;
@@ -139,10 +186,10 @@ public class DatabaseHandler
 		int startYear = firstDate.getYear();
 		int startMonth = firstDate.getMonthOfYear();
 		int totalRest = 0;
-		
+
 		while(startYear < year || startMonth < month)
 		{
-			totalRest += getRest(startYear, startMonth);			
+			totalRest += getRest(startYear, startMonth);
 
 			startMonth++;
 			if(startMonth > 12)
@@ -159,13 +206,13 @@ public class DatabaseHandler
 		ArrayList<Payment> payments = new ArrayList<>();
 		payments.addAll(getPayments(year, month));
 		payments.addAll(getRepeatingPayments(year, month));
-		
+
 		int rest = 0;
 		for(Payment currentPayment : payments)
 		{
 			rest += currentPayment.getAmount();
 		}
-		
+
 		return rest;
 	}
 
@@ -193,30 +240,21 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 
 		return results;
 	}
-	
+
 	public Category getCategory(int ID)
 	{
 		Statement stmt = null;
-		String query = "SELECT * FROM category WHERE category.ID = " + ID;	
+		String query = "SELECT * FROM category WHERE category.ID = " + ID;
 		Category result = null;
 		try
 		{
 			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);			
+			ResultSet rs = stmt.executeQuery(query);
 			while(rs.next())
 			{
 				int id = rs.getInt("ID");
@@ -232,21 +270,71 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
+			closeConnection(stmt);
+		}
+
+		return result;
+	}
+	
+	public Category getCategory(String name, Color color)
+	{
+		Statement stmt = null;
+		String query = "SELECT * FROM category WHERE category.name = \"" + name + "\" AND category.color = \"" + ConvertTo.toRGBHexWithoutOpacity(color) + "\";";
+		Category result = null;
+		try
+		{
+			stmt = connection.createStatement();
+			ResultSet rs = stmt.executeQuery(query);
+			while(rs.next())
+			{
+				int id = rs.getInt("ID");
+				String categoryName = rs.getString("Name");
+				String categoryColor = rs.getString("Color");
+
+				result = new Category(id, categoryName, Color.web(categoryColor));
+			}
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			closeConnection(stmt);
+		}
+
+		return result;
+	}
+	
+	public boolean categoryExists(int ID)
+	{
+		Statement stmt = null;
+		String query = "SELECT COUNT(ID) as \"count\" FROM category WHERE category.ID = " + ID;
+		boolean exists = false;
+		try
+		{
+			stmt = connection.createStatement();
+			ResultSet rs = stmt.executeQuery(query);
+			while(rs.next())
 			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
+				if(rs.getInt("count") > 0)
 				{
+					exists = true;
 				}
 			}
 		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			closeConnection(stmt);
+		}
 
-		return result;
+		return exists;
 	}
-	
+
 	public NormalPayment getPayment(int ID)
 	{
 		Statement stmt = null;
@@ -274,16 +362,7 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 
 		return null;
@@ -294,6 +373,41 @@ public class DatabaseHandler
 		Statement stmt = null;
 		String query = "SELECT * FROM payment WHERE YEAR(Date) = " + year + " AND  MONTH(Date) = " + month;
 
+		ArrayList<NormalPayment> results = new ArrayList<>();
+		try
+		{
+			stmt = connection.createStatement();
+			ResultSet rs = stmt.executeQuery(query);
+
+			while(rs.next())
+			{
+				int resultID = rs.getInt("ID");
+				String name = rs.getString("Name");
+				int amount = rs.getInt("amount");
+				String date = rs.getString("Date");
+				int categoryID = rs.getInt("CategoryID");
+				String description = rs.getString("Description");
+
+				results.add(new NormalPayment(resultID, amount, date, categoryID, name, description));
+			}
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			closeConnection(stmt);
+		}
+
+		return results;
+	}
+	
+	public ArrayList<NormalPayment> getPaymentsBetween(String startDate, String endDate)
+	{	
+		Statement stmt = null;
+		String query = "SELECT * FROM payment WHERE DATE(Date) BETWEEN '" + startDate + "' AND '" + endDate + "';";
+
 		ArrayList<NormalPayment> results = new ArrayList<>();
 		try
 		{
@@ -318,16 +432,7 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 
 		return results;
@@ -336,7 +441,47 @@ public class DatabaseHandler
 	public ArrayList<RepeatingPaymentEntry> getRepeatingPayments(int year, int month)
 	{
 		Statement stmt = null;
-		String query = "SELECT repeating_entry.ID, repeating_entry.RepeatingPaymentID, repeating_entry.Date, repeating_payment.Name, repeating_payment.CategoryID, repeating_payment.Amount, repeating_payment.RepeatInterval, repeating_payment.RepeatEndDate, repeating_payment.RepeatMonthDay, repeating_payment.Description FROM repeating_entry, repeating_payment WHERE repeating_entry.RepeatingPaymentID = repeating_payment.ID AND YEAR(repeating_entry.Date) = " + year + " AND MONTH(repeating_entry.Date) = " + month;
+		String query = "SELECT repeating_entry.ID, repeating_entry.RepeatingPaymentID, repeating_entry.Date, repeating_payment.Name, repeating_payment.CategoryID, repeating_payment.Amount, repeating_payment.RepeatInterval, repeating_payment.RepeatEndDate, repeating_payment.RepeatMonthDay, repeating_payment.Description FROM repeating_entry, repeating_payment WHERE repeating_entry.RepeatingPaymentID = repeating_payment.ID AND YEAR(repeating_entry.Date) = "
+				+ year + " AND MONTH(repeating_entry.Date) = " + month;
+
+		ArrayList<RepeatingPaymentEntry> results = new ArrayList<>();
+		try
+		{
+			stmt = connection.createStatement();
+			ResultSet rs = stmt.executeQuery(query);
+
+			while(rs.next())
+			{
+				int resultID = rs.getInt("ID");
+				int repeatingPaymentID = rs.getInt("repeatingPaymentID");
+				String name = rs.getString("Name");
+				String description = rs.getString("Description");
+				int amount = rs.getInt("amount");
+				String date = rs.getString("Date");
+				int categoryID = rs.getInt("CategoryID");
+				int repeatInterval = rs.getInt("RepeatInterval");
+				String repeatEndDate = rs.getString("RepeatEndDate");
+				int repeatMonthDay = rs.getInt("RepeatMonthDay");
+
+				results.add(new RepeatingPaymentEntry(resultID, repeatingPaymentID, date, amount, categoryID, name, description, repeatInterval, repeatEndDate, repeatMonthDay));
+			}
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			closeConnection(stmt);
+		}
+
+		return results;
+	}
+	
+	public ArrayList<RepeatingPaymentEntry> getRepeatingPaymentsBetween(String startDate, String endDate)
+	{
+		Statement stmt = null;
+		String query = "SELECT repeating_entry.ID, repeating_entry.RepeatingPaymentID, repeating_entry.Date, repeating_payment.Name, repeating_payment.CategoryID, repeating_payment.Amount, repeating_payment.RepeatInterval, repeating_payment.RepeatEndDate, repeating_payment.RepeatMonthDay, repeating_payment.Description FROM repeating_entry, repeating_payment WHERE repeating_entry.RepeatingPaymentID = repeating_payment.ID AND DATE(repeating_entry.Date) BETWEEN '" + startDate + "' AND '" + endDate + "';";
 
 		ArrayList<RepeatingPaymentEntry> results = new ArrayList<>();
 		try
@@ -366,23 +511,14 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 
 		return results;
 	}
-	
+
 	public ArrayList<RepeatingPayment> getAllRepeatingPayments()
-	{		
+	{
 		Statement stmt = null;
 		String query = "SELECT * FROM repeating_payment;";
 
@@ -394,15 +530,15 @@ public class DatabaseHandler
 
 			while(rs.next())
 			{
-				int resultID = rs.getInt("ID");				
+				int resultID = rs.getInt("ID");
 				String name = rs.getString("Name");
 				int amount = rs.getInt("amount");
-				String date = rs.getString("Date");		
+				String date = rs.getString("Date");
 				String description = rs.getString("Description");
 				int categoryID = rs.getInt("CategoryID");
 				int repeatInterval = rs.getInt("RepeatInterval");
 				String repeatEndDate = rs.getString("RepeatEndDate");
-				int repeatMonthDay = rs.getInt("RepeatMonthDay");			
+				int repeatMonthDay = rs.getInt("RepeatMonthDay");
 
 				results.add(new RepeatingPayment(resultID, amount, date, categoryID, name, description, repeatInterval, repeatEndDate, repeatMonthDay));
 			}
@@ -413,21 +549,12 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 
 		return results;
 	}
-	
+
 	public ArrayList<LatestRepeatingPayment> getLatestRepeatingPaymentEntries()
 	{
 		Statement stmt = null;
@@ -442,9 +569,9 @@ public class DatabaseHandler
 			while(rs.next())
 			{
 				int resultID = rs.getInt("ID");
-				int repeatingPaymentID = rs.getInt("repeatingPaymentID");				
+				int repeatingPaymentID = rs.getInt("repeatingPaymentID");
 				String date = rs.getString("LastDate");
-			
+
 				results.add(new LatestRepeatingPayment(resultID, repeatingPaymentID, date));
 			}
 		}
@@ -454,33 +581,24 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 
 		return results;
 	}
-	
+
 	public RepeatingPayment getRepeatingPayment(int ID)
 	{
 		Statement stmt = null;
-		String query = "SELECT * FROM repeating_payment WHERE ID = " + ID;	
+		String query = "SELECT * FROM repeating_payment WHERE ID = " + ID;
 		RepeatingPayment result = null;
 		try
 		{
 			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);			
+			ResultSet rs = stmt.executeQuery(query);
 			while(rs.next())
 			{
-				int id = rs.getInt("ID");				
+				int id = rs.getInt("ID");
 				int amount = rs.getInt("amount");
 				String date = rs.getString("Date");
 				int categoryID = rs.getInt("CategoryID");
@@ -499,16 +617,7 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 
 		return result;
@@ -532,19 +641,10 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 	}
-	
+
 	public void deletePayment(int ID)
 	{
 		Statement stmt = null;
@@ -560,19 +660,10 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 	}
-	
+
 	public void deleteRepeatingPayment(int ID)
 	{
 		Statement stmt = null;
@@ -588,16 +679,38 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
+		}
+	}
+
+	public void deleteDatabase()
+	{
+		Statement stmt = null;
+		String tableCategory = "DROP TABLE IF EXISTS category;";
+		String tablePayment = "DROP TABLE IF EXISTS payment;";
+		String tableRepeatingPayment = "DROP TABLE IF EXISTS repeating_payment;";
+		String tableRepeatingEntry = "DROP TABLE IF EXISTS repeating_entry;";
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute("SET FOREIGN_KEY_CHECKS = 0;");
+			stmt.execute(tableCategory);
+			Logger.info("Deleted table: category");
+			stmt.execute(tablePayment);
+			Logger.info("Deleted table: payment");
+			stmt.execute(tableRepeatingPayment);
+			Logger.info("Deleted table: repeating_payment");
+			stmt.execute(tableRepeatingEntry);
+			Logger.info("Deleted table: repeating_entry");
+			stmt.execute("SET FOREIGN_KEY_CHECKS = 1;");
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			closeConnection(stmt);
 		}
 	}
 
@@ -619,16 +732,26 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
+		}
+	}
+
+	public void importCategory(Category category)
+	{
+		Statement stmt = null;
+		String query = "INSERT INTO category (ID, Name, Color) VALUES('" + category.getID() + "', '" + category.getName() + "' , '" + ConvertTo.toRGBHexWithoutOpacity(category.getColor()) + "');";
+		try
+		{
+			stmt = connection.createStatement();
+			stmt.execute(query);
+		}
+		catch(SQLException e)
+		{
+			Logger.error(e);
+		}
+		finally
+		{
+			closeConnection(stmt);
 		}
 	}
 
@@ -647,33 +770,27 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 	}
-	
+
 	public void addRepeatingPayment(int amount, String date, int categoryID, String name, String description, int repeatInterval, String repeatEndDate, int repeatMonthDay)
 	{
 		Statement stmt = null;
-		String query;		
-		//A is placeholder for empty repeatEndDate
-		if(repeatEndDate.equals("A") || repeatEndDate == null)
-		{			
-			query = "INSERT INTO repeating_payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay, Description) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "' , '" + repeatInterval + "' , NULL , '" + repeatMonthDay + "' , '" + description + "');";
+		String query;
+		String correctRepeatEndDate = repeatEndDate;
+		if(correctRepeatEndDate == null || correctRepeatEndDate.equals("A"))
+		{
+			correctRepeatEndDate = "NULL";
 		}
 		else
 		{
-			query = "INSERT INTO repeating_payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay, Description) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "' , '" + repeatInterval + "' , '" + repeatEndDate + "' , '" + repeatMonthDay + "' , '" + description + "');";
+			correctRepeatEndDate = "'" + correctRepeatEndDate + "'";
 		}
-		
+
+		query = "INSERT INTO repeating_payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay, Description) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "' , '" + repeatInterval + "' , " + correctRepeatEndDate + " , '" + repeatMonthDay
+				+ "' , '" + description + "');";
+
 		try
 		{
 			stmt = connection.createStatement();
@@ -685,24 +802,15 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 	}
 	
 	public void addRepeatingPaymentEntry(int repeatingPaymentID, String date)
 	{
 		Statement stmt = null;
-		String query;		
-		query = "INSERT INTO repeating_entry (RepeatingPaymentID, Date) VALUES('" +  repeatingPaymentID + "' , '" + date + "');";
+		String query;
+		query = "INSERT INTO repeating_entry (RepeatingPaymentID, Date) VALUES('" + repeatingPaymentID + "' , '" + date + "');";
 		try
 		{
 			stmt = connection.createStatement();
@@ -714,16 +822,7 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 	}
 
@@ -745,19 +844,10 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
-	}	
-	
+	}
+
 	public void updateNormalPayment(int ID, int amount, String date, int categoryID, String name, String description)
 	{
 		Statement stmt = null;
@@ -773,16 +863,7 @@ public class DatabaseHandler
 		}
 		finally
 		{
-			if(stmt != null)
-			{
-				try
-				{
-					stmt.close();
-				}
-				catch(SQLException e)
-				{
-				}
-			}
+			closeConnection(stmt);
 		}
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/logic/DatabaseImporter.java b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseImporter.java
new file mode 100644
index 0000000000000000000000000000000000000000..7880c9c2dd7d0e1c3e61989d371114f79458b713
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseImporter.java
@@ -0,0 +1,107 @@
+package de.deadlocker8.budgetmasterserver.logic;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+
+public class DatabaseImporter
+{
+	private DatabaseHandler handler;
+	private ArrayList<Category> categories;
+	private ArrayList<NormalPayment> normalPayments;
+	private ArrayList<RepeatingPayment> repeatingPayments;
+	private ArrayList<NormalPayment> changedNormalPayments;
+	private ArrayList<RepeatingPayment> changedRepeatingPayments;
+	
+	public DatabaseImporter(DatabaseHandler handler) throws IllegalStateException
+    {
+        this.handler = handler;
+    }
+	
+	public void importDatabase(Database database)
+	{		
+		this.categories = database.getCategories();
+		this.normalPayments = database.getNormalPayments();
+		this.repeatingPayments = database.getRepeatingPayments();	
+		this.changedNormalPayments = new ArrayList<>();
+		this.changedRepeatingPayments = new ArrayList<>();
+		
+		importAll();	
+	}
+	
+	private void importAll()
+	{	   	
+        for(Category currentCategory : categories)
+        {
+        	Category existingCategory = handler.getCategory(currentCategory.getName(), currentCategory.getColor());
+        	if(existingCategory == null)
+        	{
+        		handler.addCategory(currentCategory.getName(), currentCategory.getColor());
+        		int newID = handler.getLastInsertID();
+        		
+        		updatePayments(currentCategory.getID(), newID);
+        	}
+        	else
+        	{
+        		updatePayments(currentCategory.getID(), existingCategory.getID()); 
+        	}
+        }
+        
+        //merge changed and remaining payments
+        normalPayments.addAll(changedNormalPayments);
+        repeatingPayments.addAll(changedRepeatingPayments);
+        
+        importNormalPayments(normalPayments);
+        importRepeatingPayments(repeatingPayments);
+	}
+	
+	private void updatePayments(int oldID, int newID)
+	{
+		//check normal payments for old category ID
+		Iterator<NormalPayment> iterator = normalPayments.iterator();        		
+		while(iterator.hasNext())
+		{
+			NormalPayment currentPayment = iterator.next();
+			if(currentPayment.getCategoryID() == oldID)
+			{
+				currentPayment.setCategoryID(newID);
+				//remove payment from list to avoid overriding category ID again in the future
+				changedNormalPayments.add(currentPayment);
+				iterator.remove();
+			}
+		}
+		
+		//check repeating payments for old category ID
+		Iterator<RepeatingPayment> iterator2 = repeatingPayments.iterator();        		
+		while(iterator2.hasNext())
+		{
+			RepeatingPayment currentPayment = iterator2.next();
+			if(currentPayment.getCategoryID() == oldID)
+			{
+				currentPayment.setCategoryID(newID);
+				//remove payment from list to avoid overriding category ID again in the future
+				changedRepeatingPayments.add(currentPayment);
+				iterator2.remove();
+			}
+		}
+	}
+		
+	private void importNormalPayments(ArrayList<NormalPayment> normalPayments)
+    {      
+		for(NormalPayment currentPayment : normalPayments)
+        {
+        	handler.addNormalPayment(currentPayment.getAmount(), currentPayment.getDate(), currentPayment.getCategoryID(), currentPayment.getName(), currentPayment.getDescription());
+        }
+    }
+	
+	private void importRepeatingPayments(ArrayList<RepeatingPayment> repeatingPayments)
+    {      
+		for(RepeatingPayment currentPayment : repeatingPayments)
+        {
+        	handler.addRepeatingPayment(currentPayment.getAmount(), currentPayment.getDate(), currentPayment.getCategoryID(), currentPayment.getName(), currentPayment.getDescription(), currentPayment.getRepeatInterval(), currentPayment.getRepeatEndDate(), currentPayment.getRepeatMonthDay());
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/main/Settings.java b/src/de/deadlocker8/budgetmasterserver/logic/Settings.java
similarity index 96%
rename from src/de/deadlocker8/budgetmasterserver/main/Settings.java
rename to src/de/deadlocker8/budgetmasterserver/logic/Settings.java
index 1dbc26be8a1cacc8e1ecedba6a2216ec604b3d8b..121ba938b3b45f8ab641e1b267e2b896a5777491 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/Settings.java
+++ b/src/de/deadlocker8/budgetmasterserver/logic/Settings.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmasterserver.main;
+package de.deadlocker8.budgetmasterserver.logic;
 
 public class Settings
 {
diff --git a/src/de/deadlocker8/budgetmasterserver/logic/Utils.java b/src/de/deadlocker8/budgetmasterserver/logic/Utils.java
new file mode 100644
index 0000000000000000000000000000000000000000..265ab169df0cec23bb18cc16c6ebd9e87a9fa639
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/logic/Utils.java
@@ -0,0 +1,23 @@
+package de.deadlocker8.budgetmasterserver.logic;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import com.google.gson.Gson;
+
+public class Utils
+{
+	public static Settings loadSettings() throws IOException, URISyntaxException
+	{
+		String settingsJSON;
+		Settings settings;
+		
+		Gson gson = new Gson();
+		
+		settingsJSON = new String(Files.readAllBytes(Paths.get(Settings.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent().resolve("settings.json")));		
+		settings = gson.fromJson(settingsJSON, Settings.class);	
+		return settings;		
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/main/Main.java b/src/de/deadlocker8/budgetmasterserver/main/Main.java
index 995f4e11b3ccfab77f7dd22b9c487ad83b414c3a..38a523850192a9d3ca547d8d454c82aa69c1ba55 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/Main.java
+++ b/src/de/deadlocker8/budgetmasterserver/main/Main.java
@@ -4,11 +4,15 @@ import java.io.File;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.nio.file.Files;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Locale;
 import java.util.ResourceBundle;
 
+import de.deadlocker8.budgetmasterserver.logic.Settings;
+import de.deadlocker8.budgetmasterserver.logic.Utils;
 import de.deadlocker8.budgetmasterserver.server.SparkServer;
+import logger.FileOutputMode;
 import logger.LogLevel;
 import logger.Logger;
 
@@ -22,35 +26,44 @@ public class Main
 		Logger.appInfo(bundle.getString("app.name"), bundle.getString("version.name"), bundle.getString("version.code"), bundle.getString("version.date"));
 		try
 		{
-			File logFile = new File(Paths.get(SparkServer.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent().toFile() + "/error.log");
-			Logger.enableFileOutput(logFile);
+			File logFolder = Paths.get(SparkServer.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent().toFile();
+			Logger.enableFileOutput(logFolder, System.out, System.err, FileOutputMode.COMBINED);
 		}
 		catch(URISyntaxException e1)
 		{
 			Logger.error(e1);
-		}		
+		}	
 		
-		if(!Files.exists(Paths.get("settings.json")))
+		try
 		{
+			Path settingsPath = Paths.get(Settings.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getParent().resolve("settings.json");
+			
+			if(!Files.exists(settingsPath))
+			{
+				try
+				{
+					Files.copy(SparkServer.class.getClassLoader().getResourceAsStream("de/deadlocker8/budgetmasterserver/resources/settings.json"), settingsPath);
+				}
+				catch(IOException e)
+				{
+					Logger.error(e);
+				}
+			}
+
+			Settings settings;
 			try
 			{
-				Files.copy(SparkServer.class.getClassLoader().getResourceAsStream("de/deadlocker8/budgetmasterserver/resources/settings.json"), Paths.get("settings.json"));
+				settings = Utils.loadSettings();
+				new SparkServer(settings);
 			}
-			catch(IOException e)
+			catch(IOException | URISyntaxException e)
 			{
 				Logger.error(e);
 			}
 		}
-
-		Settings settings;
-		try
-		{
-			settings = Utils.loadSettings();
-			new SparkServer(settings);
-		}
-		catch(IOException e)
-		{
-			Logger.error(e);
-		}
+		catch(URISyntaxException e1)
+		{			
+			Logger.error(e1);			
+		}		
 	}
-}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/main/Utils.java b/src/de/deadlocker8/budgetmasterserver/main/Utils.java
deleted file mode 100644
index 417375ffc23b3164fd3e54bbb54fc37c73534438..0000000000000000000000000000000000000000
--- a/src/de/deadlocker8/budgetmasterserver/main/Utils.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package de.deadlocker8.budgetmasterserver.main;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-import com.google.gson.Gson;
-
-public class Utils
-{
-	public static Settings loadSettings() throws IOException
-	{
-		String settingsJSON;
-		Settings settings;
-		
-		Gson gson = new Gson();
-		settingsJSON = new String(Files.readAllBytes(Paths.get("settings.json")));		
-		settings = gson.fromJson(settingsJSON, Settings.class);	
-		return settings;		
-	}
-}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/main/_de.properties b/src/de/deadlocker8/budgetmasterserver/main/_de.properties
index b231f1d78f4e46819869a44ca52fbc7a2efe6b88..a3d8467008e914df260865c3283be6d831e09e01 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/_de.properties
+++ b/src/de/deadlocker8/budgetmasterserver/main/_de.properties
@@ -1,5 +1,5 @@
 app.name=BudgetMasterServer
-version.code=2
-version.name=1.1.0
-version.date=12.04.17
+version.code=3
+version.name=1.2.0
+version.date=25.05.17
 author=Robert Goldmann
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java b/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java
index 760e6fb7424d0554da7e51d061f5606d4114d328..b2389dd932e79e399f09272e5140ae9d2b87e3e3 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java
@@ -17,14 +17,20 @@ import org.joda.time.DateTime;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
-import de.deadlocker8.budgetmasterserver.main.Settings;
+import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.Settings;
 import de.deadlocker8.budgetmasterserver.server.category.CategoryAdd;
 import de.deadlocker8.budgetmasterserver.server.category.CategoryDelete;
 import de.deadlocker8.budgetmasterserver.server.category.CategoryGet;
 import de.deadlocker8.budgetmasterserver.server.category.CategoryGetAll;
 import de.deadlocker8.budgetmasterserver.server.category.CategoryUpdate;
 import de.deadlocker8.budgetmasterserver.server.categorybudget.CategoryBudgetGet;
+import de.deadlocker8.budgetmasterserver.server.charts.CategoryInOutSumForMonth;
+import de.deadlocker8.budgetmasterserver.server.charts.MonthInOutSum;
+import de.deadlocker8.budgetmasterserver.server.database.DatabaseDelete;
+import de.deadlocker8.budgetmasterserver.server.database.DatabaseExport;
+import de.deadlocker8.budgetmasterserver.server.database.DatabaseImport;
 import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentAdd;
 import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentDelete;
 import de.deadlocker8.budgetmasterserver.server.payment.normal.PaymentGet;
@@ -38,6 +44,7 @@ import de.deadlocker8.budgetmasterserver.server.updater.RepeatingPaymentUpdater;
 import logger.Logger;
 import spark.Spark;
 import spark.route.RouteOverview;
+import tools.HashUtils;
 
 public class SparkServer
 {	
@@ -77,7 +84,7 @@ public class SparkServer
 
 			String clientSecret = request.queryMap("secret").value();
 
-			if(clientSecret == null || !clientSecret.equals(settings.getServerSecret()))
+			if(clientSecret == null || !clientSecret.equals(HashUtils.hash(settings.getServerSecret(), Helpers.SALT)))
 			{
 				halt(401, "Unauthorized");
 			}
@@ -109,7 +116,16 @@ public class SparkServer
 		get("/categorybudget", new CategoryBudgetGet(handler, gson));
 		
 		// Rest
-		get("/rest", new RestGet(handler, gson));
+		get("/rest", new RestGet(handler, gson));		
+
+		//charts
+		get("/charts/categoryInOutSum", new CategoryInOutSumForMonth(handler, gson));
+		get("/charts/monthInOutSum", new MonthInOutSum(handler, gson));
+
+		// Database
+		get("/database", new DatabaseExport(settings, gson));
+		post("/database", new DatabaseImport(handler, gson));
+		delete("/database", new DatabaseDelete(handler, settings));
 
 		after((request, response) -> {
 			new RepeatingPaymentUpdater(handler).updateRepeatingPayments(DateTime.now());
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java
index c20739e619a6090aacd41e94d79ef9178600cbca..71e5dcac445853179abdf3aa35ed2cff6c1ae875 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryAdd.java
@@ -2,7 +2,7 @@ package de.deadlocker8.budgetmasterserver.server.category;
 
 import static spark.Spark.halt;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import javafx.scene.paint.Color;
 import spark.Request;
 import spark.Response;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java
index 3a0088e2a9205c1d5b786d0b6e9782b3a3d1edca..5e4ad5a6958cf02678651d6e06a0e25e08311980 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryDelete.java
@@ -2,7 +2,7 @@ package de.deadlocker8.budgetmasterserver.server.category;
 
 import static spark.Spark.halt;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java
index 55953ad73dd19db8f21cc266fc44908d3b4d6041..bf4eb9c41614aff11d4b2173893822656b86a3e3 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGet.java
@@ -5,7 +5,7 @@ import static spark.Spark.halt;
 import com.google.gson.Gson;
 
 import de.deadlocker8.budgetmaster.logic.Category;
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java
index 75a921947320ca5ff99c070aeabaf8441a89cd08..8bb67cab65a1a3fb7346ef9cc3e9139ef099f18e 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryGetAll.java
@@ -7,7 +7,7 @@ import java.util.ArrayList;
 import com.google.gson.Gson;
 
 import de.deadlocker8.budgetmaster.logic.Category;
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java
index 315199436e410d4d7c8bfd114fa030ae6d033e33..a8f4d65dddc92caae6953173d6b0c6a367799a0f 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/category/CategoryUpdate.java
@@ -2,7 +2,7 @@ package de.deadlocker8.budgetmasterserver.server.category;
 
 import static spark.Spark.halt;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import javafx.scene.paint.Color;
 import spark.Request;
 import spark.Response;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java b/src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java
index 0b0859c69771c6405bf01921b09e09928f6ea535..26504559b0cd744843a9c32b574bb039cdfe1c9d 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/categorybudget/CategoryBudgetGet.java
@@ -12,7 +12,7 @@ import com.google.gson.Gson;
 import de.deadlocker8.budgetmaster.logic.Category;
 import de.deadlocker8.budgetmaster.logic.CategoryBudget;
 import de.deadlocker8.budgetmaster.logic.Payment;
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
@@ -54,14 +54,7 @@ public class CategoryBudgetGet implements Route
 				ArrayList<Payment> payments = new ArrayList<>();
 				payments.addAll(handler.getPayments(year, month));
 				payments.addAll(handler.getRepeatingPayments(year, month));			
-				Collections.sort(payments, new Comparator<Payment>() {
-			        @Override
-			        public int compare(Payment payment1, Payment payment2)
-			        {
-			            return  payment2.getDate().compareTo(payment1.getDate());
-			        }
-			    });	
-				
+			
 				ArrayList<CategoryBudget> budgets = new ArrayList<>();
 				
 				for(Category currentCategory : handler.getCategories())
diff --git a/src/de/deadlocker8/budgetmasterserver/server/charts/CategoryInOutSumForMonth.java b/src/de/deadlocker8/budgetmasterserver/server/charts/CategoryInOutSumForMonth.java
new file mode 100644
index 0000000000000000000000000000000000000000..067567b4a9658742dc33d19a70c0840a5d0b9d58
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/charts/CategoryInOutSumForMonth.java
@@ -0,0 +1,74 @@
+package de.deadlocker8.budgetmasterserver.server.charts;
+
+import static spark.Spark.halt;
+
+import java.util.ArrayList;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
+import de.deadlocker8.budgetmaster.logic.Payment;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class CategoryInOutSumForMonth implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+
+	public CategoryInOutSumForMonth(DatabaseHandler handler, Gson gson)
+	{
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("startDate") || !req.queryParams().contains("endDate"))
+		{
+			halt(400, "Bad Request");
+		}		
+	
+		try
+		{	
+			ArrayList<Payment> payments = new ArrayList<>();
+			payments.addAll(handler.getPaymentsBetween(req.queryMap("startDate").value(), req.queryMap("endDate").value()));
+			payments.addAll(handler.getRepeatingPaymentsBetween(req.queryMap("startDate").value(), req.queryMap("endDate").value()));	
+			
+			ArrayList<CategoryInOutSum> inOutSums = new ArrayList<>();
+			
+			for(Category currentCategory : handler.getCategories())
+			{					
+				inOutSums.add(new CategoryInOutSum(currentCategory.getID(), currentCategory.getName(), currentCategory.getColor(), 0, 0));
+				CategoryInOutSum currentInOutSum = inOutSums.get(inOutSums.size() - 1);
+				for(Payment currentPayment : payments)
+				{					
+					if(currentCategory.getID() == currentPayment.getCategoryID())
+					{
+						int amount = currentPayment.getAmount();
+						if(amount > 0)
+						{
+							currentInOutSum.setBudgetIN(currentInOutSum.getBudgetIN() + amount);
+						}
+						else
+						{
+							currentInOutSum.setBudgetOUT(currentInOutSum.getBudgetOUT() + amount);
+						}
+					}						
+				}
+			}
+				
+			return gson.toJson(inOutSums);
+		}
+		catch(IllegalStateException ex)
+		{
+			halt(500, "Internal Server Error");
+		}		
+		
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/charts/MonthInOutSum.java b/src/de/deadlocker8/budgetmasterserver/server/charts/MonthInOutSum.java
new file mode 100644
index 0000000000000000000000000000000000000000..452e9acdffb3c820c9dff64d7600796659edb1ce
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/charts/MonthInOutSum.java
@@ -0,0 +1,88 @@
+package de.deadlocker8.budgetmasterserver.server.charts;
+
+import static spark.Spark.halt;
+
+import java.util.ArrayList;
+
+import org.joda.time.DateTime;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
+import de.deadlocker8.budgetmaster.logic.Payment;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class MonthInOutSum implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+
+	public MonthInOutSum(DatabaseHandler handler, Gson gson)
+	{
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		if(!req.queryParams().contains("startDate") || !req.queryParams().contains("endDate"))
+		{
+			halt(400, "Bad Request");
+		}		
+	
+		try
+		{				
+			DateTime startDate = DateTime.parse(req.queryMap("startDate").value()).withDayOfMonth(1);
+			DateTime endDate = DateTime.parse(req.queryMap("endDate").value()).withDayOfMonth(1);		
+			
+			ArrayList<de.deadlocker8.budgetmaster.logic.MonthInOutSum> monthInOutSums = new ArrayList<>();
+			
+			while(startDate.isBefore(endDate) || startDate.isEqual(endDate))
+			{
+				ArrayList<Payment> currentMonthPayments = new ArrayList<>();
+				currentMonthPayments.addAll(handler.getPayments(startDate.getYear(), startDate.getMonthOfYear()));
+				currentMonthPayments.addAll(handler.getRepeatingPayments(startDate.getYear(), startDate.getMonthOfYear()));		
+				
+				ArrayList<CategoryInOutSum> sums = new ArrayList<>();
+				
+				for(Category currentCategory : handler.getCategories())
+				{					
+					sums.add(new CategoryInOutSum(currentCategory.getID(), currentCategory.getName(), currentCategory.getColor(), 0, 0));
+					CategoryInOutSum currentInOutSum = sums.get(sums.size() - 1);
+					for(Payment currentPayment : currentMonthPayments)
+					{					
+						if(currentCategory.getID() == currentPayment.getCategoryID())
+						{
+							int amount = currentPayment.getAmount();
+							if(amount > 0)
+							{
+								currentInOutSum.setBudgetIN(currentInOutSum.getBudgetIN() + amount);
+							}
+							else
+							{
+								currentInOutSum.setBudgetOUT(currentInOutSum.getBudgetOUT() + amount);
+							}
+						}						
+					}
+				}
+				
+				monthInOutSums.add(new de.deadlocker8.budgetmaster.logic.MonthInOutSum(startDate.getMonthOfYear(), startDate.getYear(), sums));				
+				
+				startDate = startDate.plusMonths(1);
+			}	
+		
+			return gson.toJson(monthInOutSums);
+		}
+		catch(IllegalStateException ex)
+		{
+			halt(500, "Internal Server Error");
+		}		
+		
+		return null;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseDelete.java b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseDelete.java
new file mode 100644
index 0000000000000000000000000000000000000000..373a788ade424ea1cbb62c35632a58a82efbcc6a
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseDelete.java
@@ -0,0 +1,39 @@
+package de.deadlocker8.budgetmasterserver.server.database;
+
+import static spark.Spark.halt;
+
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.Settings;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class DatabaseDelete implements Route
+{
+	private DatabaseHandler handler;
+	private Settings settings;
+	
+	public DatabaseDelete(DatabaseHandler handler, Settings settings)
+	{	
+		this.handler = handler;
+		this.settings = settings;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{		
+		try
+		{							
+			handler.deleteDatabase();
+			handler = new DatabaseHandler(settings);
+	
+			return "";
+		}
+		catch(IllegalStateException ex)
+		{
+			halt(500, "Internal Server Error");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java
new file mode 100644
index 0000000000000000000000000000000000000000..5205de6f69fdc68ff3988e23ab85e2502fe18422
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseExport.java
@@ -0,0 +1,41 @@
+package de.deadlocker8.budgetmasterserver.server.database;
+
+import static spark.Spark.halt;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmasterserver.logic.DatabaseExporter;
+import de.deadlocker8.budgetmasterserver.logic.Settings;
+import logger.Logger;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class DatabaseExport implements Route
+{
+	private Settings settings;
+	private Gson gson;
+
+	public DatabaseExport(Settings settings, Gson gson)
+	{
+		this.settings = settings;
+		this.gson = gson;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{
+		try
+		{	
+		    DatabaseExporter exporter = new DatabaseExporter(settings);	
+			return gson.toJson(exporter.exportDatabase());
+		}
+		catch(Exception e)
+		{
+		    Logger.error(e);
+			halt(500, "Internal Server Error");
+		}		
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java
new file mode 100644
index 0000000000000000000000000000000000000000..082e938ae41446f8814edddfb8c825f55f0af685
--- /dev/null
+++ b/src/de/deadlocker8/budgetmasterserver/server/database/DatabaseImport.java
@@ -0,0 +1,47 @@
+package de.deadlocker8.budgetmasterserver.server.database;
+
+import static spark.Spark.halt;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmasterserver.logic.Database;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseImporter;
+import logger.Logger;
+import spark.Request;
+import spark.Response;
+import spark.Route;
+
+public class DatabaseImport implements Route
+{
+	private DatabaseHandler handler;
+	private Gson gson;
+
+	public DatabaseImport(DatabaseHandler handler, Gson gson)
+	{
+		this.handler = handler;
+		this.gson = gson;
+	}
+
+	@Override
+	public Object handle(Request req, Response res) throws Exception
+	{	
+		String databaseJSON = req.body();		
+		
+		try
+		{
+			Database database = gson.fromJson(databaseJSON, Database.class);
+
+			DatabaseImporter importer = new DatabaseImporter(handler);
+			importer.importDatabase(database);
+			return "";
+		}
+		catch(Exception e)
+		{
+			Logger.error(e);
+			halt(500, "Internal Server Error");
+		}
+		
+		return "";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java
index 7a6bd99a68ba75c9e2a2f1f9d63ee63724359c7d..9d016915dc8eeb91a1575b480fc3549a7bd5b66b 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentAdd.java
@@ -2,7 +2,7 @@ package de.deadlocker8.budgetmasterserver.server.payment.normal;
 
 import static spark.Spark.halt;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java
index 0933a3ba5a32f45ea6f1edc0cbaf577efe2f9083..f5ff9285872dff0339bd02a6c15c787d0cb8f4d6 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentDelete.java
@@ -2,7 +2,7 @@ package de.deadlocker8.budgetmasterserver.server.payment.normal;
 
 import static spark.Spark.halt;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java
index 967cbae9fd99ba3e79197632bbb03a1fb4fe052d..b13dba89e08a7832ea8c0b152b2a5042899ea260 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentGet.java
@@ -9,7 +9,7 @@ import org.joda.time.DateTime;
 import com.google.gson.Gson;
 
 import de.deadlocker8.budgetmaster.logic.NormalPayment;
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import de.deadlocker8.budgetmasterserver.server.updater.RepeatingPaymentUpdater;
 import spark.Request;
 import spark.Response;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java
index 6eb56285f87f075493cb671996ad1b5f9a54de4c..3c58aa12cfe1c8a16a41b0b32ce2ccbe8599c5fa 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/normal/PaymentUpdate.java
@@ -2,7 +2,7 @@ package de.deadlocker8.budgetmasterserver.server.payment.normal;
 
 import static spark.Spark.halt;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java
index e55598dcfccac3b03bde656273124e49fca3fbf1..4d622ffb1179f671b11cc1534602838dcc77f029 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentAdd.java
@@ -2,7 +2,7 @@ package de.deadlocker8.budgetmasterserver.server.payment.repeating;
 
 import static spark.Spark.halt;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java
index b2b480c5d81f263a27b4340cf4f1616449d72df0..a88de42bffad9293f85214a4c0975ecda7fbb208 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentDelete.java
@@ -2,7 +2,7 @@ package de.deadlocker8.budgetmasterserver.server.payment.repeating;
 
 import static spark.Spark.halt;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java
index fc6e13d84f23a612fbf0cc3c05fd9d66add7c6b4..0a8fd5af5c87a92b58205a771eeebb2e6d13ca07 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGet.java
@@ -5,7 +5,7 @@ import static spark.Spark.halt;
 import com.google.gson.Gson;
 
 import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java
index 3c053d1142b95a5e2dadadafaafac1f817100e2c..573a3c0114fc94c3a366d5d1ea3a0f4435e8fbc9 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/payment/repeating/RepeatingPaymentGetAll.java
@@ -9,7 +9,7 @@ import org.joda.time.DateTime;
 import com.google.gson.Gson;
 
 import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import de.deadlocker8.budgetmasterserver.server.updater.RepeatingPaymentUpdater;
 import spark.Request;
 import spark.Response;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java b/src/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java
index 0962749b594c2111f93c633685446494585704b7..2dd749311af34963b22d1d4a4149028a9ea40994 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/rest/RestGet.java
@@ -4,7 +4,7 @@ import static spark.Spark.halt;
 
 import com.google.gson.Gson;
 
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import spark.Request;
 import spark.Response;
 import spark.Route;
diff --git a/src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java b/src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java
index 0b7246a911ffcb06200b782759ce1c01eb3482d9..65299438637232fdaf169cf2d3fe9679016fa564 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/updater/RepeatingPaymentUpdater.java
@@ -8,7 +8,7 @@ import org.joda.time.Months;
 
 import de.deadlocker8.budgetmaster.logic.LatestRepeatingPayment;
 import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
-import de.deadlocker8.budgetmasterserver.main.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import logger.Logger;
 
 public class RepeatingPaymentUpdater