commit 928971988e3b45fdfca5562fc3cd886fe59cfec6
Author: Eliška Mourycová <eliska.mourycova@seznam.cz>
Date:   Sun May 23 16:17:45 2021 +0200

    Re #8944. Prepared testing class for DataDownloader.

diff --git a/Server/ServerApp/Connection/ConnectionListener.cs b/Server/ServerApp/Connection/ConnectionListener.cs
new file mode 100644
index 0000000..7cebbe8
--- /dev/null
+++ b/Server/ServerApp/Connection/ConnectionListener.cs
@@ -0,0 +1,730 @@
+﻿//
+// Author: Eliska Mourycova
+//
+
+using ServerApp.Connection.XMLProtocolHandler;
+using ServerApp.Predictor;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Web;
+
+namespace ServerApp.Connection
+{
+
+	//public class HttpListenerCallbackState
+	//{
+	//    private readonly HttpListener _listener;
+	//    private readonly AutoResetEvent _listenForNextRequest;
+
+	//    public HttpListenerCallbackState(HttpListener listener)
+	//    {
+	//        if (listener == null) throw new ArgumentNullException("listener");
+	//        _listener = listener;
+	//        _listenForNextRequest = new AutoResetEvent(false);
+	//    }
+
+	//    public HttpListener Listener { get { return _listener; } }
+	//    public AutoResetEvent ListenForNextRequest { get { return _listenForNextRequest; } }
+	//}
+
+	//public class HttpRequestHandler
+	//{
+	//    private int requestCounter = 0;
+	//    private ManualResetEvent stopEvent = new ManualResetEvent(false);
+	//    private int PORT;
+
+	//    public HttpRequestHandler(int port)
+	//    {
+	//        this.PORT = port;
+	//    }
+
+	//    public void ListenAsynchronously(/*IEnumerable<string> prefixes*/)
+	//    {
+	//        HttpListener listener = new HttpListener();
+
+	//        //foreach (string s in prefixes)
+	//        //{
+	//        //    listener.Prefixes.Add(s);
+	//        //}
+
+	//        listener.Prefixes.Add($"http://localhost:{PORT}/");
+
+	//        listener.Start();
+	//        Console.WriteLine("Listening...");
+	//        HttpListenerCallbackState state = new HttpListenerCallbackState(listener);
+	//        ThreadPool.QueueUserWorkItem(Listen, state);
+	//    }
+
+	//    public void StopListening()
+	//    {
+	//        stopEvent.Set();
+	//    }
+
+
+	//    private void Listen(object state)
+	//    {
+	//        HttpListenerCallbackState callbackState = (HttpListenerCallbackState)state;
+
+	//        while (callbackState.Listener.IsListening)
+	//        {
+	//            callbackState.Listener.BeginGetContext(new AsyncCallback(ListenerCallback), callbackState);
+	//            int n = WaitHandle.WaitAny(new WaitHandle[] { callbackState.ListenForNextRequest, stopEvent });
+
+	//            if (n == 1)
+	//            {
+	//                // stopEvent was signalled 
+	//                callbackState.Listener.Stop();
+	//                break;
+	//            }
+	//        }
+	//    }
+
+	//    private void ListenerCallback(IAsyncResult ar)
+	//    {
+	//        HttpListenerCallbackState callbackState = (HttpListenerCallbackState)ar.AsyncState;
+	//        HttpListenerContext context = null;
+
+	//        int requestNumber = Interlocked.Increment(ref requestCounter);
+
+	//        try
+	//        {
+	//            context = callbackState.Listener.EndGetContext(ar);
+	//        }
+	//        catch (Exception ex)
+	//        {
+	//            return;
+	//        }
+	//        finally
+	//        {
+	//            callbackState.ListenForNextRequest.Set();
+	//        }
+
+	//        if (context == null) return;
+
+
+	//        HttpListenerRequest request = context.Request;
+
+	//        if (request.HasEntityBody)
+	//        {
+	//            using (System.IO.StreamReader sr = new System.IO.StreamReader(request.InputStream, request.ContentEncoding))
+	//            {
+	//                string requestData = sr.ReadToEnd();
+
+	//                //Stuff I do with the request happens here  
+	//            }
+	//        }
+
+
+	//        try
+	//        {
+	//            using (HttpListenerResponse response = context.Response)
+	//            {
+	//                Console.WriteLine("dealing with response");
+	//                //Thread.Sleep(10000);
+	//                //response stuff happens here  
+	//                string responseString = "Ok";
+
+	//                byte[] buffer = Encoding.UTF8.GetBytes(responseString);
+	//                response.ContentLength64 = buffer.LongLength;
+	//                response.OutputStream.Write(buffer, 0, buffer.Length);
+	//                response.Close();
+	//            }
+	//        }
+	//        catch (Exception e)
+	//        {
+	//        }
+	//    }
+	//}
+
+
+
+
+
+
+
+
+
+
+	public class ConnectionListener
+	{
+		private readonly int PORT;
+		private IPredictionController predictionController;
+
+		public ConnectionListener(int port, IPredictionController predictionController)
+		{
+			this.PORT = port;
+			this.predictionController = predictionController;
+		}
+
+		public void StartListening()
+		{
+			string ip = GetLocalIPAddress();
+			Console.WriteLine("ip : " + ip);
+			HttpListener server = new HttpListener();
+			server.Prefixes.Add($"https://{ip}:{PORT}/");
+			//server.Prefixes.Add($"http://localhost:{PORT}/");
+
+			server.Start();
+
+			Console.WriteLine("Listening...");
+
+			while (true)
+			{
+				Console.WriteLine("Waiting for a client request...");
+
+				HttpListenerContext context = server.GetContext();
+
+
+
+				if (context.Request.HttpMethod == "GET") // when client says download
+				{
+					Console.WriteLine("received GET request");
+
+					HttpListenerResponse response = context.Response;
+					response.AddHeader("Access-Control-Allow-Credentials", "true");
+					response.AddHeader("Access-Control-Expose-Headers", "ETag");
+					response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
+					response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+					response.AddHeader("Access-Control-Allow-Origin", "*");
+
+
+
+					//string page = Directory.GetCurrentDirectory() + context.Request.Url.LocalPath;
+					// if (page == string.Empty)
+					//     page = "test.txt";
+					// 
+					// TextReader tr = new StreamReader(page);
+					// string msg = tr.ReadToEnd();
+
+					int rand = new Random().Next(1, 10);
+					string msg = "This is a response from the server :) " + rand;
+
+					Response xmlResp = Response.Randomize();
+					var xml = XmlCommunication.Serialize(xmlResp);
+					//Console.WriteLine(xml);
+
+					msg = xml;
+
+					byte[] buffer = Encoding.UTF8.GetBytes(msg);
+
+					response.ContentLength64 = buffer.Length;
+					Stream st = response.OutputStream;
+					st.Write(buffer, 0, buffer.Length);
+
+
+					context.Response.Close();
+				}
+
+				else if (context.Request.HttpMethod == "POST") // when client says upload
+				{
+					Console.WriteLine("received POST request");
+
+					string text;
+					using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
+						text = reader.ReadToEnd();
+					Console.WriteLine("Received request:");
+					string requestXML = HttpUtility.UrlDecode(text);
+					Console.WriteLine(requestXML);
+
+					// prepare the type:
+					Request newRequest = new Request();
+					Request requestDeserialized = null;
+					try
+					{
+						requestDeserialized = XmlCommunication.Deserialize(newRequest, requestXML);
+					}
+					catch
+					{
+						Console.WriteLine("wrong format of request!");
+
+						// don't bother to send anything:
+						context.Response.Close();
+						continue;
+					}
+					
+
+					// response headers:
+					HttpListenerResponse response = context.Response;
+					response.AddHeader("Access-Control-Allow-Credentials", "true");
+					response.AddHeader("Access-Control-Expose-Headers", "ETag");
+					response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
+					response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+					response.AddHeader("Access-Control-Allow-Origin", "*");
+
+					// get the prediction from the model:
+					Response responsePrediction = predictionController.Predict(requestDeserialized);
+
+					int rand = new Random().Next(1, 10);
+					string msg = "OK " + rand;
+
+					// build the xml from the prediction: - TODO mbe an exception can happen here as well? - it shouldnt
+					msg = XmlCommunication.Serialize(responsePrediction);
+
+
+					// send the response:
+					byte[] buffer = Encoding.UTF8.GetBytes(msg);
+					response.ContentLength64 = buffer.Length;
+					Stream st = response.OutputStream;
+					st.Write(buffer, 0, buffer.Length);
+
+					// close
+					context.Response.Close(); // ?? Works better with this, if this line is absent, the client gets 'stuck' after approximately 6 messages
+				}
+				else
+				{
+					Console.WriteLine("received request other than GET or POST");
+					Console.WriteLine("method: " + context.Request.HttpMethod);
+					Console.WriteLine("headers: " + context.Request.Headers);
+					Console.WriteLine("whole request?: " + context.Request);
+					Console.WriteLine("user: " + context.User);
+
+
+
+					//HttpListenerResponse response = context.Response;
+					//response.AddHeader("Access-Control-Allow-Credentials", "true");
+					//response.AddHeader("Access-Control-Expose-Headers", "ETag");
+					//response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time, Origin, Content-Type, X-Auth-Token");
+					//response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+					//response.AddHeader("Access-Control-Allow-Origin", "*");
+
+					//string msg = "Preflight check? ";
+
+					//byte[] buffer = Encoding.UTF8.GetBytes(msg);
+
+					//response.ContentLength64 = buffer.Length;
+					//Stream st = response.OutputStream;
+					//st.Write(buffer, 0, buffer.Length);
+
+
+					//context.Response.Close(); // ??
+
+				}
+			}
+		}
+
+		private string GetLocalIPAddress()
+		{
+			var host = Dns.GetHostEntry(Dns.GetHostName());
+			foreach (var ip in host.AddressList)
+			{
+				if (ip.AddressFamily == AddressFamily.InterNetwork)
+				{
+					return ip.ToString();
+				}
+			}
+			throw new Exception("No network adapters with an IPv4 address in the system!");
+		}
+
+	}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	// ---------------------------------------------------------------------------
+
+
+
+
+
+
+
+
+	class ClientService
+	{
+		public static readonly int MAX_IDS = 1000000; // ??
+		public static int IDs = 0;
+		public int UniqueID;
+		public Request ClientRequest;
+		public Response ClientResponse;
+    }
+
+    public class ConnectionListenerMulti
+    {
+        private readonly int PORT;
+        private ConcurrentDictionary<int, ClientService> readyRequests;
+        private ConcurrentQueue<ClientService> waitingRequests;
+
+
+        public ConnectionListenerMulti(int port)
+        {
+            this.PORT = port;
+        }
+
+
+		private void RequestHandler()
+		{
+			while (true)
+			{
+				if (!waitingRequests.IsEmpty)
+				{
+					Console.WriteLine("handling a request for 10s...");
+					ClientService nextService;
+					bool deqResultOk = waitingRequests.TryDequeue(out nextService);
+					// nextService has ID and request filled out
+					Thread.Sleep(10000);
+
+					Console.WriteLine("finished building response, adding it to the dictionary...");
+					//ClientService service = new ClientService();
+					//service.UniqueID = GetNextID();
+					//service.ClientRequest = Request.Randomize();
+					nextService.ClientResponse = Response.Randomize();
+					bool resultOk = readyRequests.TryAdd(nextService.UniqueID, nextService);
+					if (!resultOk)
+					{
+						Console.WriteLine("ID " + nextService.UniqueID + " is being used!");
+						// do nothing? - keep it in the queue and let the client try later perhaps?
+					}
+					else
+					{
+						// added to dictionary
+						// -> remove it from the queue
+						
+					}
+				}
+				else
+				{
+					Thread.Sleep(100); // ??
+				}
+				
+			}
+			
+
+		}
+
+		private int GetNextID()
+		{
+			int id = (ClientService.IDs++) % ClientService.MAX_IDS; // we presume that after a million requests, the first ids are free again, if not, tough luck
+			return id;
+		}
+
+        public void StartListening()
+        {
+            string ip = GetLocalIPAddress();
+            Console.WriteLine("ip : " + ip);
+            HttpListener server = new HttpListener();
+            //server.Prefixes.Add($"https://{ip}:{PORT}/");
+            server.Prefixes.Add($"http://localhost:{PORT}/");
+
+            server.Start();
+
+            Console.WriteLine("Listening...");
+
+			waitingRequests = new ConcurrentQueue<ClientService>();
+			readyRequests = new ConcurrentDictionary<int, ClientService>();
+
+
+			Thread requestHandlerThread = new Thread(RequestHandler);
+			requestHandlerThread.Start();
+
+			while (true)
+            {
+                Console.WriteLine("Waiting for a client request...");
+				//Console.ReadLine();
+
+				HttpListenerContext context = server.GetContext();
+				//Thread.Sleep(10000);
+
+				//IAsyncResult result = server.BeginGetContext(new AsyncCallback(ListenerCallback), server);
+				//Console.WriteLine("Waiting for request to be processed asyncronously.");
+				//result.AsyncWaitHandle.WaitOne();
+				//Console.WriteLine("Request processed asyncronously.");
+
+
+
+				if (context.Request.HttpMethod == "GET") // when client says download
+				{
+					Console.WriteLine("received GET request");
+
+					HttpListenerResponse response = context.Response;
+					response.AddHeader("Access-Control-Allow-Credentials", "true");
+					response.AddHeader("Access-Control-Expose-Headers", "ETag");
+					response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
+					response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+					response.AddHeader("Access-Control-Allow-Origin", "*");
+
+
+
+					//string page = Directory.GetCurrentDirectory() + context.Request.Url.LocalPath;
+					// if (page == string.Empty)
+					//     page = "test.txt";
+					// 
+					// TextReader tr = new StreamReader(page);
+					// string msg = tr.ReadToEnd();
+
+					int rand = new Random().Next(1, 10);
+					string msg = "This is a response from the server :) " + rand;
+
+					Response xmlResp = Response.Randomize();
+					var xml = XmlCommunication.Serialize(xmlResp);
+					//Console.WriteLine(xml);
+
+					msg = xml;
+
+					byte[] buffer = Encoding.UTF8.GetBytes(msg);
+
+					response.ContentLength64 = buffer.Length;
+					Stream st = response.OutputStream;
+					st.Write(buffer, 0, buffer.Length);
+
+
+					context.Response.Close();
+				}
+
+				else if (context.Request.HttpMethod == "POST") // when client says upload
+				{
+					Console.WriteLine("received POST request");
+
+					string text;
+					using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
+						text = reader.ReadToEnd();
+					Console.WriteLine("Received request:");
+					string requestXML = HttpUtility.UrlDecode(text);
+					Console.WriteLine(requestXML);
+
+					Request newRequest = new Request();
+					Request requestDeserialized = XmlCommunication.Deserialize(newRequest, requestXML);
+
+					ClientService newService = new ClientService();
+					newService.UniqueID = GetNextID();
+					newService.ClientRequest = requestDeserialized;
+					// save the request to the queue
+					waitingRequests.Enqueue(newService);
+
+
+
+					// SEND THE ID: - TODO xml format also
+					HttpListenerResponse response = context.Response;
+					response.AddHeader("Access-Control-Allow-Credentials", "true");
+					response.AddHeader("Access-Control-Expose-Headers", "ETag");
+					response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
+					response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+					response.AddHeader("Access-Control-Allow-Origin", "*");
+
+
+
+					int rand = new Random().Next(1, 10);
+					string msg = "" + newService.UniqueID;
+
+					byte[] buffer = Encoding.UTF8.GetBytes(msg);
+
+					response.ContentLength64 = buffer.Length;
+					Stream st = response.OutputStream;
+					st.Write(buffer, 0, buffer.Length);
+
+
+					context.Response.Close(); // ?? Works better with this, if this line is absent, the client gets 'stuck' after approximately 6 messages
+				}
+				else
+				{
+					Console.WriteLine("received request other than GET or POST");
+					Console.WriteLine("method: " + context.Request.HttpMethod);
+					Console.WriteLine("headers: " + context.Request.Headers);
+					Console.WriteLine("whole request?: " + context.Request);
+					Console.WriteLine("user: " + context.User);
+
+
+
+					//HttpListenerResponse response = context.Response;
+					//response.AddHeader("Access-Control-Allow-Credentials", "true");
+					//response.AddHeader("Access-Control-Expose-Headers", "ETag");
+					//response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time, Origin, Content-Type, X-Auth-Token");
+					//response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+					//response.AddHeader("Access-Control-Allow-Origin", "*");
+
+					//string msg = "Preflight check? ";
+
+					//byte[] buffer = Encoding.UTF8.GetBytes(msg);
+
+					//response.ContentLength64 = buffer.Length;
+					//Stream st = response.OutputStream;
+					//st.Write(buffer, 0, buffer.Length);
+
+
+					//context.Response.Close(); // ??
+
+				}
+			}
+        }
+
+
+
+
+
+
+
+
+
+
+
+		private void ListenerCallback(IAsyncResult result)
+		{
+			HttpListener listener = (HttpListener)result.AsyncState;
+			// Call EndGetContext to complete the asynchronous operation.
+			HttpListenerContext context = listener.EndGetContext(result);
+
+			Console.WriteLine("callbacking...");
+
+			Thread.Sleep(10000);
+
+			if (context.Request.HttpMethod == "GET") // when client says download
+			{
+				Console.WriteLine("received GET request");
+
+				HttpListenerResponse response = context.Response;
+				response.AddHeader("Access-Control-Allow-Credentials", "true");
+				response.AddHeader("Access-Control-Expose-Headers", "ETag");
+				response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
+				response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+				response.AddHeader("Access-Control-Allow-Origin", "*");
+
+
+
+				//string page = Directory.GetCurrentDirectory() + context.Request.Url.LocalPath;
+				// if (page == string.Empty)
+				//     page = "test.txt";
+				// 
+				// TextReader tr = new StreamReader(page);
+				// string msg = tr.ReadToEnd();
+
+				int rand = new Random().Next(1, 10);
+				string msg = "This is a response from the server :) " + rand;
+
+				Response xmlResp = Response.Randomize();
+				var xml = XmlCommunication.Serialize(xmlResp);
+				//Console.WriteLine(xml);
+
+				msg = xml;
+
+				byte[] buffer = Encoding.UTF8.GetBytes(msg);
+
+				response.ContentLength64 = buffer.Length;
+				Stream st = response.OutputStream;
+				st.Write(buffer, 0, buffer.Length);
+
+
+				context.Response.Close();
+			}
+
+			else if (context.Request.HttpMethod == "POST") // when client says upload
+			{
+				Console.WriteLine("received POST request");
+
+				string text;
+				using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
+					text = reader.ReadToEnd();
+				Console.WriteLine("Received request:");
+				Console.WriteLine(HttpUtility.UrlDecode(text));
+
+
+
+				HttpListenerResponse response = context.Response;
+				response.AddHeader("Access-Control-Allow-Credentials", "true");
+				response.AddHeader("Access-Control-Expose-Headers", "ETag");
+				response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
+				response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+				response.AddHeader("Access-Control-Allow-Origin", "*");
+
+
+
+				int rand = new Random().Next(1, 10);
+				string msg = "OK " + rand;
+
+				byte[] buffer = Encoding.UTF8.GetBytes(msg);
+
+				response.ContentLength64 = buffer.Length;
+				Stream st = response.OutputStream;
+				st.Write(buffer, 0, buffer.Length);
+
+
+				context.Response.Close(); // ?? Works better with this, if this line is absent, the client gets 'stuck' after approximately 6 messages
+			}
+			else
+			{
+				Console.WriteLine("received request other than GET or POST");
+				Console.WriteLine("method: " + context.Request.HttpMethod);
+				Console.WriteLine("headers: " + context.Request.Headers);
+				Console.WriteLine("whole request?: " + context.Request);
+				Console.WriteLine("user: " + context.User);
+
+
+
+				//HttpListenerResponse response = context.Response;
+				//response.AddHeader("Access-Control-Allow-Credentials", "true");
+				//response.AddHeader("Access-Control-Expose-Headers", "ETag");
+				//response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time, Origin, Content-Type, X-Auth-Token");
+				//response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+				//response.AddHeader("Access-Control-Allow-Origin", "*");
+
+				//string msg = "Preflight check? ";
+
+				//byte[] buffer = Encoding.UTF8.GetBytes(msg);
+
+				//response.ContentLength64 = buffer.Length;
+				//Stream st = response.OutputStream;
+				//st.Write(buffer, 0, buffer.Length);
+
+
+				//context.Response.Close(); // ??
+
+			}
+
+
+
+
+
+
+
+
+
+
+			//HttpListenerRequest request = context.Request;
+			//// Obtain a response object.
+			//HttpListenerResponse response = context.Response;
+			//// Construct a response.
+			//string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
+			//byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
+			//// Get a response stream and write the response to it.
+			//response.ContentLength64 = buffer.Length;
+			//System.IO.Stream output = response.OutputStream;
+			//output.Write(buffer, 0, buffer.Length);
+			//// You must close the output stream.
+			//output.Close();
+		}
+
+
+		private string GetLocalIPAddress()
+        {
+            var host = Dns.GetHostEntry(Dns.GetHostName());
+            foreach (var ip in host.AddressList)
+            {
+                if (ip.AddressFamily == AddressFamily.InterNetwork)
+                {
+                    return ip.ToString();
+                }
+            }
+            throw new Exception("No network adapters with an IPv4 address in the system!");
+        }
+
+    }
+
+}
diff --git a/Server/ServerApp/Connection/ConnectionListenerMulti.cs b/Server/ServerApp/Connection/ConnectionListenerMulti.cs
deleted file mode 100644
index 7dde033..0000000
--- a/Server/ServerApp/Connection/ConnectionListenerMulti.cs
+++ /dev/null
@@ -1,729 +0,0 @@
-﻿//
-// Author: Eliska Mourycova
-//
-
-using ServerApp.Connection.XMLProtocolHandler;
-using ServerApp.Predictor;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.Web;
-
-namespace ServerApp.Connection
-{
-
-	//public class HttpListenerCallbackState
-	//{
-	//    private readonly HttpListener _listener;
-	//    private readonly AutoResetEvent _listenForNextRequest;
-
-	//    public HttpListenerCallbackState(HttpListener listener)
-	//    {
-	//        if (listener == null) throw new ArgumentNullException("listener");
-	//        _listener = listener;
-	//        _listenForNextRequest = new AutoResetEvent(false);
-	//    }
-
-	//    public HttpListener Listener { get { return _listener; } }
-	//    public AutoResetEvent ListenForNextRequest { get { return _listenForNextRequest; } }
-	//}
-
-	//public class HttpRequestHandler
-	//{
-	//    private int requestCounter = 0;
-	//    private ManualResetEvent stopEvent = new ManualResetEvent(false);
-	//    private int PORT;
-
-	//    public HttpRequestHandler(int port)
-	//    {
-	//        this.PORT = port;
-	//    }
-
-	//    public void ListenAsynchronously(/*IEnumerable<string> prefixes*/)
-	//    {
-	//        HttpListener listener = new HttpListener();
-
-	//        //foreach (string s in prefixes)
-	//        //{
-	//        //    listener.Prefixes.Add(s);
-	//        //}
-
-	//        listener.Prefixes.Add($"http://localhost:{PORT}/");
-
-	//        listener.Start();
-	//        Console.WriteLine("Listening...");
-	//        HttpListenerCallbackState state = new HttpListenerCallbackState(listener);
-	//        ThreadPool.QueueUserWorkItem(Listen, state);
-	//    }
-
-	//    public void StopListening()
-	//    {
-	//        stopEvent.Set();
-	//    }
-
-
-	//    private void Listen(object state)
-	//    {
-	//        HttpListenerCallbackState callbackState = (HttpListenerCallbackState)state;
-
-	//        while (callbackState.Listener.IsListening)
-	//        {
-	//            callbackState.Listener.BeginGetContext(new AsyncCallback(ListenerCallback), callbackState);
-	//            int n = WaitHandle.WaitAny(new WaitHandle[] { callbackState.ListenForNextRequest, stopEvent });
-
-	//            if (n == 1)
-	//            {
-	//                // stopEvent was signalled 
-	//                callbackState.Listener.Stop();
-	//                break;
-	//            }
-	//        }
-	//    }
-
-	//    private void ListenerCallback(IAsyncResult ar)
-	//    {
-	//        HttpListenerCallbackState callbackState = (HttpListenerCallbackState)ar.AsyncState;
-	//        HttpListenerContext context = null;
-
-	//        int requestNumber = Interlocked.Increment(ref requestCounter);
-
-	//        try
-	//        {
-	//            context = callbackState.Listener.EndGetContext(ar);
-	//        }
-	//        catch (Exception ex)
-	//        {
-	//            return;
-	//        }
-	//        finally
-	//        {
-	//            callbackState.ListenForNextRequest.Set();
-	//        }
-
-	//        if (context == null) return;
-
-
-	//        HttpListenerRequest request = context.Request;
-
-	//        if (request.HasEntityBody)
-	//        {
-	//            using (System.IO.StreamReader sr = new System.IO.StreamReader(request.InputStream, request.ContentEncoding))
-	//            {
-	//                string requestData = sr.ReadToEnd();
-
-	//                //Stuff I do with the request happens here  
-	//            }
-	//        }
-
-
-	//        try
-	//        {
-	//            using (HttpListenerResponse response = context.Response)
-	//            {
-	//                Console.WriteLine("dealing with response");
-	//                //Thread.Sleep(10000);
-	//                //response stuff happens here  
-	//                string responseString = "Ok";
-
-	//                byte[] buffer = Encoding.UTF8.GetBytes(responseString);
-	//                response.ContentLength64 = buffer.LongLength;
-	//                response.OutputStream.Write(buffer, 0, buffer.Length);
-	//                response.Close();
-	//            }
-	//        }
-	//        catch (Exception e)
-	//        {
-	//        }
-	//    }
-	//}
-
-
-
-
-
-
-
-
-
-
-	public class ConnectionListener
-	{
-		private readonly int PORT;
-		private IPredictionController predictionController;
-
-		public ConnectionListener(int port, IPredictionController predictionController)
-		{
-			this.PORT = port;
-			this.predictionController = predictionController;
-		}
-
-		public void StartListening()
-		{
-			string ip = GetLocalIPAddress();
-			Console.WriteLine("ip : " + ip);
-			HttpListener server = new HttpListener();
-			//server.Prefixes.Add($"https://{ip}:{PORT}/");
-			server.Prefixes.Add($"http://localhost:{PORT}/");
-
-			server.Start();
-
-			Console.WriteLine("Listening...");
-
-			while (true)
-			{
-				Console.WriteLine("Waiting for a client request...");
-
-				HttpListenerContext context = server.GetContext();
-
-
-
-				if (context.Request.HttpMethod == "GET") // when client says download
-				{
-					Console.WriteLine("received GET request");
-
-					HttpListenerResponse response = context.Response;
-					response.AddHeader("Access-Control-Allow-Credentials", "true");
-					response.AddHeader("Access-Control-Expose-Headers", "ETag");
-					response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
-					response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-					response.AddHeader("Access-Control-Allow-Origin", "*");
-
-
-
-					//string page = Directory.GetCurrentDirectory() + context.Request.Url.LocalPath;
-					// if (page == string.Empty)
-					//     page = "test.txt";
-					// 
-					// TextReader tr = new StreamReader(page);
-					// string msg = tr.ReadToEnd();
-
-					int rand = new Random().Next(1, 10);
-					string msg = "This is a response from the server :) " + rand;
-
-					Response xmlResp = Response.Randomize();
-					var xml = XmlCommunication.Serialize(xmlResp);
-					//Console.WriteLine(xml);
-
-					msg = xml;
-
-					byte[] buffer = Encoding.UTF8.GetBytes(msg);
-
-					response.ContentLength64 = buffer.Length;
-					Stream st = response.OutputStream;
-					st.Write(buffer, 0, buffer.Length);
-
-
-					context.Response.Close();
-				}
-
-				else if (context.Request.HttpMethod == "POST") // when client says upload
-				{
-					Console.WriteLine("received POST request");
-
-					string text;
-					using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
-						text = reader.ReadToEnd();
-					Console.WriteLine("Received request:");
-					string requestXML = HttpUtility.UrlDecode(text);
-					Console.WriteLine(requestXML);
-
-					// prepare the type:
-					Request newRequest = new Request();
-					Request requestDeserialized = null;
-					try
-					{
-						requestDeserialized = XmlCommunication.Deserialize(newRequest, requestXML);
-					}
-					catch
-					{
-						Console.WriteLine("wrong format of request!");
-
-						// don't bother to send anything:
-						continue;
-					}
-					
-
-					// response headers:
-					HttpListenerResponse response = context.Response;
-					response.AddHeader("Access-Control-Allow-Credentials", "true");
-					response.AddHeader("Access-Control-Expose-Headers", "ETag");
-					response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
-					response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-					response.AddHeader("Access-Control-Allow-Origin", "*");
-
-					// get the prediction from the model:
-					Response responsePrediction = predictionController.Predict(requestDeserialized);
-
-					int rand = new Random().Next(1, 10);
-					string msg = "OK " + rand;
-
-					// build the xml from the prediction: - TODO mbe an exception can happen here as well? - it shouldnt
-					msg = XmlCommunication.Serialize(responsePrediction);
-
-
-					// send the response:
-					byte[] buffer = Encoding.UTF8.GetBytes(msg);
-					response.ContentLength64 = buffer.Length;
-					Stream st = response.OutputStream;
-					st.Write(buffer, 0, buffer.Length);
-
-					// close
-					context.Response.Close(); // ?? Works better with this, if this line is absent, the client gets 'stuck' after approximately 6 messages
-				}
-				else
-				{
-					Console.WriteLine("received request other than GET or POST");
-					Console.WriteLine("method: " + context.Request.HttpMethod);
-					Console.WriteLine("headers: " + context.Request.Headers);
-					Console.WriteLine("whole request?: " + context.Request);
-					Console.WriteLine("user: " + context.User);
-
-
-
-					//HttpListenerResponse response = context.Response;
-					//response.AddHeader("Access-Control-Allow-Credentials", "true");
-					//response.AddHeader("Access-Control-Expose-Headers", "ETag");
-					//response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time, Origin, Content-Type, X-Auth-Token");
-					//response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-					//response.AddHeader("Access-Control-Allow-Origin", "*");
-
-					//string msg = "Preflight check? ";
-
-					//byte[] buffer = Encoding.UTF8.GetBytes(msg);
-
-					//response.ContentLength64 = buffer.Length;
-					//Stream st = response.OutputStream;
-					//st.Write(buffer, 0, buffer.Length);
-
-
-					//context.Response.Close(); // ??
-
-				}
-			}
-		}
-
-		private string GetLocalIPAddress()
-		{
-			var host = Dns.GetHostEntry(Dns.GetHostName());
-			foreach (var ip in host.AddressList)
-			{
-				if (ip.AddressFamily == AddressFamily.InterNetwork)
-				{
-					return ip.ToString();
-				}
-			}
-			throw new Exception("No network adapters with an IPv4 address in the system!");
-		}
-
-	}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-	// ---------------------------------------------------------------------------
-
-
-
-
-
-
-
-
-	class ClientService
-	{
-		public static readonly int MAX_IDS = 1000000; // ??
-		public static int IDs = 0;
-		public int UniqueID;
-		public Request ClientRequest;
-		public Response ClientResponse;
-    }
-
-    public class ConnectionListenerMulti
-    {
-        private readonly int PORT;
-        private ConcurrentDictionary<int, ClientService> readyRequests;
-        private ConcurrentQueue<ClientService> waitingRequests;
-
-
-        public ConnectionListenerMulti(int port)
-        {
-            this.PORT = port;
-        }
-
-
-		private void RequestHandler()
-		{
-			while (true)
-			{
-				if (!waitingRequests.IsEmpty)
-				{
-					Console.WriteLine("handling a request for 10s...");
-					ClientService nextService;
-					bool deqResultOk = waitingRequests.TryDequeue(out nextService);
-					// nextService has ID and request filled out
-					Thread.Sleep(10000);
-
-					Console.WriteLine("finished building response, adding it to the dictionary...");
-					//ClientService service = new ClientService();
-					//service.UniqueID = GetNextID();
-					//service.ClientRequest = Request.Randomize();
-					nextService.ClientResponse = Response.Randomize();
-					bool resultOk = readyRequests.TryAdd(nextService.UniqueID, nextService);
-					if (!resultOk)
-					{
-						Console.WriteLine("ID " + nextService.UniqueID + " is being used!");
-						// do nothing? - keep it in the queue and let the client try later perhaps?
-					}
-					else
-					{
-						// added to dictionary
-						// -> remove it from the queue
-						
-					}
-				}
-				else
-				{
-					Thread.Sleep(100); // ??
-				}
-				
-			}
-			
-
-		}
-
-		private int GetNextID()
-		{
-			int id = (ClientService.IDs++) % ClientService.MAX_IDS; // we presume that after a million requests, the first ids are free again, if not, tough luck
-			return id;
-		}
-
-        public void StartListening()
-        {
-            string ip = GetLocalIPAddress();
-            Console.WriteLine("ip : " + ip);
-            HttpListener server = new HttpListener();
-            //server.Prefixes.Add($"https://{ip}:{PORT}/");
-            server.Prefixes.Add($"http://localhost:{PORT}/");
-
-            server.Start();
-
-            Console.WriteLine("Listening...");
-
-			waitingRequests = new ConcurrentQueue<ClientService>();
-			readyRequests = new ConcurrentDictionary<int, ClientService>();
-
-
-			Thread requestHandlerThread = new Thread(RequestHandler);
-			requestHandlerThread.Start();
-
-			while (true)
-            {
-                Console.WriteLine("Waiting for a client request...");
-				//Console.ReadLine();
-
-				HttpListenerContext context = server.GetContext();
-				//Thread.Sleep(10000);
-
-				//IAsyncResult result = server.BeginGetContext(new AsyncCallback(ListenerCallback), server);
-				//Console.WriteLine("Waiting for request to be processed asyncronously.");
-				//result.AsyncWaitHandle.WaitOne();
-				//Console.WriteLine("Request processed asyncronously.");
-
-
-
-				if (context.Request.HttpMethod == "GET") // when client says download
-				{
-					Console.WriteLine("received GET request");
-
-					HttpListenerResponse response = context.Response;
-					response.AddHeader("Access-Control-Allow-Credentials", "true");
-					response.AddHeader("Access-Control-Expose-Headers", "ETag");
-					response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
-					response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-					response.AddHeader("Access-Control-Allow-Origin", "*");
-
-
-
-					//string page = Directory.GetCurrentDirectory() + context.Request.Url.LocalPath;
-					// if (page == string.Empty)
-					//     page = "test.txt";
-					// 
-					// TextReader tr = new StreamReader(page);
-					// string msg = tr.ReadToEnd();
-
-					int rand = new Random().Next(1, 10);
-					string msg = "This is a response from the server :) " + rand;
-
-					Response xmlResp = Response.Randomize();
-					var xml = XmlCommunication.Serialize(xmlResp);
-					//Console.WriteLine(xml);
-
-					msg = xml;
-
-					byte[] buffer = Encoding.UTF8.GetBytes(msg);
-
-					response.ContentLength64 = buffer.Length;
-					Stream st = response.OutputStream;
-					st.Write(buffer, 0, buffer.Length);
-
-
-					context.Response.Close();
-				}
-
-				else if (context.Request.HttpMethod == "POST") // when client says upload
-				{
-					Console.WriteLine("received POST request");
-
-					string text;
-					using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
-						text = reader.ReadToEnd();
-					Console.WriteLine("Received request:");
-					string requestXML = HttpUtility.UrlDecode(text);
-					Console.WriteLine(requestXML);
-
-					Request newRequest = new Request();
-					Request requestDeserialized = XmlCommunication.Deserialize(newRequest, requestXML);
-
-					ClientService newService = new ClientService();
-					newService.UniqueID = GetNextID();
-					newService.ClientRequest = requestDeserialized;
-					// save the request to the queue
-					waitingRequests.Enqueue(newService);
-
-
-
-					// SEND THE ID: - TODO xml format also
-					HttpListenerResponse response = context.Response;
-					response.AddHeader("Access-Control-Allow-Credentials", "true");
-					response.AddHeader("Access-Control-Expose-Headers", "ETag");
-					response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
-					response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-					response.AddHeader("Access-Control-Allow-Origin", "*");
-
-
-
-					int rand = new Random().Next(1, 10);
-					string msg = "" + newService.UniqueID;
-
-					byte[] buffer = Encoding.UTF8.GetBytes(msg);
-
-					response.ContentLength64 = buffer.Length;
-					Stream st = response.OutputStream;
-					st.Write(buffer, 0, buffer.Length);
-
-
-					context.Response.Close(); // ?? Works better with this, if this line is absent, the client gets 'stuck' after approximately 6 messages
-				}
-				else
-				{
-					Console.WriteLine("received request other than GET or POST");
-					Console.WriteLine("method: " + context.Request.HttpMethod);
-					Console.WriteLine("headers: " + context.Request.Headers);
-					Console.WriteLine("whole request?: " + context.Request);
-					Console.WriteLine("user: " + context.User);
-
-
-
-					//HttpListenerResponse response = context.Response;
-					//response.AddHeader("Access-Control-Allow-Credentials", "true");
-					//response.AddHeader("Access-Control-Expose-Headers", "ETag");
-					//response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time, Origin, Content-Type, X-Auth-Token");
-					//response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-					//response.AddHeader("Access-Control-Allow-Origin", "*");
-
-					//string msg = "Preflight check? ";
-
-					//byte[] buffer = Encoding.UTF8.GetBytes(msg);
-
-					//response.ContentLength64 = buffer.Length;
-					//Stream st = response.OutputStream;
-					//st.Write(buffer, 0, buffer.Length);
-
-
-					//context.Response.Close(); // ??
-
-				}
-			}
-        }
-
-
-
-
-
-
-
-
-
-
-
-		private void ListenerCallback(IAsyncResult result)
-		{
-			HttpListener listener = (HttpListener)result.AsyncState;
-			// Call EndGetContext to complete the asynchronous operation.
-			HttpListenerContext context = listener.EndGetContext(result);
-
-			Console.WriteLine("callbacking...");
-
-			Thread.Sleep(10000);
-
-			if (context.Request.HttpMethod == "GET") // when client says download
-			{
-				Console.WriteLine("received GET request");
-
-				HttpListenerResponse response = context.Response;
-				response.AddHeader("Access-Control-Allow-Credentials", "true");
-				response.AddHeader("Access-Control-Expose-Headers", "ETag");
-				response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
-				response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-				response.AddHeader("Access-Control-Allow-Origin", "*");
-
-
-
-				//string page = Directory.GetCurrentDirectory() + context.Request.Url.LocalPath;
-				// if (page == string.Empty)
-				//     page = "test.txt";
-				// 
-				// TextReader tr = new StreamReader(page);
-				// string msg = tr.ReadToEnd();
-
-				int rand = new Random().Next(1, 10);
-				string msg = "This is a response from the server :) " + rand;
-
-				Response xmlResp = Response.Randomize();
-				var xml = XmlCommunication.Serialize(xmlResp);
-				//Console.WriteLine(xml);
-
-				msg = xml;
-
-				byte[] buffer = Encoding.UTF8.GetBytes(msg);
-
-				response.ContentLength64 = buffer.Length;
-				Stream st = response.OutputStream;
-				st.Write(buffer, 0, buffer.Length);
-
-
-				context.Response.Close();
-			}
-
-			else if (context.Request.HttpMethod == "POST") // when client says upload
-			{
-				Console.WriteLine("received POST request");
-
-				string text;
-				using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
-					text = reader.ReadToEnd();
-				Console.WriteLine("Received request:");
-				Console.WriteLine(HttpUtility.UrlDecode(text));
-
-
-
-				HttpListenerResponse response = context.Response;
-				response.AddHeader("Access-Control-Allow-Credentials", "true");
-				response.AddHeader("Access-Control-Expose-Headers", "ETag");
-				response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
-				response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-				response.AddHeader("Access-Control-Allow-Origin", "*");
-
-
-
-				int rand = new Random().Next(1, 10);
-				string msg = "OK " + rand;
-
-				byte[] buffer = Encoding.UTF8.GetBytes(msg);
-
-				response.ContentLength64 = buffer.Length;
-				Stream st = response.OutputStream;
-				st.Write(buffer, 0, buffer.Length);
-
-
-				context.Response.Close(); // ?? Works better with this, if this line is absent, the client gets 'stuck' after approximately 6 messages
-			}
-			else
-			{
-				Console.WriteLine("received request other than GET or POST");
-				Console.WriteLine("method: " + context.Request.HttpMethod);
-				Console.WriteLine("headers: " + context.Request.Headers);
-				Console.WriteLine("whole request?: " + context.Request);
-				Console.WriteLine("user: " + context.User);
-
-
-
-				//HttpListenerResponse response = context.Response;
-				//response.AddHeader("Access-Control-Allow-Credentials", "true");
-				//response.AddHeader("Access-Control-Expose-Headers", "ETag");
-				//response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time, Origin, Content-Type, X-Auth-Token");
-				//response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
-				//response.AddHeader("Access-Control-Allow-Origin", "*");
-
-				//string msg = "Preflight check? ";
-
-				//byte[] buffer = Encoding.UTF8.GetBytes(msg);
-
-				//response.ContentLength64 = buffer.Length;
-				//Stream st = response.OutputStream;
-				//st.Write(buffer, 0, buffer.Length);
-
-
-				//context.Response.Close(); // ??
-
-			}
-
-
-
-
-
-
-
-
-
-
-			//HttpListenerRequest request = context.Request;
-			//// Obtain a response object.
-			//HttpListenerResponse response = context.Response;
-			//// Construct a response.
-			//string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";
-			//byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
-			//// Get a response stream and write the response to it.
-			//response.ContentLength64 = buffer.Length;
-			//System.IO.Stream output = response.OutputStream;
-			//output.Write(buffer, 0, buffer.Length);
-			//// You must close the output stream.
-			//output.Close();
-		}
-
-
-		private string GetLocalIPAddress()
-        {
-            var host = Dns.GetHostEntry(Dns.GetHostName());
-            foreach (var ip in host.AddressList)
-            {
-                if (ip.AddressFamily == AddressFamily.InterNetwork)
-                {
-                    return ip.ToString();
-                }
-            }
-            throw new Exception("No network adapters with an IPv4 address in the system!");
-        }
-
-    }
-
-}
diff --git a/Server/ServerApp/Program.cs b/Server/ServerApp/Program.cs
index 9b44654..b4ce14e 100644
--- a/Server/ServerApp/Program.cs
+++ b/Server/ServerApp/Program.cs
@@ -19,7 +19,7 @@ namespace ServerApp
 		public string DataWebsite { get; set; }
 		public string DownloadedFilesNaming { get; set; }
 		public string DataRootDir { get; set; }
-		public string Port { get; set; }
+		public string Port { get; set; } // TODO port cannot be configurable?
 	}
 
     public class Program
@@ -57,7 +57,7 @@ namespace ServerApp
 			DataDownloader dd = DataDownloadAndRetrievalTest(config);
 
 			// xml building test
-			XMLTest();
+			//XMLTest();
 
 
 
diff --git a/Server/ServerApp/ServerApp.csproj b/Server/ServerApp/ServerApp.csproj
index af87444..2afd7df 100644
--- a/Server/ServerApp/ServerApp.csproj
+++ b/Server/ServerApp/ServerApp.csproj
@@ -157,7 +157,7 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Connection\ConnectionListenerMulti.cs" />
+    <Compile Include="Connection\ConnectionListener.cs" />
     <Compile Include="Connection\XMLProtocolHandler\Buildings.cs" />
     <Compile Include="Connection\XMLProtocolHandler\Date.cs" />
     <Compile Include="Connection\XMLProtocolHandler\Prediction.cs" />
diff --git a/Server/TestProject/TestProject.csproj b/Server/TestProject/TestProject.csproj
index f3a73e8..40b363f 100644
--- a/Server/TestProject/TestProject.csproj
+++ b/Server/TestProject/TestProject.csproj
@@ -63,6 +63,7 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="TestingDataDownloader.cs" />
     <Compile Include="TestingParser.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
diff --git a/Server/TestProject/TestingDataDownloader.cs b/Server/TestProject/TestingDataDownloader.cs
new file mode 100644
index 0000000..3502151
--- /dev/null
+++ b/Server/TestProject/TestingDataDownloader.cs
@@ -0,0 +1,43 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace TestProject
+{
+	[TestClass]
+	class TestingDataDownloader
+	{
+		[TestMethod]
+		public void DataDirectoryCreate()
+		{
+
+		}
+
+		[TestMethod]
+		public void DataSubdirectoriesCreate()
+		{
+
+		}
+
+		[TestMethod]
+		public void DataDownload()
+		{
+
+		}
+
+		[TestMethod]
+		public void DataRetrieve()
+		{
+
+		}
+
+		[TestMethod]
+		public void DateCompare()
+		{
+
+		}
+	}
+}
