commit 847434c665e808efa71947f1a25a4d09d6373fae
Author: Roman Kalivoda <kalivodaroman@gmail.com>
Date:   Wed May 26 20:48:42 2021 +0200

    Re #9009 Migrate existing tests

diff --git a/Server/ServerApp.sln b/Server/ServerApp.sln
index f965b4d..ff512b4 100644
--- a/Server/ServerApp.sln
+++ b/Server/ServerApp.sln
@@ -5,9 +5,9 @@ VisualStudioVersion = 16.0.31105.61
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerApp", "ServerApp\ServerApp.csproj", "{18FCFB20-B860-4147-8E7C-8A0DD84C55D4}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestProject", "TestProject\TestProject.csproj", "{8A09DB8E-64B1-4D55-991E-7F7B21996B45}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerAppFunctionalTests", "ServerAppFunctionalTests\ServerAppFunctionalTests.csproj", "{FB3054E4-1E09-4946-8E7D-3273EBCB48F8}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServerAppUnitTests", "ServerAppTests\ServerAppUnitTests.csproj", "{125F0CBB-3B8D-45B7-8069-29CFB1416E63}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerAppUnitTests", "ServerAppUnitTests\ServerAppUnitTests.csproj", "{3B99CC79-47DD-4485-8F9F-A650DD71580B}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -25,22 +25,22 @@ Global
 		{18FCFB20-B860-4147-8E7C-8A0DD84C55D4}.Release|Any CPU.Build.0 = Release|Any CPU
 		{18FCFB20-B860-4147-8E7C-8A0DD84C55D4}.Release|x64.ActiveCfg = Release|x64
 		{18FCFB20-B860-4147-8E7C-8A0DD84C55D4}.Release|x64.Build.0 = Release|x64
-		{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Debug|x64.Build.0 = Debug|Any CPU
-		{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Release|Any CPU.Build.0 = Release|Any CPU
-		{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Release|x64.ActiveCfg = Release|Any CPU
-		{8A09DB8E-64B1-4D55-991E-7F7B21996B45}.Release|x64.Build.0 = Release|Any CPU
-		{125F0CBB-3B8D-45B7-8069-29CFB1416E63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{125F0CBB-3B8D-45B7-8069-29CFB1416E63}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{125F0CBB-3B8D-45B7-8069-29CFB1416E63}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{125F0CBB-3B8D-45B7-8069-29CFB1416E63}.Debug|x64.Build.0 = Debug|Any CPU
-		{125F0CBB-3B8D-45B7-8069-29CFB1416E63}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{125F0CBB-3B8D-45B7-8069-29CFB1416E63}.Release|Any CPU.Build.0 = Release|Any CPU
-		{125F0CBB-3B8D-45B7-8069-29CFB1416E63}.Release|x64.ActiveCfg = Release|Any CPU
-		{125F0CBB-3B8D-45B7-8069-29CFB1416E63}.Release|x64.Build.0 = Release|Any CPU
+		{FB3054E4-1E09-4946-8E7D-3273EBCB48F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{FB3054E4-1E09-4946-8E7D-3273EBCB48F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{FB3054E4-1E09-4946-8E7D-3273EBCB48F8}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{FB3054E4-1E09-4946-8E7D-3273EBCB48F8}.Debug|x64.Build.0 = Debug|Any CPU
+		{FB3054E4-1E09-4946-8E7D-3273EBCB48F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{FB3054E4-1E09-4946-8E7D-3273EBCB48F8}.Release|Any CPU.Build.0 = Release|Any CPU
+		{FB3054E4-1E09-4946-8E7D-3273EBCB48F8}.Release|x64.ActiveCfg = Release|Any CPU
+		{FB3054E4-1E09-4946-8E7D-3273EBCB48F8}.Release|x64.Build.0 = Release|Any CPU
+		{3B99CC79-47DD-4485-8F9F-A650DD71580B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3B99CC79-47DD-4485-8F9F-A650DD71580B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3B99CC79-47DD-4485-8F9F-A650DD71580B}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{3B99CC79-47DD-4485-8F9F-A650DD71580B}.Debug|x64.Build.0 = Debug|Any CPU
+		{3B99CC79-47DD-4485-8F9F-A650DD71580B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3B99CC79-47DD-4485-8F9F-A650DD71580B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3B99CC79-47DD-4485-8F9F-A650DD71580B}.Release|x64.ActiveCfg = Release|Any CPU
+		{3B99CC79-47DD-4485-8F9F-A650DD71580B}.Release|x64.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/Server/ServerApp/Program.cs b/Server/ServerApp/Program.cs
index e302e3e..e155880 100644
--- a/Server/ServerApp/Program.cs
+++ b/Server/ServerApp/Program.cs
@@ -164,7 +164,8 @@ namespace ServerApp
 
 		private static void JSONParserTest()
 		{
-			JsonParser jsonP = new JsonParser(null);
+            // FIXME pass the right references to the JsonParser constructor
+			JsonParser jsonP = new JsonParser(null, null);
 			jsonP.ParsePrediction();
 
 			var res = jsonP.GetPredictionForTime(jsonP.Predictions[5].startTime, jsonP.Predictions[20].startTime);
@@ -178,7 +179,8 @@ namespace ServerApp
 		{
 			// TODO nastavit čas
 			IDataParser p = new DataParser(dd);
-            IJsonParser jsonP = new JsonParser(dd);
+            // FIXME pass the right references to the JsonParser constructor
+            IJsonParser jsonP = new JsonParser(dd, null);
             IPredictionController predictionController = new PredictionController(jsonP, p);
             predictionController.Train();
             //var results = predictionController.Predict()
diff --git a/Server/ServerAppFunctionalTests/ParserTests/JisParserTesting.cs b/Server/ServerAppFunctionalTests/ParserTests/JisParserTesting.cs
new file mode 100644
index 0000000..799d95b
--- /dev/null
+++ b/Server/ServerAppFunctionalTests/ParserTests/JisParserTesting.cs
@@ -0,0 +1,287 @@
+﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using ServerApp.Parser.Parsers;
+using System.Collections.Generic;
+using ServerApp.Parser.OutputInfo;
+using Moq;
+using ServerApp.Parser.InputData;
+
+namespace ServerAppFunctionalTests.ParserTests
+{
+    /// <summary>
+    /// Summary description for WeatherParserTesting
+    /// </summary>
+    [TestClass]
+    public class JisParserTesting
+    {
+
+
+        #region Jis parser
+
+        #region Parse days
+        [TestMethod]
+        public void ParseJisDayOne()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<JisInstance> data = new List<JisInstance>();
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
+
+            JisParser target = new JisParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(2, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("MENZA", 3, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("KARMA", 5, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+        }
+
+        [TestMethod]
+        public void ParseJisDayOneFiltering()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<JisInstance> data = new List<JisInstance>();
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 6, 0, 0), 2));
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 17, 0, 0), 2));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
+
+            JisParser target = new JisParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 1, 16, 0, 0));
+
+            Assert.AreEqual(2, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("MENZA", 3, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("KARMA", 5, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+        }
+
+        [TestMethod]
+        public void ParseJisDayTwo()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<JisInstance> data = new List<JisInstance>();
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
+
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 2, 1, 8, 0, 0), 8));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 2, 1, 12, 0, 0), 2));
+            data.Add(new JisInstance("A2", new DateTime(2000, 2, 1, 16, 0, 0), 1));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
+
+            JisParser target = new JisParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 2, 1, 16, 0, 0));
+
+            Assert.AreEqual(4, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("MENZA", 3, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("KARMA", 5, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+
+            Assert.AreEqual(new ActivityInfo("MENZA", 10, new DateTime(2000, 2, 1, 7, 0, 0), 18 - 7), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("KARMA", 1, new DateTime(2000, 2, 1, 7, 0, 0), 18 - 7), retVal[3]);
+        }
+
+        [TestMethod]
+        public void ParseJisDayTwoFiltering()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<JisInstance> data = new List<JisInstance>();
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 6, 0, 0), 2));
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
+
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 2, 1, 8, 0, 0), 8));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 2, 1, 12, 0, 0), 2));
+            data.Add(new JisInstance("A2", new DateTime(2000, 2, 1, 16, 0, 0), 1));
+            data.Add(new JisInstance("A2", new DateTime(2000, 2, 1, 17, 0, 0), 2));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
+
+            JisParser target = new JisParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 2, 1, 16, 0, 0));
+
+            Assert.AreEqual(4, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("MENZA", 3, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("KARMA", 5, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+
+            Assert.AreEqual(new ActivityInfo("MENZA", 10, new DateTime(2000, 2, 1, 7, 0, 0), 18 - 7), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("KARMA", 1, new DateTime(2000, 2, 1, 7, 0, 0), 18 - 7), retVal[3]);
+        }
+
+
+        [TestMethod]
+        public void ParseJisDayNone()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<JisInstance> data = new List<JisInstance>();
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
+
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 2, 15, 0, 0), 2));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
+
+            JisParser target = new JisParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 3), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(0, retVal.Count);
+        }
+        #endregion
+
+        #region Parse hours
+        [TestMethod]
+        public void ParseJisHourlyOne()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<JisInstance> data = new List<JisInstance>();
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 0, 0), 3));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 15, 0), 3));
+
+            /*
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 5));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
+            */
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
+
+            JisParser target = new JisParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(2, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("MENZA", 2, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("KARMA", 6, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[1]);
+        }
+
+        [TestMethod]
+        public void ParseJisDayHourlyMultiple()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<JisInstance> data = new List<JisInstance>();
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 0, 0), 3));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 15, 0), 3));
+
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 11, 0, 0), 5));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 11, 10, 0), 1));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 11, 20, 0), 2));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
+
+            JisParser target = new JisParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(4, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("MENZA", 2, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("KARMA", 6, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("MENZA", 6, new DateTime(2000, 1, 1, 11, 0, 0), 2), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("KARMA", 2, new DateTime(2000, 1, 1, 11, 0, 0), 2), retVal[3]);
+        }
+
+        [TestMethod]
+        public void ParseJisHourlyNone()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<JisInstance> data = new List<JisInstance>();
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 3, 0, 0), 2));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 4, 0, 0), 3));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 5, 15, 0), 3));
+
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 19, 0, 0), 5));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 19, 10, 0), 1));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 19, 20, 0), 2));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
+
+            JisParser target = new JisParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(0, retVal.Count);
+        }
+
+        [TestMethod]
+        public void ParseJisHourlyFiltering()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<JisInstance> data = new List<JisInstance>();
+            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 6, 0, 0), 2));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 0, 0), 3));
+            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 15, 0), 3));
+
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 11, 0, 0), 5));
+            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 18, 10, 0), 1));
+            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 19, 20, 0), 2));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
+
+            JisParser target = new JisParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(3, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("KARMA", 6, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("MENZA", 5, new DateTime(2000, 1, 1, 11, 0, 0), 2), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("MENZA", 1, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[2]);
+        }
+        #endregion
+
+        #endregion
+
+    }
+}
diff --git a/Server/ServerAppFunctionalTests/ParserTests/JsonParserTesting.cs b/Server/ServerAppFunctionalTests/ParserTests/JsonParserTesting.cs
new file mode 100644
index 0000000..b362f7c
--- /dev/null
+++ b/Server/ServerAppFunctionalTests/ParserTests/JsonParserTesting.cs
@@ -0,0 +1,518 @@
+﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using ServerApp.Parser.Parsers;
+using System.Collections.Generic;
+using ServerApp.Parser.OutputInfo;
+using Moq;
+using ServerApp.Parser.InputData;
+using ServerApp.WeatherPredictionParser;
+using ServerApp.DataDownload;
+
+namespace ServerAppFunctionalTests.ParserTests
+{
+    /// <summary>
+    /// Summary description for WeatherParserTesting
+    /// </summary>
+    [TestClass]
+    public class JsonParserTesting
+    {
+
+        #region Json parser
+
+        #region Parsing
+
+        string SetBasicData()
+        {
+            return
+@"{
+    ""current_condition"": [
+        {
+            ""FeelsLikeC"": ""4"",
+            ""cloudcover"": ""100"",
+            ""localObsDateTime"": ""2021-05-25 01:29 PM"",
+            ""observation_time"": ""11:29 AM"",
+            ""precipMM"": ""0.1"",
+            ""temp_C"": ""8"",
+            ""windspeedKmph"": ""13""
+        }
+    ],
+    ""weather"": [
+        {
+                ""astronomy"": [
+                    {
+                    ""sunrise"": ""05:10 AM"",
+                    ""sunset"": ""08:58 PM""
+                    }
+            ],
+            ""date"": ""2021-05-25"",
+            ""hourly"": [
+                {
+                    ""FeelsLikeC"": ""7"",
+                    ""WindGustKmph"": ""31"",
+                    ""chanceofrain"": ""87"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""92"",
+                    ""precipMM"": ""4.5"",
+                    ""tempC"": ""9"",
+                    ""time"": ""0"",
+                    ""windspeedKmph"": ""19""
+                },
+                {
+                    ""FeelsLikeC"": ""8"",
+                    ""WindGustKmph"": ""10"",
+                    ""chanceofrain"": ""50"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""60"",
+                    ""precipMM"": ""2.0"",
+                    ""tempC"": ""9"",
+                    ""time"": ""1200"",
+                    ""windspeedKmph"": ""10""
+                }
+            ]
+        },
+        {
+                ""astronomy"": [
+                    {
+                    ""sunrise"": ""05:09 AM"",
+                    ""sunset"": ""08:59 PM""
+                    }
+            ],
+            ""date"": ""2021-05-26"",
+            ""hourly"": [
+                {
+                    ""FeelsLikeC"": ""10"",
+                    ""WindGustKmph"": ""31"",
+                    ""chanceofrain"": ""0"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""0"",
+                    ""precipMM"": ""0"",
+                    ""tempC"": ""12"",
+                    ""time"": ""1200"",
+                    ""windspeedKmph"": ""19""
+                },
+                                {
+                    ""FeelsLikeC"": ""12"",
+                    ""WindGustKmph"": ""31"",
+                    ""chanceofrain"": ""0"",
+                    ""chanceofsnow"": ""80"",
+                    ""cloudcover"": ""92"",
+                    ""precipMM"": ""4.5"",
+                    ""tempC"": ""19"",
+                    ""time"": ""2100"",
+                    ""windspeedKmph"": ""19""
+                }
+            ]
+        },
+        {
+                ""astronomy"": [
+                    {
+                    ""sunrise"": ""05:08 AM"",
+                    ""sunset"": ""09:00 PM""
+                    }
+            ],
+            ""date"": ""2021-05-27"",
+            ""hourly"": [
+                {
+                    ""FeelsLikeC"": ""17"",
+                    ""WindGustKmph"": ""3"",
+                    ""chanceofrain"": ""7"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""10"",
+                    ""precipMM"": ""0"",
+                    ""tempC"": ""20"",
+                    ""time"": ""1800"",
+                    ""windspeedKmph"": ""9""
+                },
+                {
+                    ""FeelsLikeC"": ""9"",
+                    ""WindGustKmph"": ""31"",
+                    ""chanceofrain"": ""87"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""32"",
+                    ""precipMM"": ""4.5"",
+                    ""tempC"": ""9"",
+                    ""time"": ""2100"",
+                    ""windspeedKmph"": ""10""
+                }
+            ]
+        }
+    ]
+}";
+        }
+
+        string SetAstronomyData()
+        {
+            return
+    @"{
+    ""current_condition"": [
+        {
+            ""FeelsLikeC"": ""4"",
+            ""cloudcover"": ""100"",
+            ""localObsDateTime"": ""2021-05-25 01:29 PM"",
+            ""observation_time"": ""11:29 AM"",
+            ""precipMM"": ""0.1"",
+            ""temp_C"": ""8"",
+            ""windspeedKmph"": ""13""
+        }
+    ],
+    ""weather"": [
+        {
+                ""astronomy"": [
+                    {
+                    ""sunrise"": ""08:10 AM"",
+                    ""sunset"": ""06:58 PM""
+                    }
+            ],
+            ""date"": ""2021-05-25"",
+            ""hourly"": [
+                {
+                    ""FeelsLikeC"": ""7"",
+                    ""WindGustKmph"": ""31"",
+                    ""chanceofrain"": ""87"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""92"",
+                    ""precipMM"": ""4.5"",
+                    ""tempC"": ""9"",
+                    ""time"": ""0"",
+                    ""windspeedKmph"": ""19""
+                },
+                {
+                    ""FeelsLikeC"": ""8"",
+                    ""WindGustKmph"": ""10"",
+                    ""chanceofrain"": ""50"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""60"",
+                    ""precipMM"": ""2.0"",
+                    ""tempC"": ""9"",
+                    ""time"": ""300"",
+                    ""windspeedKmph"": ""10""
+                },
+                {
+                    ""FeelsLikeC"": ""8"",
+                    ""WindGustKmph"": ""10"",
+                    ""chanceofrain"": ""50"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""60"",
+                    ""precipMM"": ""2.0"",
+                    ""tempC"": ""9"",
+                    ""time"": ""600"",
+                    ""windspeedKmph"": ""10""
+                },
+                {
+                    ""FeelsLikeC"": ""8"",
+                    ""WindGustKmph"": ""10"",
+                    ""chanceofrain"": ""50"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""60"",
+                    ""precipMM"": ""2.0"",
+                    ""tempC"": ""9"",
+                    ""time"": ""1500"",
+                    ""windspeedKmph"": ""10""
+                },
+                {
+                    ""FeelsLikeC"": ""8"",
+                    ""WindGustKmph"": ""10"",
+                    ""chanceofrain"": ""50"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""60"",
+                    ""precipMM"": ""2.0"",
+                    ""tempC"": ""9"",
+                    ""time"": ""1800"",
+                    ""windspeedKmph"": ""10""
+                },
+                {
+                    ""FeelsLikeC"": ""8"",
+                    ""WindGustKmph"": ""10"",
+                    ""chanceofrain"": ""50"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""60"",
+                    ""precipMM"": ""2.0"",
+                    ""tempC"": ""9"",
+                    ""time"": ""2100"",
+                    ""windspeedKmph"": ""10""
+                }
+            ]
+        },
+        {
+                ""astronomy"": [
+                    {
+                    ""sunrise"": ""05:09 AM"",
+                    ""sunset"": ""08:59 PM""
+                    }
+            ],
+            ""date"": ""2021-05-26"",
+            ""hourly"": [
+                {
+                    ""FeelsLikeC"": ""10"",
+                    ""WindGustKmph"": ""31"",
+                    ""chanceofrain"": ""0"",
+                    ""chanceofsnow"": ""0"",
+                    ""cloudcover"": ""0"",
+                    ""precipMM"": ""0"",
+                    ""tempC"": ""12"",
+                    ""time"": ""1200"",
+                    ""windspeedKmph"": ""19""
+                },
+                                {
+                    ""FeelsLikeC"": ""12"",
+                    ""WindGustKmph"": ""31"",
+                    ""chanceofrain"": ""0"",
+                    ""chanceofsnow"": ""80"",
+                    ""cloudcover"": ""92"",
+                    ""precipMM"": ""4.5"",
+                    ""tempC"": ""19"",
+                    ""time"": ""2100"",
+                    ""windspeedKmph"": ""19""
+                }
+            ]
+        }
+    ]
+}";
+        }
+
+        [TestMethod]
+        public void JsonParserTestCurrent()
+        {
+            TagInfo.CreateDictionaries();
+
+            string data = SetBasicData();
+
+            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
+            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
+
+            Mock<IDataLoader> l = new Mock<IDataLoader>();
+            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
+
+            JsonParser target = new JsonParser(dl.Object, l.Object);
+
+            target.ParsePrediction();
+            WeatherInfo current = target.Current;
+
+            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 25, 13, 29, 0), 4, 0, 3.611, ValueToConditions.CloudCoverToConditions(100), 0), current);
+        }
+
+        [TestMethod]
+        public void JsonParserTestPrediction()
+        {
+            string data = SetBasicData();
+
+            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
+            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
+
+            Mock<IDataLoader> l = new Mock<IDataLoader>();
+            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
+
+            JsonParser target = new JsonParser(dl.Object, l.Object);
+
+            target.ParsePrediction();
+            List<WeatherInfo> retVal = target.Predictions;
+
+            Assert.AreEqual(6, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 25, 0, 0, 0), 7, 87, 5.277, ValueToConditions.CloudCoverToConditions(92), 12), retVal[0]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 25, 12, 0, 0), 8, 50, 2.77778, ValueToConditions.CloudCoverToConditions(60), 24), retVal[1]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 26, 12, 0, 0), 10, 0, 5.27778, ValueToConditions.CloudCoverToConditions(0), 9), retVal[2]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 26, 21, 0, 0), 12, 80, 5.27778, ValueToConditions.CloudCoverToConditions(92), 21), retVal[3]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 27, 18, 0, 0), 17, 7, 2.5, ValueToConditions.CloudCoverToConditions(10), 3), retVal[4]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 27, 21, 0, 0), 9, 87, 2.77778, WeatherConditions.Dark, 24), retVal[5]);
+        }
+
+        [TestMethod]
+        public void JsonParserEncompassSunRiseSetTimes()
+        {
+            string data = SetAstronomyData();
+
+            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
+            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
+
+            Mock<IDataLoader> l = new Mock<IDataLoader>();
+            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
+
+            JsonParser target = new JsonParser(dl.Object, l.Object);
+
+            target.ParsePrediction();
+            List<WeatherInfo> retVal = target.Predictions;
+
+            Assert.AreEqual(8, retVal.Count);
+            Assert.AreEqual(WeatherConditions.Dark, retVal[0].condition);
+            Assert.AreEqual(WeatherConditions.Dark, retVal[1].condition);
+            Assert.AreNotEqual(WeatherConditions.Dark, retVal[2].condition);
+            Assert.AreNotEqual(WeatherConditions.Dark, retVal[3].condition);
+            Assert.AreEqual(WeatherConditions.Dark, retVal[4].condition);
+            Assert.AreEqual(WeatherConditions.Dark, retVal[5].condition);
+
+            Assert.AreNotEqual(WeatherConditions.Dark, retVal[6].condition);
+            Assert.AreEqual(WeatherConditions.Dark, retVal[7].condition);
+        }
+
+        #endregion
+
+        #region GetPredictionForTime
+        [TestMethod]
+        public void GetPredictionForTimeFilter()
+        {
+            string data = "";
+            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
+            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
+
+            Mock<IDataLoader> l = new Mock<IDataLoader>();
+            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
+
+            JsonParser target = new JsonParser(dl.Object, l.Object);
+
+            List<WeatherInfo> pred = new List<WeatherInfo>();
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
+
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 9, 0, 0), 8, 1, 2, 60_000, 15));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 0, 0, 0), 8, 1, 2, 60_000, 3));
+
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 3, 0, 0), 8, 1, 2, 60_000, 3));
+
+            target.Predictions = pred;
+
+            List<WeatherInfo> retVal = target.GetPredictionForTime(new DateTime(2000, 1, 1, 6, 0, 0), new DateTime(2000, 1, 3, 0, 0, 0));
+
+            Assert.AreEqual(6, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6), retVal[0]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6), retVal[1]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12), retVal[2]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3), retVal[3]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 9, 0, 0), 8, 1, 2, 60_000, 15), retVal[4]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 3, 0, 0, 0), 8, 1, 2, 60_000, 3), retVal[5]);
+        }
+
+        [TestMethod]
+        public void GetPredictionForTimeInvalidInput()
+        {
+            string data = "";
+            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
+            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
+
+            Mock<IDataLoader> l = new Mock<IDataLoader>();
+            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
+
+            JsonParser target = new JsonParser(dl.Object, l.Object);
+
+            List<WeatherInfo> pred = new List<WeatherInfo>();
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
+
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 9, 0, 0), 8, 1, 2, 60_000, 15));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 0, 0, 0), 8, 1, 2, 60_000, 3));
+
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 3, 0, 0), 8, 1, 2, 60_000, 3));
+
+            target.Predictions = pred;
+
+            List<WeatherInfo> retVal = target.GetPredictionForTime(new DateTime(2000, 1, 3, 0, 0, 0), new DateTime(2000, 1, 1, 6, 0, 0));
+            Assert.AreEqual(null, retVal);
+        }
+
+        [TestMethod]
+        public void GetPredictionForTimeAllTo()
+        {
+            string data = "";
+            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
+            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
+
+            Mock<IDataLoader> l = new Mock<IDataLoader>();
+            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
+
+            JsonParser target = new JsonParser(dl.Object, l.Object);
+
+            List<WeatherInfo> pred = new List<WeatherInfo>();
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
+
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 9, 0, 0), 8, 1, 2, 60_000, 15));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 0, 0, 0), 8, 1, 2, 60_000, 3));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 3, 0, 0), 8, 1, 2, 60_000, 3));
+
+            target.Predictions = pred;
+
+            List<WeatherInfo> retVal = target.GetPredictionForTime(DateTime.MinValue, new DateTime(2000, 1, 2, 6, 0, 0));
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3), retVal[0]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6), retVal[1]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6), retVal[2]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12), retVal[3]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3), retVal[4]);
+        }
+
+        [TestMethod]
+        public void GetPredictionForTimeAllFrom()
+        {
+            string data = "";
+            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
+            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
+
+            Mock<IDataLoader> l = new Mock<IDataLoader>();
+            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
+
+            JsonParser target = new JsonParser(dl.Object, l.Object);
+
+            List<WeatherInfo> pred = new List<WeatherInfo>();
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 3));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 6, 0, 0), 8, 1, 2, 60_000, 3));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 9, 0, 0), 8, 1, 2, 60_000, 3));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
+
+            target.Predictions = pred;
+
+            List<WeatherInfo> retVal = target.GetPredictionForTime(new DateTime(2000, 1, 1, 12, 0, 0), DateTime.MaxValue);
+
+            Assert.AreEqual(3, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6), retVal[0]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12), retVal[1]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3), retVal[2]);
+        }
+
+        public void GetPredictionForTimeAll()
+        {
+
+            // TODO make an input file
+            string data = "";
+            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
+            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
+
+            Mock<IDataLoader> l = new Mock<IDataLoader>();
+            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
+
+            JsonParser target = new JsonParser(dl.Object, l.Object);
+
+            List<WeatherInfo> pred = new List<WeatherInfo>();
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
+            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
+
+            target.Predictions = pred;
+
+            List<WeatherInfo> retVal = target.GetPredictionForTime(DateTime.MinValue, DateTime.MaxValue);
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3), retVal[0]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6), retVal[1]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6), retVal[2]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12), retVal[3]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3), retVal[4]);
+        }
+        #endregion
+
+        #endregion
+    }
+}
diff --git a/Server/ServerAppFunctionalTests/ParserTests/LoginParserTesting.cs b/Server/ServerAppFunctionalTests/ParserTests/LoginParserTesting.cs
new file mode 100644
index 0000000..31415a3
--- /dev/null
+++ b/Server/ServerAppFunctionalTests/ParserTests/LoginParserTesting.cs
@@ -0,0 +1,314 @@
+﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using ServerApp.Parser.Parsers;
+using System.Collections.Generic;
+using ServerApp.Parser.OutputInfo;
+using Moq;
+using ServerApp.Parser.InputData;
+
+namespace ServerAppFunctionalTests.ParserTests
+{
+    /// <summary>
+    /// Summary description for WeatherParserTesting
+    /// </summary>
+    [TestClass]
+    public class LoginParserTesting
+    {
+
+        #region Login parser
+
+        #region Parse days
+        [TestMethod]
+        public void ParseLoginDayOne()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(2, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+        }
+
+        [TestMethod]
+        public void ParseLoginDayOneFiltering()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 6, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 1, 16, 0, 0));
+
+            Assert.AreEqual(2, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+        }
+
+        [TestMethod]
+        public void ParseLoginDayTwo()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 3, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EU", "Učebna", "EU-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 3, 0, 0, 0));
+
+            Assert.AreEqual(4, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FEL", 5, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[3]);
+        }
+
+        [TestMethod]
+        public void ParseLoginDayTwoFiltering()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 6, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 3, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EU", "Učebna", "EU-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 19, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 3, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 3, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 3, 0, 0, 0));
+
+            Assert.AreEqual(4, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FEL", 5, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[3]);
+        }
+
+
+        [TestMethod]
+        public void ParseLoginDayNone()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 3, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EU", "Učebna", "EU-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 1, 9, 0, 0));
+
+            Assert.AreEqual(0, retVal.Count);
+        }
+        #endregion
+
+        #region Parse hours
+        [TestMethod]
+        public void ParseLoginHourlyOne()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 13, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 14, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[4]);
+        }
+
+        [TestMethod]
+        public void ParseLoginDayHourlyMultiple()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 13, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 14, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 17, 0, 0), 2), retVal[4]);
+        }
+
+        [TestMethod]
+        public void ParseLoginHourlyFiltering()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 13, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 14, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 19, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 17, 0, 0), 2), retVal[4]);
+        }
+
+        [TestMethod]
+        public void ParseLoginHourlyNone()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 9, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 19, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 19, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 10, 0, 0), new DateTime(2000, 1, 2, 10, 0, 0));
+
+            Assert.AreEqual(0, retVal.Count);
+        }
+        #endregion
+
+        #endregion
+
+    }
+}
diff --git a/Server/ServerAppFunctionalTests/ParserTests/TestingParser.cs b/Server/ServerAppFunctionalTests/ParserTests/TestingParser.cs
new file mode 100644
index 0000000..c5f873d
--- /dev/null
+++ b/Server/ServerAppFunctionalTests/ParserTests/TestingParser.cs
@@ -0,0 +1,181 @@
+﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using ServerApp.Parser.Parsers;
+using System.Collections.Generic;
+using ServerApp.Parser.OutputInfo;
+
+namespace ServerAppFunctionalTests.ParserTests
+{
+
+    [TestClass]
+    public class TestingParser
+    {
+        [TestMethod]
+        public void AbstactClassTest()
+        {
+            IDataParser p = new DataParser(null);
+            List<ActivityInfo> aa = p.AttendanceList;
+            List<WeatherInfo> wa = p.WeatherList;
+
+            DataParser pp = (DataParser)p;
+            List<ActivityInfo> ap = pp.AttendanceList;
+            List<WeatherInfo> wp = pp.WeatherList;
+
+            Assert.AreEqual(aa, ap);
+            Assert.AreEqual(wa, wp);
+        }
+
+        // ------------------------------------ MERGE LISTS -------------------------------------
+
+        #region Merge lists
+        [TestMethod]
+        public void MergeListsNull()
+        {
+            DataParser target = new DataParser(null);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = null;
+            List<ActivityInfo> pc = null;
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
+            Assert.AreEqual(0, retVal.Count);
+        }
+
+        [TestMethod]
+        public void MergeListsJisNull()
+        {
+            DataParser target = new DataParser(null);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = null;
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
+            Assert.AreEqual(pc, retVal);
+        }
+
+        [TestMethod]
+        public void MergeListsPcNull()
+        {
+            DataParser target = new DataParser(null);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = null;
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
+            Assert.AreEqual(jis, retVal);
+        }
+
+        [TestMethod]
+        public void MergeListsOneNoOverlap()
+        {
+            DataParser target = new DataParser(null);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 15, 0, 0), 3));
+            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 18, 0, 0), 3));
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
+
+            Assert.AreEqual(2, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 18, 0, 0), 3), retVal[1]);
+        }
+
+        [TestMethod]
+        public void MergeListsOneOverlap()
+        {
+            DataParser target = new DataParser(null);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 15, 0, 0), 3));
+            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 15, 0, 0), 3));
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
+
+            Assert.AreEqual(1, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FAV", 8, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[0]);
+        }
+
+        [TestMethod]
+        public void MergeListsTwoNoOverlap()
+        {
+            DataParser target = new DataParser(null);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 9, 0, 0), 3));
+            jis.Add(new ActivityInfo("FAV", 1, new DateTime(2001, 1, 1, 15, 0, 0), 3));
+            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3));
+            pc.Add(new ActivityInfo("FAV", 2, new DateTime(2001, 1, 1, 18, 0, 0), 3));
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
+
+            Assert.AreEqual(4, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 9, 0, 0), 3), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FAV", 1, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FAV", 2, new DateTime(2001, 1, 1, 18, 0, 0), 3), retVal[3]);
+        }
+
+        [TestMethod]
+        public void MergeListsTwoOverlap()
+        {
+            DataParser target = new DataParser(null);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 9, 0, 0), 3));
+            jis.Add(new ActivityInfo("FAV", 1, new DateTime(2001, 1, 1, 15, 0, 0), 3));
+            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3));
+            pc.Add(new ActivityInfo("FAV", 2, new DateTime(2001, 1, 1, 15, 0, 0), 3));
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
+
+            Assert.AreEqual(3, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 9, 0, 0), 3), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[2]);
+        }
+
+        [TestMethod]
+        public void MergeListsMultiple()
+        {
+            DataParser target = new DataParser(null);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 10, 9, 0, 0), 3));
+            jis.Add(new ActivityInfo("FAV", 1, new DateTime(2001, 1, 1, 15, 0, 0), 3));
+            jis.Add(new ActivityInfo("FDU", 3, new DateTime(2001, 4, 1, 15, 0, 0), 3));
+
+            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3));
+            pc.Add(new ActivityInfo("FAV", 2, new DateTime(2001, 1, 1, 15, 0, 0), 3));
+            pc.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 4, 1, 15, 0, 0), 3));
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 10, 9, 0, 0), 3), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FDU", 3, new DateTime(2001, 4, 1, 15, 0, 0), 3), retVal[3]);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2001, 4, 1, 15, 0, 0), 3), retVal[4]);
+        }
+        #endregion
+
+    }
+}
diff --git a/Server/ServerAppFunctionalTests/ParserTests/WeatherParserTesting.cs b/Server/ServerAppFunctionalTests/ParserTests/WeatherParserTesting.cs
new file mode 100644
index 0000000..542044a
--- /dev/null
+++ b/Server/ServerAppFunctionalTests/ParserTests/WeatherParserTesting.cs
@@ -0,0 +1,274 @@
+﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System;
+using ServerApp.Parser.Parsers;
+using System.Collections.Generic;
+using ServerApp.Parser.OutputInfo;
+using Moq;
+using ServerApp.Parser.InputData;
+
+namespace ServerAppFunctionalTests.ParserTests
+{
+    /// <summary>
+    /// Summary description for WeatherParserTesting
+    /// </summary>
+    [TestClass]
+    public class WeatherParserTesting
+    {
+
+        #region Weather parser
+
+        #region Parse days
+        [TestMethod]
+        public void ParseWeatherDayOne()
+        {
+            string path = "";
+            List<WeatherInstance> data = new List<WeatherInstance>();
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 7, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 10, 3, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 12, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
+
+            WeatherParser target = new WeatherParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(1, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 8, 50, 1.25, 10_000, 18 - 7), retVal[0]);
+        }
+
+        [TestMethod]
+        public void ParseWeatherDayOneFiltering()
+        {
+            string path = "";
+            List<WeatherInstance> data = new List<WeatherInstance>();
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 7, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 10, 3, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 12, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 13, 0, 0), 12, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
+
+            WeatherParser target = new WeatherParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsDays", path, new DateTime(2000, 1, 1, 9, 0, 0), new DateTime(2000, 1, 1, 15, 0, 0));
+
+            Assert.AreEqual(1, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 9.75, 25, 1.75, 10_000, 18 - 7), retVal[0]);
+        }
+
+        [TestMethod]
+        public void ParseWeatherDayTwo()
+        {
+            string path = "";
+            List<WeatherInstance> data = new List<WeatherInstance>();
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 3, 3, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 12, 0, 0), 5, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
+
+            WeatherParser target = new WeatherParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(2, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 6, 100, 1, 10_000, 18 - 7), retVal[0]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 7, 0, 0), 10, 25, 2, 10_000, 18 - 7), retVal[1]);
+        }
+
+        [TestMethod]
+        public void ParseWeatherDayTwoFiltering()
+        {
+            string path = "";
+            List<WeatherInstance> data = new List<WeatherInstance>();
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 3, 3, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 12, 0, 0), 5, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
+
+            WeatherParser target = new WeatherParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsDays", path, new DateTime(2000, 1, 1, 8, 0, 0), new DateTime(2000, 1, 1, 11, 0, 0));
+
+            Assert.AreEqual(1, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 6, 100, 1, 10_000, 18 - 7), retVal[0]);
+            //Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 7, 0, 0), 10, 25, 2, 10_000, 18 - 7), retVal[1]);
+        }
+        #endregion
+
+        #region Parse hours
+        [TestMethod]
+        public void ParseWeatherHourOne()
+        {
+            string path = "";
+            List<WeatherInstance> data = new List<WeatherInstance>();
+
+            // day 1
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
+
+            WeatherParser target = new WeatherParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 8, 0, 0), new DateTime(2001, 1, 1, 11, 0, 0));
+
+            Assert.AreEqual(1, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 5, 100, 0, (double)0, 2), retVal[0]);
+        }
+
+        [TestMethod]
+        public void ParseWeatherHourMultiple()
+        {
+            string path = "";
+            List<WeatherInstance> data = new List<WeatherInstance>();
+
+            // day 1
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 3, 3, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+            // day 2
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 12, 0, 0), 5, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Sunny) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 15, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
+
+            WeatherParser target = new WeatherParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 8, 0, 0), new DateTime(2001, 1, 1, 11, 0, 0));
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 5, 100, 0, (double)0, 2), retVal[0]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 9, 0, 0), 6.5, 100, 1.5, 10_000, 2), retVal[1]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 11, 0, 0), 5, 0, 2, 60_000, 2), retVal[2]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 13, 0, 0), 10, 25, 2, 10_000, 2), retVal[3]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 15, 0, 0), 15, 40, 2, 10_000, 2), retVal[4]);
+        }
+
+
+        [TestMethod]
+        public void ParseWeatherHourFiltering()
+        {
+            string path = "";
+            List<WeatherInstance> data = new List<WeatherInstance>();
+
+            // day 1
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 3, 3, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+            // day 2
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 12, 0, 0), 5, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Sunny) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 15, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
+
+            WeatherParser target = new WeatherParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 9, 0, 0), new DateTime(2000, 2, 1, 13, 0, 0));
+
+            Assert.AreEqual(3, retVal.Count);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 9, 0, 0), 6.5, 100, 1.5, 10_000, 2), retVal[0]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 11, 0, 0), 5, 0, 2, 60_000, 2), retVal[1]);
+            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 13, 0, 0), 10, 33, 2, 10_000, 2), retVal[2]);
+        }
+
+        [TestMethod]
+        public void ParseWeatherHourNone()
+        {
+            string path = "";
+            List<WeatherInstance> data = new List<WeatherInstance>();
+
+            // day 1
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
+
+            // day 2
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 17, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
+
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
+
+            WeatherParser target = new WeatherParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> jis = new List<ActivityInfo>();
+            List<ActivityInfo> pc = new List<ActivityInfo>();
+
+            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 10, 0, 0), new DateTime(2000, 2, 1, 15, 0, 0));
+
+            Assert.AreEqual(0, retVal.Count);
+        }
+        #endregion
+
+        #endregion
+    }
+}
diff --git a/Server/ServerAppFunctionalTests/PrivateObjectPrivateType.cs b/Server/ServerAppFunctionalTests/PrivateObjectPrivateType.cs
new file mode 100644
index 0000000..e990168
--- /dev/null
+++ b/Server/ServerAppFunctionalTests/PrivateObjectPrivateType.cs
@@ -0,0 +1,1864 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Reflection;
+
+namespace Microsoft.VisualStudio.TestTools.UnitTesting
+{
+    /// <summary>
+    /// This class represents the live NON public INTERNAL object in the system
+    /// </summary>
+    public class PrivateObject
+    {
+        // bind everything
+        private const BindingFlags BindToEveryThing = BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;
+
+        private static BindingFlags constructorFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance | BindingFlags.NonPublic;
+
+        private object target;     // automatically initialized to null
+        private Type originalType; // automatically initialized to null
+
+        private Dictionary<string, LinkedList<MethodInfo>> methodCache; // automatically initialized to null
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PrivateObject"/> class that contains
+        /// the already existing object of the private class
+        /// </summary>
+        /// <param name="obj"> object that serves as starting point to reach the private members</param>
+        /// <param name="memberToAccess">the derefrencing string using . that points to the object to be retrived as in m_X.m_Y.m_Z</param>
+        public PrivateObject(object obj, string memberToAccess)
+        {
+            ValidateAccessString(memberToAccess);
+
+            PrivateObject temp = obj as PrivateObject;
+            if (temp == null)
+            {
+                temp = new PrivateObject(obj);
+            }
+
+            // Split The access string
+            string[] arr = memberToAccess.Split(new char[] { '.' });
+
+            for (int i = 0; i < arr.Length; i++)
+            {
+                object next = temp.InvokeHelper(arr[i], BindToEveryThing | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty, null, CultureInfo.InvariantCulture);
+                temp = new PrivateObject(next);
+            }
+
+            this.target = temp.target;
+            this.originalType = temp.originalType;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PrivateObject"/> class that wraps the
+        /// specified type.
+        /// </summary>
+        /// <param name="assemblyName">Name of the assembly</param>
+        /// <param name="typeName">fully qualified name</param>
+        /// <param name="args">Argmenets to pass to the constructor</param>
+        public PrivateObject(string assemblyName, string typeName, params object[] args)
+            : this(assemblyName, typeName, null, args)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PrivateObject"/> class that wraps the
+        /// specified type.
+        /// </summary>
+        /// <param name="assemblyName">Name of the assembly</param>
+        /// <param name="typeName">fully qualified name</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the constructor to get</param>
+        /// <param name="args">Argmenets to pass to the constructor</param>
+        public PrivateObject(string assemblyName, string typeName, Type[] parameterTypes, object[] args)
+            : this(Type.GetType(string.Format(CultureInfo.InvariantCulture, "{0}, {1}", typeName, assemblyName), false), parameterTypes, args)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PrivateObject"/> class that wraps the
+        /// specified type.
+        /// </summary>
+        /// <param name="type">type of the object to create</param>
+        /// <param name="args">Argmenets to pass to the constructor</param>
+        public PrivateObject(Type type, params object[] args)
+            : this(type, null, args)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PrivateObject"/> class that wraps the
+        /// specified type.
+        /// </summary>
+        /// <param name="type">type of the object to create</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the constructor to get</param>
+        /// <param name="args">Argmenets to pass to the constructor</param>
+        public PrivateObject(Type type, Type[] parameterTypes, object[] args)
+        {
+            object o;
+            if (parameterTypes != null)
+            {
+                ConstructorInfo ci = type.GetConstructor(BindToEveryThing, null, parameterTypes, null);
+                if (ci == null)
+                {
+                    throw new ArgumentException("The constructor with the specified signature could not be found. You might need to regenerate your private accessor, or the member may be private and defined on a base class. If the latter is true, you need to pass the type that defines the member into PrivateObject's constructor.");
+                }
+
+                try
+                {
+                    o = ci.Invoke(args);
+                }
+                catch (TargetInvocationException e)
+                {
+                    Debug.Assert(e.InnerException != null, "Inner exception should not be null.");
+                    if (e.InnerException != null)
+                    {
+                        throw e.InnerException;
+                    }
+
+                    throw;
+                }
+            }
+            else
+            {
+                o = Activator.CreateInstance(type, constructorFlags, null, args, null);
+            }
+
+            this.ConstructFrom(o);
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PrivateObject"/> class that wraps
+        /// the given object.
+        /// </summary>
+        /// <param name="obj">object to wrap</param>
+        public PrivateObject(object obj)
+        {
+            this.ConstructFrom(obj);
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PrivateObject"/> class that wraps
+        /// the given object.
+        /// </summary>
+        /// <param name="obj">object to wrap</param>
+        /// <param name="type">PrivateType object</param>
+        public PrivateObject(object obj, PrivateType type)
+        {
+            this.target = obj;
+            this.originalType = type.ReferencedType;
+        }
+
+        /// <summary>
+        /// Gets or sets the target
+        /// </summary>
+        public object Target
+        {
+            get
+            {
+                return this.target;
+            }
+
+            set
+            {
+                this.target = value;
+                this.originalType = value.GetType();
+            }
+        }
+
+        /// <summary>
+        /// Gets the type of underlying object
+        /// </summary>
+        public Type RealType
+        {
+            get
+            {
+                return this.originalType;
+            }
+        }
+
+        private Dictionary<string, LinkedList<MethodInfo>> GenericMethodCache
+        {
+            get
+            {
+                if (this.methodCache == null)
+                {
+                    this.BuildGenericMethodCacheForType(this.originalType);
+                }
+
+                Debug.Assert(this.methodCache != null, "Invalid method cache for type.");
+
+                return this.methodCache;
+            }
+        }
+
+        /// <summary>
+        /// returns the hash code of the target object
+        /// </summary>
+        /// <returns>int representing hashcode of the target object</returns>
+        public override int GetHashCode()
+        {
+            Debug.Assert(this.target != null, "target should not be null.");
+            return this.target.GetHashCode();
+        }
+
+        /// <summary>
+        /// Equals
+        /// </summary>
+        /// <param name="obj">Object with whom to compare</param>
+        /// <returns>returns true if the objects are equal.</returns>
+        public override bool Equals(object obj)
+        {
+            if (this != obj)
+            {
+                Debug.Assert(this.target != null, "target should not be null.");
+                if (typeof(PrivateObject) == obj?.GetType())
+                {
+                    return this.target.Equals(((PrivateObject)obj).target);
+                }
+                else
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, params object[] args)
+        {
+            return this.Invoke(name, null, args, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to get.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, Type[] parameterTypes, object[] args)
+        {
+            return this.Invoke(name, parameterTypes, args, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to get.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <param name="typeArguments">An array of types corresponding to the types of the generic arguments.</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, Type[] parameterTypes, object[] args, Type[] typeArguments)
+        {
+            return this.Invoke(name, BindToEveryThing, parameterTypes, args, CultureInfo.InvariantCulture, typeArguments);
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <param name="culture">Culture info</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, object[] args, CultureInfo culture)
+        {
+            return this.Invoke(name, null, args, culture);
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to get.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <param name="culture">Culture info</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, Type[] parameterTypes, object[] args, CultureInfo culture)
+        {
+            return this.Invoke(name, BindToEveryThing, parameterTypes, args, culture);
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, BindingFlags bindingFlags, params object[] args)
+        {
+            return this.Invoke(name, bindingFlags, null, args, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to get.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, BindingFlags bindingFlags, Type[] parameterTypes, object[] args)
+        {
+            return this.Invoke(name, bindingFlags, parameterTypes, args, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <param name="culture">Culture info</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, BindingFlags bindingFlags, object[] args, CultureInfo culture)
+        {
+            return this.Invoke(name, bindingFlags, null, args, culture);
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to get.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <param name="culture">Culture info</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, BindingFlags bindingFlags, Type[] parameterTypes, object[] args, CultureInfo culture)
+        {
+            return this.Invoke(name, bindingFlags, parameterTypes, args, culture, null);
+        }
+
+        /// <summary>
+        /// Invokes the specified method
+        /// </summary>
+        /// <param name="name">Name of the method</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to get.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <param name="culture">Culture info</param>
+        /// <param name="typeArguments">An array of types corresponding to the types of the generic arguments.</param>
+        /// <returns>Result of method call</returns>
+        public object Invoke(string name, BindingFlags bindingFlags, Type[] parameterTypes, object[] args, CultureInfo culture, Type[] typeArguments)
+        {
+            if (parameterTypes != null)
+            {
+                bindingFlags |= BindToEveryThing | BindingFlags.Instance;
+
+                // Fix up the parameter types
+                MethodInfo member = this.originalType.GetMethod(name, bindingFlags, null, parameterTypes, null);
+
+                // If the method was not found and type arguments were provided for generic paramaters,
+                // attempt to look up a generic method.
+                if ((member == null) && (typeArguments != null))
+                {
+                    // This method may contain generic parameters...if so, the previous call to
+                    // GetMethod() will fail because it doesn't fully support generic parameters.
+
+                    // Look in the method cache to see if there is a generic method
+                    // on the incoming type that contains the correct signature.
+                    member = this.GetGenericMethodFromCache(name, parameterTypes, typeArguments, bindingFlags, null);
+                }
+
+                if (member == null)
+                {
+                    throw new ArgumentException(
+                        string.Format(CultureInfo.CurrentCulture, "The member specified ({0}) could not be found. You might need to regenerate your private accessor, or the member may be private and defined on a base class. If the latter is true, you need to pass the type that defines the member into PrivateObject's constructor.", name));
+                }
+
+                try
+                {
+                    if (member.IsGenericMethodDefinition)
+                    {
+                        MethodInfo constructed = member.MakeGenericMethod(typeArguments);
+                        return constructed.Invoke(this.target, bindingFlags, null, args, culture);
+                    }
+                    else
+                    {
+                        return member.Invoke(this.target, bindingFlags, null, args, culture);
+                    }
+                }
+                catch (TargetInvocationException e)
+                {
+                    Debug.Assert(e.InnerException != null, "Inner exception should not be null.");
+                    if (e.InnerException != null)
+                    {
+                        throw e.InnerException;
+                    }
+
+                    throw;
+                }
+            }
+            else
+            {
+                return this.InvokeHelper(name, bindingFlags | BindingFlags.InvokeMethod, args, culture);
+            }
+        }
+
+        /// <summary>
+        /// Gets the array element using array of subsrcipts for each dimension
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="indices">the indices of array</param>
+        /// <returns>An arrya of elements.</returns>
+        public object GetArrayElement(string name, params int[] indices)
+        {
+            return this.GetArrayElement(name, BindToEveryThing, indices);
+        }
+
+        /// <summary>
+        /// Sets the array element using array of subsrcipts for each dimension
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="value">Value to set</param>
+        /// <param name="indices">the indices of array</param>
+        public void SetArrayElement(string name, object value, params int[] indices)
+        {
+            this.SetArrayElement(name, BindToEveryThing, value, indices);
+        }
+
+        /// <summary>
+        /// Gets the array element using array of subsrcipts for each dimension
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="indices">the indices of array</param>
+        /// <returns>An arrya of elements.</returns>
+        public object GetArrayElement(string name, BindingFlags bindingFlags, params int[] indices)
+        {
+            Array arr = (Array)this.InvokeHelper(name, BindingFlags.GetField | bindingFlags, null, CultureInfo.InvariantCulture);
+            return arr.GetValue(indices);
+        }
+
+        /// <summary>
+        /// Sets the array element using array of subsrcipts for each dimension
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="value">Value to set</param>
+        /// <param name="indices">the indices of array</param>
+        public void SetArrayElement(string name, BindingFlags bindingFlags, object value, params int[] indices)
+        {
+            Array arr = (Array)this.InvokeHelper(name, BindingFlags.GetField | bindingFlags, null, CultureInfo.InvariantCulture);
+            arr.SetValue(value, indices);
+        }
+
+        /// <summary>
+        /// Get the field
+        /// </summary>
+        /// <param name="name">Name of the field</param>
+        /// <returns>The field.</returns>
+        public object GetField(string name)
+        {
+            return this.GetField(name, BindToEveryThing);
+        }
+
+        /// <summary>
+        /// Sets the field
+        /// </summary>
+        /// <param name="name">Name of the field</param>
+        /// <param name="value">value to set</param>
+        public void SetField(string name, object value)
+        {
+            this.SetField(name, BindToEveryThing, value);
+        }
+
+        /// <summary>
+        /// Gets the field
+        /// </summary>
+        /// <param name="name">Name of the field</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <returns>The field.</returns>
+        public object GetField(string name, BindingFlags bindingFlags)
+        {
+            return this.InvokeHelper(name, BindingFlags.GetField | bindingFlags, null, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Sets the field
+        /// </summary>
+        /// <param name="name">Name of the field</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="value">value to set</param>
+        public void SetField(string name, BindingFlags bindingFlags, object value)
+        {
+            this.InvokeHelper(name, BindingFlags.SetField | bindingFlags, new object[] { value }, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Get the field or property
+        /// </summary>
+        /// <param name="name">Name of the field or property</param>
+        /// <returns>The field or property.</returns>
+        public object GetFieldOrProperty(string name)
+        {
+            return this.GetFieldOrProperty(name, BindToEveryThing);
+        }
+
+        /// <summary>
+        /// Sets the field or property
+        /// </summary>
+        /// <param name="name">Name of the field or property</param>
+        /// <param name="value">value to set</param>
+        public void SetFieldOrProperty(string name, object value)
+        {
+            this.SetFieldOrProperty(name, BindToEveryThing, value);
+        }
+
+        /// <summary>
+        /// Gets the field or property
+        /// </summary>
+        /// <param name="name">Name of the field or property</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <returns>The field or property.</returns>
+        public object GetFieldOrProperty(string name, BindingFlags bindingFlags)
+        {
+            return this.InvokeHelper(name, BindingFlags.GetField | BindingFlags.GetProperty | bindingFlags, null, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Sets the field or property
+        /// </summary>
+        /// <param name="name">Name of the field or property</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="value">value to set</param>
+        public void SetFieldOrProperty(string name, BindingFlags bindingFlags, object value)
+        {
+            this.InvokeHelper(name, BindingFlags.SetField | BindingFlags.SetProperty | bindingFlags, new object[] { value }, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Gets the property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>The property.</returns>
+        public object GetProperty(string name, params object[] args)
+        {
+            return this.GetProperty(name, null, args);
+        }
+
+        /// <summary>
+        /// Gets the property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the indexed property.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>The property.</returns>
+        public object GetProperty(string name, Type[] parameterTypes, object[] args)
+        {
+            return this.GetProperty(name, BindToEveryThing, parameterTypes, args);
+        }
+
+        /// <summary>
+        /// Set the property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="value">value to set</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        public void SetProperty(string name, object value, params object[] args)
+        {
+            this.SetProperty(name, null, value, args);
+        }
+
+        /// <summary>
+        /// Set the property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the indexed property.</param>
+        /// <param name="value">value to set</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        public void SetProperty(string name, Type[] parameterTypes, object value, object[] args)
+        {
+            this.SetProperty(name, BindToEveryThing, value, parameterTypes, args);
+        }
+
+        /// <summary>
+        /// Gets the property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>The property.</returns>
+        public object GetProperty(string name, BindingFlags bindingFlags, params object[] args)
+        {
+            return this.GetProperty(name, bindingFlags, null, args);
+        }
+
+        /// <summary>
+        /// Gets the property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the indexed property.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>The property.</returns>
+        public object GetProperty(string name, BindingFlags bindingFlags, Type[] parameterTypes, object[] args)
+        {
+            if (parameterTypes != null)
+            {
+                PropertyInfo pi = this.originalType.GetProperty(name, bindingFlags, null, null, parameterTypes, null);
+                if (pi == null)
+                {
+                    throw new ArgumentException(
+                        string.Format(CultureInfo.CurrentCulture, "The member specified ({0}) could not be found. You might need to regenerate your private accessor, or the member may be private and defined on a base class. If the latter is true, you need to pass the type that defines the member into PrivateObject's constructor.", name));
+                }
+
+                return pi.GetValue(this.target, args);
+            }
+            else
+            {
+                return this.InvokeHelper(name, bindingFlags | BindingFlags.GetProperty, args, null);
+            }
+        }
+
+        /// <summary>
+        /// Sets the property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="value">value to set</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        public void SetProperty(string name, BindingFlags bindingFlags, object value, params object[] args)
+        {
+            this.SetProperty(name, bindingFlags, value, null, args);
+        }
+
+        /// <summary>
+        /// Sets the property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="bindingFlags">A bitmask comprised of one or more <see cref="T:System.Reflection.BindingFlags"/> that specify how the search is conducted.</param>
+        /// <param name="value">value to set</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the indexed property.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        public void SetProperty(string name, BindingFlags bindingFlags, object value, Type[] parameterTypes, object[] args)
+        {
+            if (parameterTypes != null)
+            {
+                PropertyInfo pi = this.originalType.GetProperty(name, bindingFlags, null, null, parameterTypes, null);
+                if (pi == null)
+                {
+                    throw new ArgumentException(
+                        string.Format(CultureInfo.CurrentCulture, "The member specified ({0}) could not be found. You might need to regenerate your private accessor, or the member may be private and defined on a base class. If the latter is true, you need to pass the type that defines the member into PrivateObject's constructor.", name));
+                }
+
+                pi.SetValue(this.target, value, args);
+            }
+            else
+            {
+                object[] pass = new object[(args?.Length ?? 0) + 1];
+                pass[0] = value;
+                args?.CopyTo(pass, 1);
+                this.InvokeHelper(name, bindingFlags | BindingFlags.SetProperty, pass, null);
+            }
+        }
+
+        /// <summary>
+        /// Validate access string
+        /// </summary>
+        /// <param name="access"> access string</param>
+        private static void ValidateAccessString(string access)
+        {
+            if (access.Length == 0)
+            {
+                throw new ArgumentException("Access string has invalid syntax.");
+            }
+
+            string[] arr = access.Split('.');
+            foreach (string str in arr)
+            {
+                if ((str.Length == 0) || (str.IndexOfAny(new char[] { ' ', '\t', '\n' }) != -1))
+                {
+                    throw new ArgumentException("Access string has invalid syntax.");
+                }
+            }
+        }
+
+        /// <summary>
+        /// Invokes the memeber
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="bindingFlags">Additional attributes</param>
+        /// <param name="args">Arguments for the invocation</param>
+        /// <param name="culture">Culture</param>
+        /// <returns>Result of the invocation</returns>
+        private object InvokeHelper(string name, BindingFlags bindingFlags, object[] args, CultureInfo culture)
+        {
+            Debug.Assert(this.target != null, "Internal Error: Null reference is returned for internal object");
+
+            // Invoke the actual Method
+            try
+            {
+                return this.originalType.InvokeMember(name, bindingFlags, null, this.target, args, culture);
+            }
+            catch (TargetInvocationException e)
+            {
+                Debug.Assert(e.InnerException != null, "Inner exception should not be null.");
+                if (e.InnerException != null)
+                {
+                    throw e.InnerException;
+                }
+
+                throw;
+            }
+        }
+
+        private void ConstructFrom(object obj)
+        {
+            this.target = obj;
+            this.originalType = obj.GetType();
+        }
+
+        private void BuildGenericMethodCacheForType(Type t)
+        {
+            Debug.Assert(t != null, "type should not be null.");
+            this.methodCache = new Dictionary<string, LinkedList<MethodInfo>>();
+
+            MethodInfo[] members = t.GetMethods(BindToEveryThing);
+            LinkedList<MethodInfo> listByName; // automatically initialized to null
+
+            foreach (MethodInfo member in members)
+            {
+                if (member.IsGenericMethod || member.IsGenericMethodDefinition)
+                {
+                    if (!this.GenericMethodCache.TryGetValue(member.Name, out listByName))
+                    {
+                        listByName = new LinkedList<MethodInfo>();
+                        this.GenericMethodCache.Add(member.Name, listByName);
+                    }
+
+                    Debug.Assert(listByName != null, "list should not be null.");
+                    listByName.AddLast(member);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Extracts the most appropriate generic method signature from the current private type.
+        /// </summary>
+        /// <param name="methodName">The name of the method in which to search the signature cache.</param>
+        /// <param name="parameterTypes">An array of types corresponding to the types of the parameters in which to search.</param>
+        /// <param name="typeArguments">An array of types corresponding to the types of the generic arguments.</param>
+        /// <param name="bindingFlags"><see cref="BindingFlags"/> to further filter the method signatures.</param>
+        /// <param name="modifiers">Modifiers for parameters.</param>
+        /// <returns>A methodinfo instance.</returns>
+        private MethodInfo GetGenericMethodFromCache(string methodName, Type[] parameterTypes, Type[] typeArguments, BindingFlags bindingFlags, ParameterModifier[] modifiers)
+        {
+            Debug.Assert(!string.IsNullOrEmpty(methodName), "Invalid method name.");
+            Debug.Assert(parameterTypes != null, "Invalid parameter type array.");
+            Debug.Assert(typeArguments != null, "Invalid type arguments array.");
+
+            // Build a preliminary list of method candidates that contain roughly the same signature.
+            var methodCandidates = this.GetMethodCandidates(methodName, parameterTypes, typeArguments, bindingFlags, modifiers);
+
+            // Search of ambiguous methods (methods with the same signature).
+            MethodInfo[] finalCandidates = new MethodInfo[methodCandidates.Count];
+            methodCandidates.CopyTo(finalCandidates, 0);
+
+            if ((parameterTypes != null) && (parameterTypes.Length == 0))
+            {
+                for (int i = 0; i < finalCandidates.Length; i++)
+                {
+                    MethodInfo methodInfo = finalCandidates[i];
+
+                    if (!RuntimeTypeHelper.CompareMethodSigAndName(methodInfo, finalCandidates[0]))
+                    {
+                        throw new AmbiguousMatchException();
+                    }
+                }
+
+                // All the methods have the exact same name and sig so return the most derived one.
+                return RuntimeTypeHelper.FindMostDerivedNewSlotMeth(finalCandidates, finalCandidates.Length) as MethodInfo;
+            }
+
+            // Now that we have a preliminary list of candidates, select the most appropriate one.
+            return RuntimeTypeHelper.SelectMethod(bindingFlags, finalCandidates, parameterTypes, modifiers) as MethodInfo;
+        }
+
+        private LinkedList<MethodInfo> GetMethodCandidates(string methodName, Type[] parameterTypes, Type[] typeArguments, BindingFlags bindingFlags, ParameterModifier[] modifiers)
+        {
+            Debug.Assert(!string.IsNullOrEmpty(methodName), "methodName should not be null.");
+            Debug.Assert(parameterTypes != null, "parameterTypes should not be null.");
+            Debug.Assert(typeArguments != null, "typeArguments should not be null.");
+
+            LinkedList<MethodInfo> methodCandidates = new LinkedList<MethodInfo>();
+            LinkedList<MethodInfo> methods = null;
+
+            if (!this.GenericMethodCache.TryGetValue(methodName, out methods))
+            {
+                return methodCandidates;
+            }
+
+            Debug.Assert(methods != null, "methods should not be null.");
+
+            foreach (MethodInfo candidate in methods)
+            {
+                bool paramMatch = true;
+                ParameterInfo[] candidateParams = null;
+                Type[] genericArgs = candidate.GetGenericArguments();
+                Type sourceParameterType = null;
+
+                if (genericArgs.Length != typeArguments.Length)
+                {
+                    continue;
+                }
+
+                // Since we can't just get the correct MethodInfo from Reflection,
+                // we will just match the number of parameters, their order, and their type
+                var methodCandidate = candidate;
+                candidateParams = methodCandidate.GetParameters();
+
+                if (candidateParams.Length != parameterTypes.Length)
+                {
+                    continue;
+                }
+
+                // Exact binding
+                if ((bindingFlags & BindingFlags.ExactBinding) != 0)
+                {
+                    int i = 0;
+
+                    foreach (ParameterInfo candidateParam in candidateParams)
+                    {
+                        sourceParameterType = parameterTypes[i++];
+
+                        if (candidateParam.ParameterType.ContainsGenericParameters)
+                        {
+                            // Since we have a generic parameter here, just make sure the IsArray matches.
+                            if (candidateParam.ParameterType.IsArray != sourceParameterType.IsArray)
+                            {
+                                paramMatch = false;
+                                break;
+                            }
+                        }
+                        else
+                        {
+                            if (candidateParam.ParameterType != sourceParameterType)
+                            {
+                                paramMatch = false;
+                                break;
+                            }
+                        }
+                    }
+
+                    if (paramMatch)
+                    {
+                        methodCandidates.AddLast(methodCandidate);
+                        continue;
+                    }
+                }
+                else
+                {
+                    methodCandidates.AddLast(methodCandidate);
+                }
+            }
+
+            return methodCandidates;
+        }
+    }
+
+    /// <summary>
+    /// This class represents a private class for the Private Accessor functionality.
+    /// </summary>
+    public class PrivateType
+    {
+        /// <summary>
+        /// Binds to everything
+        /// </summary>
+        private const BindingFlags BindToEveryThing = BindingFlags.Default
+            | BindingFlags.NonPublic | BindingFlags.Instance
+            | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
+
+        /// <summary>
+        /// The wrapped type.
+        /// </summary>
+        private Type type;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PrivateType"/> class that contains the private type.
+        /// </summary>
+        /// <param name="assemblyName">Assembly name</param>
+        /// <param name="typeName">fully qualified name of the </param>
+        public PrivateType(string assemblyName, string typeName)
+        {
+            Assembly asm = Assembly.Load(assemblyName);
+
+            this.type = asm.GetType(typeName, true);
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="PrivateType"/> class that contains
+        /// the private type from the type object
+        /// </summary>
+        /// <param name="type">The wrapped Type to create.</param>
+        public PrivateType(Type type)
+        {
+            if (type == null)
+            {
+                throw new ArgumentNullException("type");
+            }
+
+            this.type = type;
+        }
+
+        /// <summary>
+        /// Gets the referenced type
+        /// </summary>
+        public Type ReferencedType => this.type;
+
+        /// <summary>
+        /// Invokes static member
+        /// </summary>
+        /// <param name="name">Name of the member to InvokeHelper</param>
+        /// <param name="args">Arguements to the invoction</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, params object[] args)
+        {
+            return this.InvokeStatic(name, null, args, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Invokes static member
+        /// </summary>
+        /// <param name="name">Name of the member to InvokeHelper</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to invoke</param>
+        /// <param name="args">Arguements to the invoction</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, Type[] parameterTypes, object[] args)
+        {
+            return this.InvokeStatic(name, parameterTypes, args, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Invokes static member
+        /// </summary>
+        /// <param name="name">Name of the member to InvokeHelper</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to invoke</param>
+        /// <param name="args">Arguements to the invoction</param>
+        /// <param name="typeArguments">An array of types corresponding to the types of the generic arguments.</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, Type[] parameterTypes, object[] args, Type[] typeArguments)
+        {
+            return this.InvokeStatic(name, BindToEveryThing, parameterTypes, args, CultureInfo.InvariantCulture, typeArguments);
+        }
+
+        /// <summary>
+        /// Invokes the static method
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="args">Arguements to the invocation</param>
+        /// <param name="culture">Culture</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, object[] args, CultureInfo culture)
+        {
+            return this.InvokeStatic(name, null, args, culture);
+        }
+
+        /// <summary>
+        /// Invokes the static method
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to invoke</param>
+        /// <param name="args">Arguements to the invocation</param>
+        /// <param name="culture">Culture info</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, Type[] parameterTypes, object[] args, CultureInfo culture)
+        {
+            return this.InvokeStatic(name, BindingFlags.InvokeMethod, parameterTypes, args, culture);
+        }
+
+        /// <summary>
+        /// Invokes the static method
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="bindingFlags">Additional invocation attributes</param>
+        /// <param name="args">Arguements to the invocation</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, BindingFlags bindingFlags, params object[] args)
+        {
+            return this.InvokeStatic(name, bindingFlags, null, args, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Invokes the static method
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="bindingFlags">Additional invocation attributes</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to invoke</param>
+        /// <param name="args">Arguements to the invocation</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, BindingFlags bindingFlags, Type[] parameterTypes, object[] args)
+        {
+            return this.InvokeStatic(name, bindingFlags, parameterTypes, args, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Invokes the static method
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="bindingFlags">Additional invocation attributes</param>
+        /// <param name="args">Arguements to the invocation</param>
+        /// <param name="culture">Culture</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, BindingFlags bindingFlags, object[] args, CultureInfo culture)
+        {
+            return this.InvokeStatic(name, bindingFlags, null, args, culture);
+        }
+
+        /// <summary>
+        /// Invokes the static method
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="bindingFlags">Additional invocation attributes</param>
+        /// /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to invoke</param>
+        /// <param name="args">Arguements to the invocation</param>
+        /// <param name="culture">Culture</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, BindingFlags bindingFlags, Type[] parameterTypes, object[] args, CultureInfo culture)
+        {
+            return this.InvokeStatic(name, bindingFlags, parameterTypes, args, culture, null);
+        }
+
+        /// <summary>
+        /// Invokes the static method
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="bindingFlags">Additional invocation attributes</param>
+        /// /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the method to invoke</param>
+        /// <param name="args">Arguements to the invocation</param>
+        /// <param name="culture">Culture</param>
+        /// <param name="typeArguments">An array of types corresponding to the types of the generic arguments.</param>
+        /// <returns>Result of invocation</returns>
+        public object InvokeStatic(string name, BindingFlags bindingFlags, Type[] parameterTypes, object[] args, CultureInfo culture, Type[] typeArguments)
+        {
+            if (parameterTypes != null)
+            {
+                MethodInfo member = this.type.GetMethod(name, bindingFlags | BindToEveryThing | BindingFlags.Static, null, parameterTypes, null);
+                if (member == null)
+                {
+                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "The member specified ({0}) could not be found. You might need to regenerate your private accessor, or the member may be private and defined on a base class. If the latter is true, you need to pass the type that defines the member into PrivateObject's constructor.", name));
+                }
+
+                try
+                {
+                    if (member.IsGenericMethodDefinition)
+                    {
+                        MethodInfo constructed = member.MakeGenericMethod(typeArguments);
+                        return constructed.Invoke(null, bindingFlags, null, args, culture);
+                    }
+                    else
+                    {
+                        return member.Invoke(null, bindingFlags, null, args, culture);
+                    }
+                }
+                catch (TargetInvocationException e)
+                {
+                    Debug.Assert(e.InnerException != null, "Inner Exception should not be null.");
+                    if (e.InnerException != null)
+                    {
+                        throw e.InnerException;
+                    }
+
+                    throw;
+                }
+            }
+            else
+            {
+                return this.InvokeHelperStatic(name, bindingFlags | BindingFlags.InvokeMethod, args, culture);
+            }
+        }
+
+        /// <summary>
+        /// Gets the element in static array
+        /// </summary>
+        /// <param name="name">Name of the array</param>
+        /// <param name="indices">
+        /// A one-dimensional array of 32-bit integers that represent the indexes specifying
+        /// the position of the element to get. For instance, to access a[10][11] the indices would be {10,11}
+        /// </param>
+        /// <returns>element at the specified location</returns>
+        public object GetStaticArrayElement(string name, params int[] indices)
+        {
+            return this.GetStaticArrayElement(name, BindToEveryThing, indices);
+        }
+
+        /// <summary>
+        /// Sets the memeber of the static array
+        /// </summary>
+        /// <param name="name">Name of the array</param>
+        /// <param name="value">value to set</param>
+        /// <param name="indices">
+        /// A one-dimensional array of 32-bit integers that represent the indexes specifying
+        /// the position of the element to set. For instance, to access a[10][11] the array would be {10,11}
+        /// </param>
+        public void SetStaticArrayElement(string name, object value, params int[] indices)
+        {
+            this.SetStaticArrayElement(name, BindToEveryThing, value, indices);
+        }
+
+        /// <summary>
+        /// Gets the element in satatic array
+        /// </summary>
+        /// <param name="name">Name of the array</param>
+        /// <param name="bindingFlags">Additional InvokeHelper attributes</param>
+        /// <param name="indices">
+        /// A one-dimensional array of 32-bit integers that represent the indexes specifying
+        /// the position of the element to get. For instance, to access a[10][11] the array would be {10,11}
+        /// </param>
+        /// <returns>element at the spcified location</returns>
+        public object GetStaticArrayElement(string name, BindingFlags bindingFlags, params int[] indices)
+        {
+            Array arr = (Array)this.InvokeHelperStatic(name, BindingFlags.GetField | BindingFlags.GetProperty | bindingFlags, null, CultureInfo.InvariantCulture);
+            return arr.GetValue(indices);
+        }
+
+        /// <summary>
+        /// Sets the memeber of the static array
+        /// </summary>
+        /// <param name="name">Name of the array</param>
+        /// <param name="bindingFlags">Additional InvokeHelper attributes</param>
+        /// <param name="value">value to set</param>
+        /// <param name="indices">
+        /// A one-dimensional array of 32-bit integers that represent the indexes specifying
+        /// the position of the element to set. For instance, to access a[10][11] the array would be {10,11}
+        /// </param>
+        public void SetStaticArrayElement(string name, BindingFlags bindingFlags, object value, params int[] indices)
+        {
+            Array arr = (Array)this.InvokeHelperStatic(name, BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Static | bindingFlags, null, CultureInfo.InvariantCulture);
+            arr.SetValue(value, indices);
+        }
+
+        /// <summary>
+        /// Gets the static field
+        /// </summary>
+        /// <param name="name">Name of the field</param>
+        /// <returns>The static field.</returns>
+        public object GetStaticField(string name)
+        {
+            return this.GetStaticField(name, BindToEveryThing);
+        }
+
+        /// <summary>
+        /// Sets the static field
+        /// </summary>
+        /// <param name="name">Name of the field</param>
+        /// <param name="value">Arguement to the invocation</param>
+        public void SetStaticField(string name, object value)
+        {
+            this.SetStaticField(name, BindToEveryThing, value);
+        }
+
+        /// <summary>
+        /// Gets the static field using specified InvokeHelper attributes
+        /// </summary>
+        /// <param name="name">Name of the field</param>
+        /// <param name="bindingFlags">Additional invocation attributes</param>
+        /// <returns>The static field.</returns>
+        public object GetStaticField(string name, BindingFlags bindingFlags)
+        {
+            return this.InvokeHelperStatic(name, BindingFlags.GetField | BindingFlags.Static | bindingFlags, null, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Sets the static field using binding attributes
+        /// </summary>
+        /// <param name="name">Name of the field</param>
+        /// <param name="bindingFlags">Additional InvokeHelper attributes</param>
+        /// <param name="value">Arguement to the invocation</param>
+        public void SetStaticField(string name, BindingFlags bindingFlags, object value)
+        {
+            this.InvokeHelperStatic(name, BindingFlags.SetField | bindingFlags | BindingFlags.Static, new[] { value }, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Gets the static field or property
+        /// </summary>
+        /// <param name="name">Name of the field or property</param>
+        /// <returns>The static field or property.</returns>
+        public object GetStaticFieldOrProperty(string name)
+        {
+            return this.GetStaticFieldOrProperty(name, BindToEveryThing);
+        }
+
+        /// <summary>
+        /// Sets the static field or property
+        /// </summary>
+        /// <param name="name">Name of the field or property</param>
+        /// <param name="value">Value to be set to field or property</param>
+        public void SetStaticFieldOrProperty(string name, object value)
+        {
+            this.SetStaticFieldOrProperty(name, BindToEveryThing, value);
+        }
+
+        /// <summary>
+        /// Gets the static field or property using specified InvokeHelper attributes
+        /// </summary>
+        /// <param name="name">Name of the field or property</param>
+        /// <param name="bindingFlags">Additional invocation attributes</param>
+        /// <returns>The static field or property.</returns>
+        public object GetStaticFieldOrProperty(string name, BindingFlags bindingFlags)
+        {
+            return this.InvokeHelperStatic(name, BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Static | bindingFlags, null, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Sets the static field or property using binding attributes
+        /// </summary>
+        /// <param name="name">Name of the field or property</param>
+        /// <param name="bindingFlags">Additional invocation attributes</param>
+        /// <param name="value">Value to be set to field or property</param>
+        public void SetStaticFieldOrProperty(string name, BindingFlags bindingFlags, object value)
+        {
+            this.InvokeHelperStatic(name, BindingFlags.SetField | BindingFlags.SetProperty | bindingFlags | BindingFlags.Static, new[] { value }, CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// Gets the static property
+        /// </summary>
+        /// <param name="name">Name of the field or property</param>
+        /// <param name="args">Arguements to the invocation</param>
+        /// <returns>The static property.</returns>
+        public object GetStaticProperty(string name, params object[] args)
+        {
+            return this.GetStaticProperty(name, BindToEveryThing, args);
+        }
+
+        /// <summary>
+        /// Sets the static property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="value">Value to be set to field or property</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        public void SetStaticProperty(string name, object value, params object[] args)
+        {
+            this.SetStaticProperty(name, BindToEveryThing, value, null, args);
+        }
+
+        /// <summary>
+        /// Sets the static property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="value">Value to be set to field or property</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the indexed property.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        public void SetStaticProperty(string name, object value, Type[] parameterTypes, object[] args)
+        {
+            this.SetStaticProperty(name, BindingFlags.SetProperty, value, parameterTypes, args);
+        }
+
+        /// <summary>
+        /// Gets the static property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="bindingFlags">Additional invocation attributes.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>The static property.</returns>
+        public object GetStaticProperty(string name, BindingFlags bindingFlags, params object[] args)
+        {
+            return this.GetStaticProperty(name, BindingFlags.GetProperty | BindingFlags.Static | bindingFlags, null, args);
+        }
+
+        /// <summary>
+        /// Gets the static property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="bindingFlags">Additional invocation attributes.</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the indexed property.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        /// <returns>The static property.</returns>
+        public object GetStaticProperty(string name, BindingFlags bindingFlags, Type[] parameterTypes, object[] args)
+        {
+            if (parameterTypes != null)
+            {
+                PropertyInfo pi = this.type.GetProperty(name, bindingFlags | BindingFlags.Static, null, null, parameterTypes, null);
+                if (pi == null)
+                {
+                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "The member specified ({0}) could not be found. You might need to regenerate your private accessor, or the member may be private and defined on a base class. If the latter is true, you need to pass the type that defines the member into PrivateObject's constructor.", name));
+                }
+
+                return pi.GetValue(null, args);
+            }
+            else
+            {
+                return this.InvokeHelperStatic(name, bindingFlags | BindingFlags.GetProperty, args, null);
+            }
+        }
+
+        /// <summary>
+        /// Sets the static property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="bindingFlags">Additional invocation attributes.</param>
+        /// <param name="value">Value to be set to field or property</param>
+        /// <param name="args">Optional index values for indexed properties. The indexes of indexed properties are zero-based. This value should be null for non-indexed properties. </param>
+        public void SetStaticProperty(string name, BindingFlags bindingFlags, object value, params object[] args)
+        {
+            this.SetStaticProperty(name, bindingFlags, value, null, args);
+        }
+
+        /// <summary>
+        /// Sets the static property
+        /// </summary>
+        /// <param name="name">Name of the property</param>
+        /// <param name="bindingFlags">Additional invocation attributes.</param>
+        /// <param name="value">Value to be set to field or property</param>
+        /// <param name="parameterTypes">An array of <see cref="T:System.Type"/> objects representing the number, order, and type of the parameters for the indexed property.</param>
+        /// <param name="args">Arguments to pass to the member to invoke.</param>
+        public void SetStaticProperty(string name, BindingFlags bindingFlags, object value, Type[] parameterTypes, object[] args)
+        {
+            if (parameterTypes != null)
+            {
+                PropertyInfo pi = this.type.GetProperty(name, bindingFlags | BindingFlags.Static, null, null, parameterTypes, null);
+                if (pi == null)
+                {
+                    throw new ArgumentException(
+                        string.Format(CultureInfo.CurrentCulture, "The member specified ({0}) could not be found. You might need to regenerate your private accessor, or the member may be private and defined on a base class. If the latter is true, you need to pass the type that defines the member into PrivateObject's constructor.", name));
+                }
+
+                pi.SetValue(null, value, args);
+            }
+            else
+            {
+                object[] pass = new object[(args?.Length ?? 0) + 1];
+                pass[0] = value;
+                args?.CopyTo(pass, 1);
+                this.InvokeHelperStatic(name, bindingFlags | BindingFlags.SetProperty, pass, null);
+            }
+        }
+
+        /// <summary>
+        /// Invokes the static method
+        /// </summary>
+        /// <param name="name">Name of the member</param>
+        /// <param name="bindingFlags">Additional invocation attributes</param>
+        /// <param name="args">Arguements to the invocation</param>
+        /// <param name="culture">Culture</param>
+        /// <returns>Result of invocation</returns>
+        private object InvokeHelperStatic(string name, BindingFlags bindingFlags, object[] args, CultureInfo culture)
+        {
+            try
+            {
+                return this.type.InvokeMember(name, bindingFlags | BindToEveryThing | BindingFlags.Static, null, null, args, culture);
+            }
+            catch (TargetInvocationException e)
+            {
+                Debug.Assert(e.InnerException != null, "Inner Exception should not be null.");
+                if (e.InnerException != null)
+                {
+                    throw e.InnerException;
+                }
+
+                throw;
+            }
+        }
+    }
+
+    /// <summary>
+    /// Provides method signature discovery for generic methods.
+    /// </summary>
+    internal class RuntimeTypeHelper
+    {
+        /// <summary>
+        /// Compares the method signatures of these two methods.
+        /// </summary>
+        /// <param name="m1">Method1</param>
+        /// <param name="m2">Method2</param>
+        /// <returns>True if they are similiar.</returns>
+        internal static bool CompareMethodSigAndName(MethodBase m1, MethodBase m2)
+        {
+            ParameterInfo[] params1 = m1.GetParameters();
+            ParameterInfo[] params2 = m2.GetParameters();
+
+            if (params1.Length != params2.Length)
+            {
+                return false;
+            }
+
+            int numParams = params1.Length;
+            for (int i = 0; i < numParams; i++)
+            {
+                if (params1[i].ParameterType != params2[i].ParameterType)
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// Gets the hierarchy depth from the base type of the provided type.
+        /// </summary>
+        /// <param name="t">The type.</param>
+        /// <returns>The depth.</returns>
+        internal static int GetHierarchyDepth(Type t)
+        {
+            int depth = 0;
+
+            Type currentType = t;
+            do
+            {
+                depth++;
+                currentType = currentType.BaseType;
+            }
+            while (currentType != null);
+
+            return depth;
+        }
+
+        /// <summary>
+        /// Finds most dervied type with the provided information.
+        /// </summary>
+        /// <param name="match">Candidate matches.</param>
+        /// <param name="cMatches">Number of matches.</param>
+        /// <returns>The most derived method.</returns>
+        internal static MethodBase FindMostDerivedNewSlotMeth(MethodBase[] match, int cMatches)
+        {
+            int deepestHierarchy = 0;
+            MethodBase methWithDeepestHierarchy = null;
+
+            for (int i = 0; i < cMatches; i++)
+            {
+                // Calculate the depth of the hierarchy of the declaring type of the
+                // current method.
+                int currentHierarchyDepth = GetHierarchyDepth(match[i].DeclaringType);
+
+                // Two methods with the same hierarchy depth are not allowed. This would
+                // mean that there are 2 methods with the same name and sig on a given type
+                // which is not allowed, unless one of them is vararg...
+                if (currentHierarchyDepth == deepestHierarchy)
+                {
+                    if (methWithDeepestHierarchy != null)
+                    {
+                        Debug.Assert(
+                            methWithDeepestHierarchy != null && ((match[i].CallingConvention & CallingConventions.VarArgs)
+                                                                 | (methWithDeepestHierarchy.CallingConvention & CallingConventions.VarArgs)) != 0,
+                            "Calling conventions: " + match[i].CallingConvention + " - " + methWithDeepestHierarchy.CallingConvention);
+                    }
+
+                    throw new AmbiguousMatchException();
+                }
+
+                // Check to see if this method is on the most derived class.
+                if (currentHierarchyDepth > deepestHierarchy)
+                {
+                    deepestHierarchy = currentHierarchyDepth;
+                    methWithDeepestHierarchy = match[i];
+                }
+            }
+
+            return methWithDeepestHierarchy;
+        }
+
+        /// <summary>
+        /// Given a set of methods that match the base criteria, select a method based
+        /// upon an array of types. This method should return null if no method matches
+        /// the criteria.
+        /// </summary>
+        /// <param name="bindingAttr">Binding specification.</param>
+        /// <param name="match">Candidate matches</param>
+        /// <param name="types">Types</param>
+        /// <param name="modifiers">Parameter modifiers.</param>
+        /// <returns>Matching method. Null if none matches.</returns>
+        internal static MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
+        {
+            if (match == null)
+            {
+                throw new ArgumentNullException("match");
+            }
+
+            int i;
+            int j;
+
+            Type[] realTypes = new Type[types.Length];
+            for (i = 0; i < types.Length; i++)
+            {
+                realTypes[i] = types[i].UnderlyingSystemType;
+            }
+
+            types = realTypes;
+
+            // If there are no methods to match to, then return null, indicating that no method
+            // matches the criteria
+            if (match.Length == 0)
+            {
+                return null;
+            }
+
+            // Find all the methods that can be described by the types parameter.
+            // Remove all of them that cannot.
+            int curIdx = 0;
+            for (i = 0; i < match.Length; i++)
+            {
+                ParameterInfo[] par = match[i].GetParameters();
+                if (par.Length != types.Length)
+                {
+                    continue;
+                }
+
+                for (j = 0; j < types.Length; j++)
+                {
+                    Type pCls = par[j].ParameterType;
+
+                    if (pCls.ContainsGenericParameters)
+                    {
+                        if (pCls.IsArray != types[j].IsArray)
+                        {
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        if (pCls == types[j])
+                        {
+                            continue;
+                        }
+
+                        if (pCls == typeof(object))
+                        {
+                            continue;
+                        }
+                        else
+                        {
+                            if (!pCls.IsAssignableFrom(types[j]))
+                            {
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                if (j == types.Length)
+                {
+                    match[curIdx++] = match[i];
+                }
+            }
+
+            if (curIdx == 0)
+            {
+                return null;
+            }
+
+            if (curIdx == 1)
+            {
+                return match[0];
+            }
+
+            // Walk all of the methods looking the most specific method to invoke
+            int currentMin = 0;
+            bool ambig = false;
+            int[] paramOrder = new int[types.Length];
+            for (i = 0; i < types.Length; i++)
+            {
+                paramOrder[i] = i;
+            }
+
+            for (i = 1; i < curIdx; i++)
+            {
+                int newMin = FindMostSpecificMethod(match[currentMin], paramOrder, null, match[i], paramOrder, null, types, null);
+                if (newMin == 0)
+                {
+                    ambig = true;
+                }
+                else
+                {
+                    if (newMin == 2)
+                    {
+                        currentMin = i;
+                        ambig = false;
+                        currentMin = i;
+                    }
+                }
+            }
+
+            if (ambig)
+            {
+                throw new AmbiguousMatchException();
+            }
+
+            return match[currentMin];
+        }
+
+        /// <summary>
+        /// Finds the most specific method in the two methods provided.
+        /// </summary>
+        /// <param name="m1">Method 1</param>
+        /// <param name="paramOrder1">Parameter order for Method 1</param>
+        /// <param name="paramArrayType1">Paramter array type.</param>
+        /// <param name="m2">Method 2</param>
+        /// <param name="paramOrder2">Parameter order for Method 2</param>
+        /// <param name="paramArrayType2">>Paramter array type.</param>
+        /// <param name="types">Types to search in.</param>
+        /// <param name="args">Args.</param>
+        /// <returns>An int representing the match.</returns>
+        internal static int FindMostSpecificMethod(
+            MethodBase m1,
+            int[] paramOrder1,
+            Type paramArrayType1,
+            MethodBase m2,
+            int[] paramOrder2,
+            Type paramArrayType2,
+            Type[] types,
+            object[] args)
+        {
+            // Find the most specific method based on the parameters.
+            int res = FindMostSpecific(
+                m1.GetParameters(),
+                paramOrder1,
+                paramArrayType1,
+                m2.GetParameters(),
+                paramOrder2,
+                paramArrayType2,
+                types,
+                args);
+
+            // If the match was not ambiguous then return the result.
+            if (res != 0)
+            {
+                return res;
+            }
+
+            // Check to see if the methods have the exact same name and signature.
+            if (CompareMethodSigAndName(m1, m2))
+            {
+                // Determine the depth of the declaring types for both methods.
+                int hierarchyDepth1 = GetHierarchyDepth(m1.DeclaringType);
+                int hierarchyDepth2 = GetHierarchyDepth(m2.DeclaringType);
+
+                // The most derived method is the most specific one.
+                if (hierarchyDepth1 == hierarchyDepth2)
+                {
+                    return 0;
+                }
+                else if (hierarchyDepth1 < hierarchyDepth2)
+                {
+                    return 2;
+                }
+                else
+                {
+                    return 1;
+                }
+            }
+
+            // The match is ambiguous.
+            return 0;
+        }
+
+        /// <summary>
+        /// Finds the most specific method in the two methods provided.
+        /// </summary>
+        /// <param name="p1">Method 1</param>
+        /// <param name="paramOrder1">Parameter order for Method 1</param>
+        /// <param name="paramArrayType1">Paramter array type.</param>
+        /// <param name="p2">Method 2</param>
+        /// <param name="paramOrder2">Parameter order for Method 2</param>
+        /// <param name="paramArrayType2">>Paramter array type.</param>
+        /// <param name="types">Types to search in.</param>
+        /// <param name="args">Args.</param>
+        /// <returns>An int representing the match.</returns>
+        internal static int FindMostSpecific(
+            ParameterInfo[] p1,
+            int[] paramOrder1,
+            Type paramArrayType1,
+            ParameterInfo[] p2,
+            int[] paramOrder2,
+            Type paramArrayType2,
+            Type[] types,
+            object[] args)
+        {
+            // A method using params is always less specific than one not using params
+            if (paramArrayType1 != null && paramArrayType2 == null)
+            {
+                return 2;
+            }
+
+            if (paramArrayType2 != null && paramArrayType1 == null)
+            {
+                return 1;
+            }
+
+            bool p1Less = false;
+            bool p2Less = false;
+
+            for (int i = 0; i < types.Length; i++)
+            {
+                if (args != null && args[i] == Type.Missing)
+                {
+                    continue;
+                }
+
+                Type c1, c2;
+
+                // If a param array is present, then either
+                //      the user re-ordered the parameters in which case
+                //          the argument to the param array is either an array
+                //              in which case the params is conceptually ignored and so paramArrayType1 == null
+                //          or the argument to the param array is a single element
+                //              in which case paramOrder[i] == p1.Length - 1 for that element
+                //      or the user did not re-order the parameters in which case
+                //          the paramOrder array could contain indexes larger than p.Length - 1
+                ////          so any index >= p.Length - 1 is being put in the param array
+
+                if (paramArrayType1 != null && paramOrder1[i] >= p1.Length - 1)
+                {
+                    c1 = paramArrayType1;
+                }
+                else
+                {
+                    c1 = p1[paramOrder1[i]].ParameterType;
+                }
+
+                if (paramArrayType2 != null && paramOrder2[i] >= p2.Length - 1)
+                {
+                    c2 = paramArrayType2;
+                }
+                else
+                {
+                    c2 = p2[paramOrder2[i]].ParameterType;
+                }
+
+                if (c1 == c2)
+                {
+                    continue;
+                }
+
+                if (c1.ContainsGenericParameters || c2.ContainsGenericParameters)
+                {
+                    continue;
+                }
+
+                switch (FindMostSpecificType(c1, c2, types[i]))
+                {
+                    case 0:
+                        return 0;
+                    case 1:
+                        p1Less = true;
+                        break;
+                    case 2:
+                        p2Less = true;
+                        break;
+                }
+            }
+
+            // Two way p1Less and p2Less can be equal.  All the arguments are the
+            //  same they both equal false, otherwise there were things that both
+            //  were the most specific type on....
+            if (p1Less == p2Less)
+            {
+                // it's possible that the 2 methods have same sig and  default param in which case we match the one
+                // with the same number of args but only if they were exactly the same (that is p1Less and p2Lees are both false)
+                if (!p1Less && p1.Length != p2.Length && args != null)
+                {
+                    if (p1.Length == args.Length)
+                    {
+                        return 1;
+                    }
+                    else if (p2.Length == args.Length)
+                    {
+                        return 2;
+                    }
+                }
+
+                return 0;
+            }
+            else
+            {
+                return (p1Less == true) ? 1 : 2;
+            }
+        }
+
+        /// <summary>
+        /// Finds the most specific type in the two provided.
+        /// </summary>
+        /// <param name="c1">Type 1</param>
+        /// <param name="c2">Type 2</param>
+        /// <param name="t">The defining type</param>
+        /// <returns>An int representing the match.</returns>
+        internal static int FindMostSpecificType(Type c1, Type c2, Type t)
+        {
+            // If the two types are exact move on...
+            if (c1 == c2)
+            {
+                return 0;
+            }
+
+            if (c1 == t)
+            {
+                return 1;
+            }
+
+            if (c2 == t)
+            {
+                return 2;
+            }
+
+            bool c1FromC2;
+            bool c2FromC1;
+
+            if (c1.IsByRef || c2.IsByRef)
+            {
+                if (c1.IsByRef && c2.IsByRef)
+                {
+                    c1 = c1.GetElementType();
+                    c2 = c2.GetElementType();
+                }
+                else if (c1.IsByRef)
+                {
+                    if (c1.GetElementType() == c2)
+                    {
+                        return 2;
+                    }
+
+                    c1 = c1.GetElementType();
+                }
+                else
+                {
+                    if (c2.GetElementType() == c1)
+                    {
+                        return 1;
+                    }
+
+                    c2 = c2.GetElementType();
+                }
+            }
+
+            if (c1.IsPrimitive && c2.IsPrimitive)
+            {
+                c1FromC2 = true;
+                c2FromC1 = true;
+            }
+            else
+            {
+                c1FromC2 = c1.IsAssignableFrom(c2);
+                c2FromC1 = c2.IsAssignableFrom(c1);
+            }
+
+            if (c1FromC2 == c2FromC1)
+            {
+                return 0;
+            }
+
+            if (c1FromC2)
+            {
+                return 2;
+            }
+            else
+            {
+                return 1;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Server/ServerAppFunctionalTests/ServerAppFunctionalTests.csproj b/Server/ServerAppFunctionalTests/ServerAppFunctionalTests.csproj
new file mode 100644
index 0000000..40f7746
--- /dev/null
+++ b/Server/ServerAppFunctionalTests/ServerAppFunctionalTests.csproj
@@ -0,0 +1,24 @@
+﻿<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFramework>net5.0</TargetFramework>
+
+        <IsPackable>false</IsPackable>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
+        <PackageReference Include="Moq" Version="4.16.1" />
+        <PackageReference Include="MSTest.TestAdapter" Version="2.2.4" />
+        <PackageReference Include="MSTest.TestFramework" Version="2.2.4" />
+        <PackageReference Include="coverlet.collector" Version="3.0.3">
+          <PrivateAssets>all</PrivateAssets>
+          <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+        </PackageReference>
+    </ItemGroup>
+
+    <ItemGroup>
+        <ProjectReference Include="..\ServerApp\ServerApp.csproj" />
+    </ItemGroup>
+
+</Project>
diff --git a/Server/ServerAppFunctionalTests/TestingDataDownloader.cs b/Server/ServerAppFunctionalTests/TestingDataDownloader.cs
new file mode 100644
index 0000000..1850d5b
--- /dev/null
+++ b/Server/ServerAppFunctionalTests/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 ServerAppFunctionalTests
+{
+	[TestClass]
+	class TestingDataDownloader
+	{
+		[TestMethod]
+		public void DataDirectoryCreate()
+		{
+
+		}
+
+		[TestMethod]
+		public void DataSubdirectoriesCreate()
+		{
+
+		}
+
+		[TestMethod]
+		public void DataDownload()
+		{
+
+		}
+
+		[TestMethod]
+		public void DataRetrieve()
+		{
+
+		}
+
+		[TestMethod]
+		public void DateCompare()
+		{
+
+		}
+	}
+}
diff --git a/Server/ServerAppTests/Predictor/PredictionControllerTests.cs b/Server/ServerAppTests/Predictor/PredictionControllerTests.cs
deleted file mode 100644
index 113597c..0000000
--- a/Server/ServerAppTests/Predictor/PredictionControllerTests.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
-using ServerApp.Predictor;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace ServerApp.Predictor.Tests
-{
-    [TestClass()]
-    public class PredictionControllerTests
-    {
-        [TestMethod()]
-        public void PredictionControllerTest()
-        {
-            throw new NotImplementedException();
-        }
-
-        [TestMethod()]
-        public void GetPredictorsTest()
-        {
-            throw new NotImplementedException();
-        }
-
-        [TestMethod()]
-        public void LoadTest()
-        {
-            throw new NotImplementedException();
-        }
-
-        [TestMethod()]
-        public void PredictTest()
-        {
-            throw new NotImplementedException();
-        }
-
-        [TestMethod()]
-        public void TrainTest()
-        {
-            throw new NotImplementedException();
-        }
-    }
-}
diff --git a/Server/ServerAppTests/ServerAppUnitTests.csproj b/Server/ServerAppTests/ServerAppUnitTests.csproj
deleted file mode 100644
index 14a52b1..0000000
--- a/Server/ServerAppTests/ServerAppUnitTests.csproj
+++ /dev/null
@@ -1,20 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>.NETCoreApp,Version=v5.0</TargetFramework>
-
-    <IsPackable>false</IsPackable>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
-    <PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
-    <PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
-    <PackageReference Include="coverlet.collector" Version="1.2.0" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\ServerApp\ServerApp.csproj" />
-  </ItemGroup>
-
-</Project>
diff --git a/Server/ServerAppUnitTests/Predictor/PredictionControllerTests.cs b/Server/ServerAppUnitTests/Predictor/PredictionControllerTests.cs
new file mode 100644
index 0000000..113597c
--- /dev/null
+++ b/Server/ServerAppUnitTests/Predictor/PredictionControllerTests.cs
@@ -0,0 +1,44 @@
+﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
+using ServerApp.Predictor;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ServerApp.Predictor.Tests
+{
+    [TestClass()]
+    public class PredictionControllerTests
+    {
+        [TestMethod()]
+        public void PredictionControllerTest()
+        {
+            throw new NotImplementedException();
+        }
+
+        [TestMethod()]
+        public void GetPredictorsTest()
+        {
+            throw new NotImplementedException();
+        }
+
+        [TestMethod()]
+        public void LoadTest()
+        {
+            throw new NotImplementedException();
+        }
+
+        [TestMethod()]
+        public void PredictTest()
+        {
+            throw new NotImplementedException();
+        }
+
+        [TestMethod()]
+        public void TrainTest()
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/Server/ServerAppUnitTests/ServerAppUnitTests.csproj b/Server/ServerAppUnitTests/ServerAppUnitTests.csproj
new file mode 100644
index 0000000..8dc9b0a
--- /dev/null
+++ b/Server/ServerAppUnitTests/ServerAppUnitTests.csproj
@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>.NETCoreApp,Version=v5.0</TargetFramework>
+
+    <IsPackable>false</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
+    <PackageReference Include="Moq" Version="4.16.1" />
+    <PackageReference Include="MSTest.TestAdapter" Version="2.2.4" />
+    <PackageReference Include="MSTest.TestFramework" Version="2.2.4" />
+    <PackageReference Include="coverlet.collector" Version="3.0.3">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\ServerApp\ServerApp.csproj" />
+  </ItemGroup>
+
+</Project>
diff --git a/Server/TestProject/ParserTests/JisParserTesting.cs b/Server/TestProject/ParserTests/JisParserTesting.cs
deleted file mode 100644
index c41945b..0000000
--- a/Server/TestProject/ParserTests/JisParserTesting.cs
+++ /dev/null
@@ -1,287 +0,0 @@
-﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using ServerApp.Parser.Parsers;
-using System.Collections.Generic;
-using ServerApp.Parser.OutputInfo;
-using Moq;
-using ServerApp.Parser.InputData;
-
-namespace TestProject.ParserTests
-{
-    /// <summary>
-    /// Summary description for WeatherParserTesting
-    /// </summary>
-    [TestClass]
-    public class JisParserTesting
-    {
-
-
-        #region Jis parser
-
-        #region Parse days
-        [TestMethod]
-        public void ParseJisDayOne()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<JisInstance> data = new List<JisInstance>();
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
-
-            JisParser target = new JisParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(2, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("MENZA", 3, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("KARMA", 5, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
-        }
-
-        [TestMethod]
-        public void ParseJisDayOneFiltering()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<JisInstance> data = new List<JisInstance>();
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 6, 0, 0), 2));
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 17, 0, 0), 2));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
-
-            JisParser target = new JisParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 1, 16, 0, 0));
-
-            Assert.AreEqual(2, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("MENZA", 3, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("KARMA", 5, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
-        }
-
-        [TestMethod]
-        public void ParseJisDayTwo()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<JisInstance> data = new List<JisInstance>();
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
-
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 2, 1, 8, 0, 0), 8));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 2, 1, 12, 0, 0), 2));
-            data.Add(new JisInstance("A2", new DateTime(2000, 2, 1, 16, 0, 0), 1));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
-
-            JisParser target = new JisParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 2, 1, 16, 0, 0));
-
-            Assert.AreEqual(4, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("MENZA", 3, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("KARMA", 5, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
-
-            Assert.AreEqual(new ActivityInfo("MENZA", 10, new DateTime(2000, 2, 1, 7, 0, 0), 18 - 7), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("KARMA", 1, new DateTime(2000, 2, 1, 7, 0, 0), 18 - 7), retVal[3]);
-        }
-
-        [TestMethod]
-        public void ParseJisDayTwoFiltering()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<JisInstance> data = new List<JisInstance>();
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 6, 0, 0), 2));
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
-
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 2, 1, 8, 0, 0), 8));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 2, 1, 12, 0, 0), 2));
-            data.Add(new JisInstance("A2", new DateTime(2000, 2, 1, 16, 0, 0), 1));
-            data.Add(new JisInstance("A2", new DateTime(2000, 2, 1, 17, 0, 0), 2));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
-
-            JisParser target = new JisParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 2, 1, 16, 0, 0));
-
-            Assert.AreEqual(4, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("MENZA", 3, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("KARMA", 5, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
-
-            Assert.AreEqual(new ActivityInfo("MENZA", 10, new DateTime(2000, 2, 1, 7, 0, 0), 18 - 7), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("KARMA", 1, new DateTime(2000, 2, 1, 7, 0, 0), 18 - 7), retVal[3]);
-        }
-
-
-        [TestMethod]
-        public void ParseJisDayNone()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<JisInstance> data = new List<JisInstance>();
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 10, 0, 0), 3));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
-
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 2, 15, 0, 0), 2));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
-
-            JisParser target = new JisParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsDays", path, new DateTime(2000, 1, 3), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(0, retVal.Count);
-        }
-        #endregion
-
-        #region Parse hours
-        [TestMethod]
-        public void ParseJisHourlyOne()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<JisInstance> data = new List<JisInstance>();
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 0, 0), 3));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 15, 0), 3));
-
-            /*
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 5));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 12, 0, 0), 1));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 15, 0, 0), 2));
-            */
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
-
-            JisParser target = new JisParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(2, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("MENZA", 2, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("KARMA", 6, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[1]);
-        }
-
-        [TestMethod]
-        public void ParseJisDayHourlyMultiple()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<JisInstance> data = new List<JisInstance>();
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 7, 0, 0), 2));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 0, 0), 3));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 15, 0), 3));
-
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 11, 0, 0), 5));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 11, 10, 0), 1));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 11, 20, 0), 2));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
-
-            JisParser target = new JisParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(4, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("MENZA", 2, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("KARMA", 6, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[1]);
-            Assert.AreEqual(new ActivityInfo("MENZA", 6, new DateTime(2000, 1, 1, 11, 0, 0), 2), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("KARMA", 2, new DateTime(2000, 1, 1, 11, 0, 0), 2), retVal[3]);
-        }
-
-        [TestMethod]
-        public void ParseJisHourlyNone()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<JisInstance> data = new List<JisInstance>();
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 3, 0, 0), 2));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 4, 0, 0), 3));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 5, 15, 0), 3));
-
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 19, 0, 0), 5));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 19, 10, 0), 1));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 19, 20, 0), 2));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
-
-            JisParser target = new JisParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(0, retVal.Count);
-        }
-
-        [TestMethod]
-        public void ParseJisHourlyFiltering()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<JisInstance> data = new List<JisInstance>();
-            data.Add(new JisInstance("MenzaKL-vydej", new DateTime(2000, 1, 1, 6, 0, 0), 2));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 0, 0), 3));
-            data.Add(new JisInstance("A2-Hlavni vchod", new DateTime(2000, 1, 1, 8, 15, 0), 3));
-
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 11, 0, 0), 5));
-            data.Add(new JisInstance("Menza4-kasa5", new DateTime(2000, 1, 1, 18, 10, 0), 1));
-            data.Add(new JisInstance("A1", new DateTime(2000, 1, 1, 19, 20, 0), 2));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadJisFile(path)).Returns(data);
-
-            JisParser target = new JisParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneJisFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(3, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("KARMA", 6, new DateTime(2000, 1, 1, 7, 0, 0), 2), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("MENZA", 5, new DateTime(2000, 1, 1, 11, 0, 0), 2), retVal[1]);
-            Assert.AreEqual(new ActivityInfo("MENZA", 1, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[2]);
-        }
-        #endregion
-
-        #endregion
-
-    }
-}
diff --git a/Server/TestProject/ParserTests/JsonParserTesting.cs b/Server/TestProject/ParserTests/JsonParserTesting.cs
deleted file mode 100644
index b675f08..0000000
--- a/Server/TestProject/ParserTests/JsonParserTesting.cs
+++ /dev/null
@@ -1,518 +0,0 @@
-﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using ServerApp.Parser.Parsers;
-using System.Collections.Generic;
-using ServerApp.Parser.OutputInfo;
-using Moq;
-using ServerApp.Parser.InputData;
-using ServerApp.WeatherPredictionParser;
-using ServerApp.DataDownload;
-
-namespace TestProject.ParserTests
-{
-    /// <summary>
-    /// Summary description for WeatherParserTesting
-    /// </summary>
-    [TestClass]
-    public class JsonParserTesting
-    {
-
-        #region Json parser
-
-        #region Parsing
-
-        string SetBasicData()
-        {
-            return
-@"{
-    ""current_condition"": [
-        {
-            ""FeelsLikeC"": ""4"",
-            ""cloudcover"": ""100"",
-            ""localObsDateTime"": ""2021-05-25 01:29 PM"",
-            ""observation_time"": ""11:29 AM"",
-            ""precipMM"": ""0.1"",
-            ""temp_C"": ""8"",
-            ""windspeedKmph"": ""13""
-        }
-    ],
-    ""weather"": [
-        {
-                ""astronomy"": [
-                    {
-                    ""sunrise"": ""05:10 AM"",
-                    ""sunset"": ""08:58 PM""
-                    }
-            ],
-            ""date"": ""2021-05-25"",
-            ""hourly"": [
-                {
-                    ""FeelsLikeC"": ""7"",
-                    ""WindGustKmph"": ""31"",
-                    ""chanceofrain"": ""87"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""92"",
-                    ""precipMM"": ""4.5"",
-                    ""tempC"": ""9"",
-                    ""time"": ""0"",
-                    ""windspeedKmph"": ""19""
-                },
-                {
-                    ""FeelsLikeC"": ""8"",
-                    ""WindGustKmph"": ""10"",
-                    ""chanceofrain"": ""50"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""60"",
-                    ""precipMM"": ""2.0"",
-                    ""tempC"": ""9"",
-                    ""time"": ""1200"",
-                    ""windspeedKmph"": ""10""
-                }
-            ]
-        },
-        {
-                ""astronomy"": [
-                    {
-                    ""sunrise"": ""05:09 AM"",
-                    ""sunset"": ""08:59 PM""
-                    }
-            ],
-            ""date"": ""2021-05-26"",
-            ""hourly"": [
-                {
-                    ""FeelsLikeC"": ""10"",
-                    ""WindGustKmph"": ""31"",
-                    ""chanceofrain"": ""0"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""0"",
-                    ""precipMM"": ""0"",
-                    ""tempC"": ""12"",
-                    ""time"": ""1200"",
-                    ""windspeedKmph"": ""19""
-                },
-                                {
-                    ""FeelsLikeC"": ""12"",
-                    ""WindGustKmph"": ""31"",
-                    ""chanceofrain"": ""0"",
-                    ""chanceofsnow"": ""80"",
-                    ""cloudcover"": ""92"",
-                    ""precipMM"": ""4.5"",
-                    ""tempC"": ""19"",
-                    ""time"": ""2100"",
-                    ""windspeedKmph"": ""19""
-                }
-            ]
-        },
-        {
-                ""astronomy"": [
-                    {
-                    ""sunrise"": ""05:08 AM"",
-                    ""sunset"": ""09:00 PM""
-                    }
-            ],
-            ""date"": ""2021-05-27"",
-            ""hourly"": [
-                {
-                    ""FeelsLikeC"": ""17"",
-                    ""WindGustKmph"": ""3"",
-                    ""chanceofrain"": ""7"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""10"",
-                    ""precipMM"": ""0"",
-                    ""tempC"": ""20"",
-                    ""time"": ""1800"",
-                    ""windspeedKmph"": ""9""
-                },
-                {
-                    ""FeelsLikeC"": ""9"",
-                    ""WindGustKmph"": ""31"",
-                    ""chanceofrain"": ""87"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""32"",
-                    ""precipMM"": ""4.5"",
-                    ""tempC"": ""9"",
-                    ""time"": ""2100"",
-                    ""windspeedKmph"": ""10""
-                }
-            ]
-        }
-    ]
-}";
-        }
-
-        string SetAstronomyData()
-        {
-            return
-    @"{
-    ""current_condition"": [
-        {
-            ""FeelsLikeC"": ""4"",
-            ""cloudcover"": ""100"",
-            ""localObsDateTime"": ""2021-05-25 01:29 PM"",
-            ""observation_time"": ""11:29 AM"",
-            ""precipMM"": ""0.1"",
-            ""temp_C"": ""8"",
-            ""windspeedKmph"": ""13""
-        }
-    ],
-    ""weather"": [
-        {
-                ""astronomy"": [
-                    {
-                    ""sunrise"": ""08:10 AM"",
-                    ""sunset"": ""06:58 PM""
-                    }
-            ],
-            ""date"": ""2021-05-25"",
-            ""hourly"": [
-                {
-                    ""FeelsLikeC"": ""7"",
-                    ""WindGustKmph"": ""31"",
-                    ""chanceofrain"": ""87"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""92"",
-                    ""precipMM"": ""4.5"",
-                    ""tempC"": ""9"",
-                    ""time"": ""0"",
-                    ""windspeedKmph"": ""19""
-                },
-                {
-                    ""FeelsLikeC"": ""8"",
-                    ""WindGustKmph"": ""10"",
-                    ""chanceofrain"": ""50"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""60"",
-                    ""precipMM"": ""2.0"",
-                    ""tempC"": ""9"",
-                    ""time"": ""300"",
-                    ""windspeedKmph"": ""10""
-                },
-                {
-                    ""FeelsLikeC"": ""8"",
-                    ""WindGustKmph"": ""10"",
-                    ""chanceofrain"": ""50"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""60"",
-                    ""precipMM"": ""2.0"",
-                    ""tempC"": ""9"",
-                    ""time"": ""600"",
-                    ""windspeedKmph"": ""10""
-                },
-                {
-                    ""FeelsLikeC"": ""8"",
-                    ""WindGustKmph"": ""10"",
-                    ""chanceofrain"": ""50"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""60"",
-                    ""precipMM"": ""2.0"",
-                    ""tempC"": ""9"",
-                    ""time"": ""1500"",
-                    ""windspeedKmph"": ""10""
-                },
-                {
-                    ""FeelsLikeC"": ""8"",
-                    ""WindGustKmph"": ""10"",
-                    ""chanceofrain"": ""50"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""60"",
-                    ""precipMM"": ""2.0"",
-                    ""tempC"": ""9"",
-                    ""time"": ""1800"",
-                    ""windspeedKmph"": ""10""
-                },
-                {
-                    ""FeelsLikeC"": ""8"",
-                    ""WindGustKmph"": ""10"",
-                    ""chanceofrain"": ""50"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""60"",
-                    ""precipMM"": ""2.0"",
-                    ""tempC"": ""9"",
-                    ""time"": ""2100"",
-                    ""windspeedKmph"": ""10""
-                }
-            ]
-        },
-        {
-                ""astronomy"": [
-                    {
-                    ""sunrise"": ""05:09 AM"",
-                    ""sunset"": ""08:59 PM""
-                    }
-            ],
-            ""date"": ""2021-05-26"",
-            ""hourly"": [
-                {
-                    ""FeelsLikeC"": ""10"",
-                    ""WindGustKmph"": ""31"",
-                    ""chanceofrain"": ""0"",
-                    ""chanceofsnow"": ""0"",
-                    ""cloudcover"": ""0"",
-                    ""precipMM"": ""0"",
-                    ""tempC"": ""12"",
-                    ""time"": ""1200"",
-                    ""windspeedKmph"": ""19""
-                },
-                                {
-                    ""FeelsLikeC"": ""12"",
-                    ""WindGustKmph"": ""31"",
-                    ""chanceofrain"": ""0"",
-                    ""chanceofsnow"": ""80"",
-                    ""cloudcover"": ""92"",
-                    ""precipMM"": ""4.5"",
-                    ""tempC"": ""19"",
-                    ""time"": ""2100"",
-                    ""windspeedKmph"": ""19""
-                }
-            ]
-        }
-    ]
-}";
-        }
-
-        [TestMethod]
-        public void JsonParserTestCurrent()
-        {
-            TagInfo.CreateDictionaries();
-
-            string data = SetBasicData();
-
-            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
-            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
-
-            Mock<IDataLoader> l = new Mock<IDataLoader>();
-            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
-
-            JsonParser target = new JsonParser(dl.Object, l.Object);
-
-            target.ParsePrediction();
-            WeatherInfo current = target.Current;
-
-            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 25, 13, 29, 0), 4, 0, 3.611, ValueToConditions.CloudCoverToConditions(100), 0), current);
-        }
-
-        [TestMethod]
-        public void JsonParserTestPrediction()
-        {
-            string data = SetBasicData();
-
-            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
-            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
-
-            Mock<IDataLoader> l = new Mock<IDataLoader>();
-            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
-
-            JsonParser target = new JsonParser(dl.Object, l.Object);
-
-            target.ParsePrediction();
-            List<WeatherInfo> retVal = target.Predictions;
-
-            Assert.AreEqual(6, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 25, 0, 0, 0), 7, 87, 5.277, ValueToConditions.CloudCoverToConditions(92), 12), retVal[0]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 25, 12, 0, 0), 8, 50, 2.77778, ValueToConditions.CloudCoverToConditions(60), 24), retVal[1]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 26, 12, 0, 0), 10, 0, 5.27778, ValueToConditions.CloudCoverToConditions(0), 9), retVal[2]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 26, 21, 0, 0), 12, 80, 5.27778, ValueToConditions.CloudCoverToConditions(92), 21), retVal[3]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 27, 18, 0, 0), 17, 7, 2.5, ValueToConditions.CloudCoverToConditions(10), 3), retVal[4]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2021, 5, 27, 21, 0, 0), 9, 87, 2.77778, WeatherConditions.Dark, 24), retVal[5]);
-        }
-
-        [TestMethod]
-        public void JsonParserEncompassSunRiseSetTimes()
-        {
-            string data = SetAstronomyData();
-
-            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
-            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
-
-            Mock<IDataLoader> l = new Mock<IDataLoader>();
-            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
-
-            JsonParser target = new JsonParser(dl.Object, l.Object);
-
-            target.ParsePrediction();
-            List<WeatherInfo> retVal = target.Predictions;
-
-            Assert.AreEqual(8, retVal.Count);
-            Assert.AreEqual(WeatherConditions.Dark, retVal[0].condition);
-            Assert.AreEqual(WeatherConditions.Dark, retVal[1].condition);
-            Assert.AreNotEqual(WeatherConditions.Dark, retVal[2].condition);
-            Assert.AreNotEqual(WeatherConditions.Dark, retVal[3].condition);
-            Assert.AreEqual(WeatherConditions.Dark, retVal[4].condition);
-            Assert.AreEqual(WeatherConditions.Dark, retVal[5].condition);
-
-            Assert.AreNotEqual(WeatherConditions.Dark, retVal[6].condition);
-            Assert.AreEqual(WeatherConditions.Dark, retVal[7].condition);
-        }
-
-        #endregion
-
-        #region GetPredictionForTime
-        [TestMethod]
-        public void GetPredictionForTimeFilter()
-        {
-            string data = "";
-            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
-            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
-
-            Mock<IDataLoader> l = new Mock<IDataLoader>();
-            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
-
-            JsonParser target = new JsonParser(dl.Object, l.Object);
-
-            List<WeatherInfo> pred = new List<WeatherInfo>();
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
-
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 9, 0, 0), 8, 1, 2, 60_000, 15));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 0, 0, 0), 8, 1, 2, 60_000, 3));
-
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 3, 0, 0), 8, 1, 2, 60_000, 3));
-
-            target.Predictions = pred;
-
-            List<WeatherInfo> retVal = target.GetPredictionForTime(new DateTime(2000, 1, 1, 6, 0, 0), new DateTime(2000, 1, 3, 0, 0, 0));
-
-            Assert.AreEqual(6, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6), retVal[0]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6), retVal[1]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12), retVal[2]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3), retVal[3]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 9, 0, 0), 8, 1, 2, 60_000, 15), retVal[4]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 3, 0, 0, 0), 8, 1, 2, 60_000, 3), retVal[5]);
-        }
-
-        [TestMethod]
-        public void GetPredictionForTimeInvalidInput()
-        {
-            string data = "";
-            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
-            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
-
-            Mock<IDataLoader> l = new Mock<IDataLoader>();
-            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
-
-            JsonParser target = new JsonParser(dl.Object, l.Object);
-
-            List<WeatherInfo> pred = new List<WeatherInfo>();
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
-
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 9, 0, 0), 8, 1, 2, 60_000, 15));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 0, 0, 0), 8, 1, 2, 60_000, 3));
-
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 3, 0, 0), 8, 1, 2, 60_000, 3));
-
-            target.Predictions = pred;
-
-            List<WeatherInfo> retVal = target.GetPredictionForTime(new DateTime(2000, 1, 3, 0, 0, 0), new DateTime(2000, 1, 1, 6, 0, 0));
-            Assert.AreEqual(null, retVal);
-        }
-
-        [TestMethod]
-        public void GetPredictionForTimeAllTo()
-        {
-            string data = "";
-            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
-            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
-
-            Mock<IDataLoader> l = new Mock<IDataLoader>();
-            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
-
-            JsonParser target = new JsonParser(dl.Object, l.Object);
-
-            List<WeatherInfo> pred = new List<WeatherInfo>();
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
-
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 9, 0, 0), 8, 1, 2, 60_000, 15));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 0, 0, 0), 8, 1, 2, 60_000, 3));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 3, 3, 0, 0), 8, 1, 2, 60_000, 3));
-
-            target.Predictions = pred;
-
-            List<WeatherInfo> retVal = target.GetPredictionForTime(DateTime.MinValue, new DateTime(2000, 1, 2, 6, 0, 0));
-
-            Assert.AreEqual(5, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3), retVal[0]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6), retVal[1]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6), retVal[2]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12), retVal[3]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3), retVal[4]);
-        }
-
-        [TestMethod]
-        public void GetPredictionForTimeAllFrom()
-        {
-            string data = "";
-            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
-            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
-
-            Mock<IDataLoader> l = new Mock<IDataLoader>();
-            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
-
-            JsonParser target = new JsonParser(dl.Object, l.Object);
-
-            List<WeatherInfo> pred = new List<WeatherInfo>();
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 3));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 6, 0, 0), 8, 1, 2, 60_000, 3));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 9, 0, 0), 8, 1, 2, 60_000, 3));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
-
-            target.Predictions = pred;
-
-            List<WeatherInfo> retVal = target.GetPredictionForTime(new DateTime(2000, 1, 1, 12, 0, 0), DateTime.MaxValue);
-
-            Assert.AreEqual(3, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6), retVal[0]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12), retVal[1]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3), retVal[2]);
-        }
-
-        public void GetPredictionForTimeAll()
-        {
-
-            // TODO make an input file
-            string data = "";
-            Mock<DataDownloader> dl = new Mock<DataDownloader>("", "", "");
-            dl.Setup(m => m.DownloadWeatherPrediction()).Returns("test");
-
-            Mock<IDataLoader> l = new Mock<IDataLoader>();
-            l.Setup(m => m.LoadPredictionFile("test")).Returns(data);
-
-            JsonParser target = new JsonParser(dl.Object, l.Object);
-
-            List<WeatherInfo> pred = new List<WeatherInfo>();
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12));
-            pred.Add(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3));
-
-            target.Predictions = pred;
-
-            List<WeatherInfo> retVal = target.GetPredictionForTime(DateTime.MinValue, DateTime.MaxValue);
-
-            Assert.AreEqual(5, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 0, 0, 0), 8, 1, 2, 60_000, 3), retVal[0]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 3, 0, 0), 8, 1, 2, 60_000, 6), retVal[1]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 12, 0, 0), 8, 1, 2, 60_000, 6), retVal[2]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 18, 0, 0), 8, 1, 2, 60_000, 12), retVal[3]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 2, 6, 0, 0), 8, 1, 2, 60_000, 3), retVal[4]);
-        }
-        #endregion
-
-        #endregion
-    }
-}
diff --git a/Server/TestProject/ParserTests/LoginParserTesting.cs b/Server/TestProject/ParserTests/LoginParserTesting.cs
deleted file mode 100644
index bca6d55..0000000
--- a/Server/TestProject/ParserTests/LoginParserTesting.cs
+++ /dev/null
@@ -1,314 +0,0 @@
-﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using ServerApp.Parser.Parsers;
-using System.Collections.Generic;
-using ServerApp.Parser.OutputInfo;
-using Moq;
-using ServerApp.Parser.InputData;
-
-namespace TestProject.ParserTests
-{
-    /// <summary>
-    /// Summary description for WeatherParserTesting
-    /// </summary>
-    [TestClass]
-    public class LoginParserTesting
-    {
-
-        #region Login parser
-
-        #region Parse days
-        [TestMethod]
-        public void ParseLoginDayOne()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<LogInInstance> data = new List<LogInInstance>();
-            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
-
-            LogInParser target = new LogInParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(2, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
-        }
-
-        [TestMethod]
-        public void ParseLoginDayOneFiltering()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<LogInInstance> data = new List<LogInInstance>();
-            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 6, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
-
-            LogInParser target = new LogInParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 1, 16, 0, 0));
-
-            Assert.AreEqual(2, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
-        }
-
-        [TestMethod]
-        public void ParseLoginDayTwo()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<LogInInstance> data = new List<LogInInstance>();
-            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 3, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EU", "Učebna", "EU-108", "uc233p02-fav"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
-
-            LogInParser target = new LogInParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 3, 0, 0, 0));
-
-            Assert.AreEqual(4, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
-
-            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("FEL", 5, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[3]);
-        }
-
-        [TestMethod]
-        public void ParseLoginDayTwoFiltering()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<LogInInstance> data = new List<LogInInstance>();
-            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 6, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 3, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EU", "Učebna", "EU-108", "uc233p02-fav"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 19, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 3, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 3, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
-
-            LogInParser target = new LogInParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 3, 0, 0, 0));
-
-            Assert.AreEqual(4, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
-
-            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("FEL", 5, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[3]);
-        }
-
-
-        [TestMethod]
-        public void ParseLoginDayNone()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<LogInInstance> data = new List<LogInInstance>();
-            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 3, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EU", "Učebna", "EU-108", "uc233p02-fav"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
-
-            LogInParser target = new LogInParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 1, 9, 0, 0));
-
-            Assert.AreEqual(0, retVal.Count);
-        }
-        #endregion
-
-        #region Parse hours
-        [TestMethod]
-        public void ParseLoginHourlyOne()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<LogInInstance> data = new List<LogInInstance>();
-            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 13, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 14, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
-
-            LogInParser target = new LogInParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(5, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
-            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
-            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[4]);
-        }
-
-        [TestMethod]
-        public void ParseLoginDayHourlyMultiple()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<LogInInstance> data = new List<LogInInstance>();
-            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 13, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 14, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
-
-            LogInParser target = new LogInParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(5, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
-            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
-            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 17, 0, 0), 2), retVal[4]);
-        }
-
-        [TestMethod]
-        public void ParseLoginHourlyFiltering()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<LogInInstance> data = new List<LogInInstance>();
-            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 13, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 14, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 19, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
-
-            LogInParser target = new LogInParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(5, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
-            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
-            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 17, 0, 0), 2), retVal[4]);
-        }
-
-        [TestMethod]
-        public void ParseLoginHourlyNone()
-        {
-            TagInfo.CreateDictionaries();
-
-            string path = "";
-            List<LogInInstance> data = new List<LogInInstance>();
-            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 9, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 19, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 19, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
-
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
-
-            LogInParser target = new LogInParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 10, 0, 0), new DateTime(2000, 1, 2, 10, 0, 0));
-
-            Assert.AreEqual(0, retVal.Count);
-        }
-        #endregion
-
-        #endregion
-
-    }
-}
diff --git a/Server/TestProject/ParserTests/TestingParser.cs b/Server/TestProject/ParserTests/TestingParser.cs
deleted file mode 100644
index 6855c3a..0000000
--- a/Server/TestProject/ParserTests/TestingParser.cs
+++ /dev/null
@@ -1,181 +0,0 @@
-﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using ServerApp.Parser.Parsers;
-using System.Collections.Generic;
-using ServerApp.Parser.OutputInfo;
-
-namespace TestProject.ParserTests
-{
-
-    [TestClass]
-    public class TestingParser
-    {
-        [TestMethod]
-        public void AbstactClassTest()
-        {
-            IDataParser p = new DataParser(null);
-            List<ActivityInfo> aa = p.AttendanceList;
-            List<WeatherInfo> wa = p.WeatherList;
-
-            DataParser pp = (DataParser)p;
-            List<ActivityInfo> ap = pp.AttendanceList;
-            List<WeatherInfo> wp = pp.WeatherList;
-
-            Assert.AreEqual(aa, ap);
-            Assert.AreEqual(wa, wp);
-        }
-
-        // ------------------------------------ MERGE LISTS -------------------------------------
-
-        #region Merge lists
-        [TestMethod]
-        public void MergeListsNull()
-        {
-            DataParser target = new DataParser(null);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = null;
-            List<ActivityInfo> pc = null;
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
-            Assert.AreEqual(0, retVal.Count);
-        }
-
-        [TestMethod]
-        public void MergeListsJisNull()
-        {
-            DataParser target = new DataParser(null);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = null;
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
-            Assert.AreEqual(pc, retVal);
-        }
-
-        [TestMethod]
-        public void MergeListsPcNull()
-        {
-            DataParser target = new DataParser(null);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = null;
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
-            Assert.AreEqual(jis, retVal);
-        }
-
-        [TestMethod]
-        public void MergeListsOneNoOverlap()
-        {
-            DataParser target = new DataParser(null);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 15, 0, 0), 3));
-            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 18, 0, 0), 3));
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
-
-            Assert.AreEqual(2, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 18, 0, 0), 3), retVal[1]);
-        }
-
-        [TestMethod]
-        public void MergeListsOneOverlap()
-        {
-            DataParser target = new DataParser(null);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 15, 0, 0), 3));
-            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 15, 0, 0), 3));
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
-
-            Assert.AreEqual(1, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FAV", 8, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[0]);
-        }
-
-        [TestMethod]
-        public void MergeListsTwoNoOverlap()
-        {
-            DataParser target = new DataParser(null);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 9, 0, 0), 3));
-            jis.Add(new ActivityInfo("FAV", 1, new DateTime(2001, 1, 1, 15, 0, 0), 3));
-            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3));
-            pc.Add(new ActivityInfo("FAV", 2, new DateTime(2001, 1, 1, 18, 0, 0), 3));
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
-
-            Assert.AreEqual(4, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 9, 0, 0), 3), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3), retVal[1]);
-            Assert.AreEqual(new ActivityInfo("FAV", 1, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("FAV", 2, new DateTime(2001, 1, 1, 18, 0, 0), 3), retVal[3]);
-        }
-
-        [TestMethod]
-        public void MergeListsTwoOverlap()
-        {
-            DataParser target = new DataParser(null);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 9, 0, 0), 3));
-            jis.Add(new ActivityInfo("FAV", 1, new DateTime(2001, 1, 1, 15, 0, 0), 3));
-            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3));
-            pc.Add(new ActivityInfo("FAV", 2, new DateTime(2001, 1, 1, 15, 0, 0), 3));
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
-
-            Assert.AreEqual(3, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2001, 1, 1, 9, 0, 0), 3), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3), retVal[1]);
-            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[2]);
-        }
-
-        [TestMethod]
-        public void MergeListsMultiple()
-        {
-            DataParser target = new DataParser(null);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            jis.Add(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 10, 9, 0, 0), 3));
-            jis.Add(new ActivityInfo("FAV", 1, new DateTime(2001, 1, 1, 15, 0, 0), 3));
-            jis.Add(new ActivityInfo("FDU", 3, new DateTime(2001, 4, 1, 15, 0, 0), 3));
-
-            pc.Add(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3));
-            pc.Add(new ActivityInfo("FAV", 2, new DateTime(2001, 1, 1, 15, 0, 0), 3));
-            pc.Add(new ActivityInfo("FAV", 5, new DateTime(2001, 4, 1, 15, 0, 0), 3));
-
-            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("MergeAttendance", jis, pc);
-
-            Assert.AreEqual(5, retVal.Count);
-            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 10, 9, 0, 0), 3), retVal[0]);
-            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 12, 0, 0), 3), retVal[1]);
-            Assert.AreEqual(new ActivityInfo("FAV", 3, new DateTime(2001, 1, 1, 15, 0, 0), 3), retVal[2]);
-            Assert.AreEqual(new ActivityInfo("FDU", 3, new DateTime(2001, 4, 1, 15, 0, 0), 3), retVal[3]);
-            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2001, 4, 1, 15, 0, 0), 3), retVal[4]);
-        }
-        #endregion
-
-    }
-}
diff --git a/Server/TestProject/ParserTests/WeatherParserTesting.cs b/Server/TestProject/ParserTests/WeatherParserTesting.cs
deleted file mode 100644
index 225180b..0000000
--- a/Server/TestProject/ParserTests/WeatherParserTesting.cs
+++ /dev/null
@@ -1,274 +0,0 @@
-﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using ServerApp.Parser.Parsers;
-using System.Collections.Generic;
-using ServerApp.Parser.OutputInfo;
-using Moq;
-using ServerApp.Parser.InputData;
-
-namespace TestProject.ParserTests
-{
-    /// <summary>
-    /// Summary description for WeatherParserTesting
-    /// </summary>
-    [TestClass]
-    public class WeatherParserTesting
-    {
-
-        #region Weather parser
-
-        #region Parse days
-        [TestMethod]
-        public void ParseWeatherDayOne()
-        {
-            string path = "";
-            List<WeatherInstance> data = new List<WeatherInstance>();
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 7, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 10, 3, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 12, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
-
-            WeatherParser target = new WeatherParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(1, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 8, 50, 1.25, 10_000, 18 - 7), retVal[0]);
-        }
-
-        [TestMethod]
-        public void ParseWeatherDayOneFiltering()
-        {
-            string path = "";
-            List<WeatherInstance> data = new List<WeatherInstance>();
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 7, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 10, 3, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 12, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 13, 0, 0), 12, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
-
-            WeatherParser target = new WeatherParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsDays", path, new DateTime(2000, 1, 1, 9, 0, 0), new DateTime(2000, 1, 1, 15, 0, 0));
-
-            Assert.AreEqual(1, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 9.75, 25, 1.75, 10_000, 18 - 7), retVal[0]);
-        }
-
-        [TestMethod]
-        public void ParseWeatherDayTwo()
-        {
-            string path = "";
-            List<WeatherInstance> data = new List<WeatherInstance>();
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 3, 3, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 12, 0, 0), 5, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
-
-            WeatherParser target = new WeatherParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
-
-            Assert.AreEqual(2, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 6, 100, 1, 10_000, 18 - 7), retVal[0]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 7, 0, 0), 10, 25, 2, 10_000, 18 - 7), retVal[1]);
-        }
-
-        [TestMethod]
-        public void ParseWeatherDayTwoFiltering()
-        {
-            string path = "";
-            List<WeatherInstance> data = new List<WeatherInstance>();
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 3, 3, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 12, 0, 0), 5, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
-
-            WeatherParser target = new WeatherParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsDays", path, new DateTime(2000, 1, 1, 8, 0, 0), new DateTime(2000, 1, 1, 11, 0, 0));
-
-            Assert.AreEqual(1, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 6, 100, 1, 10_000, 18 - 7), retVal[0]);
-            //Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 7, 0, 0), 10, 25, 2, 10_000, 18 - 7), retVal[1]);
-        }
-        #endregion
-
-        #region Parse hours
-        [TestMethod]
-        public void ParseWeatherHourOne()
-        {
-            string path = "";
-            List<WeatherInstance> data = new List<WeatherInstance>();
-
-            // day 1
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
-
-            WeatherParser target = new WeatherParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 8, 0, 0), new DateTime(2001, 1, 1, 11, 0, 0));
-
-            Assert.AreEqual(1, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 5, 100, 0, (double)0, 2), retVal[0]);
-        }
-
-        [TestMethod]
-        public void ParseWeatherHourMultiple()
-        {
-            string path = "";
-            List<WeatherInstance> data = new List<WeatherInstance>();
-
-            // day 1
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 3, 3, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-            // day 2
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 12, 0, 0), 5, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Sunny) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 15, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
-
-            WeatherParser target = new WeatherParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 8, 0, 0), new DateTime(2001, 1, 1, 11, 0, 0));
-
-            Assert.AreEqual(5, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 7, 0, 0), 5, 100, 0, (double)0, 2), retVal[0]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 9, 0, 0), 6.5, 100, 1.5, 10_000, 2), retVal[1]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 11, 0, 0), 5, 0, 2, 60_000, 2), retVal[2]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 13, 0, 0), 10, 25, 2, 10_000, 2), retVal[3]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 15, 0, 0), 15, 40, 2, 10_000, 2), retVal[4]);
-        }
-
-
-        [TestMethod]
-        public void ParseWeatherHourFiltering()
-        {
-            string path = "";
-            List<WeatherInstance> data = new List<WeatherInstance>();
-
-            // day 1
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 10, 0, 0), 3, 3, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-            // day 2
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 12, 0, 0), 5, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Sunny) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 13, 15, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
-
-            WeatherParser target = new WeatherParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 9, 0, 0), new DateTime(2000, 2, 1, 13, 0, 0));
-
-            Assert.AreEqual(3, retVal.Count);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 1, 1, 9, 0, 0), 6.5, 100, 1.5, 10_000, 2), retVal[0]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 11, 0, 0), 5, 0, 2, 60_000, 2), retVal[1]);
-            Assert.AreEqual(new WeatherInfo(new DateTime(2000, 2, 1, 13, 0, 0), 10, 33, 2, 10_000, 2), retVal[2]);
-        }
-
-        [TestMethod]
-        public void ParseWeatherHourNone()
-        {
-            string path = "";
-            List<WeatherInstance> data = new List<WeatherInstance>();
-
-            // day 1
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 8, 0, 0), 5, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 1, 1, 9, 0, 0), 10, 0, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Dark) / 1000));
-
-            // day 2
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 16, 0, 0), 10, 2, 0, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-            data.Add(new WeatherInstance(new DateTime(2000, 2, 1, 17, 0, 0), 15, 2, 1, ValueToConditions.TransferConditionsToLux(WeatherConditions.Overcast) / 1000));
-
-
-            Mock<IDataLoader> dl = new Mock<IDataLoader>();
-            dl.Setup(m => m.LoadWeatherFile(path)).Returns(data);
-
-            WeatherParser target = new WeatherParser(dl.Object);
-            PrivateObject obj = new PrivateObject(target);
-
-            List<ActivityInfo> jis = new List<ActivityInfo>();
-            List<ActivityInfo> pc = new List<ActivityInfo>();
-
-            List<WeatherInfo> retVal = (List<WeatherInfo>)obj.Invoke("ProcessOneWeatherFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 10, 0, 0), new DateTime(2000, 2, 1, 15, 0, 0));
-
-            Assert.AreEqual(0, retVal.Count);
-        }
-        #endregion
-
-        #endregion
-    }
-}
diff --git a/Server/TestProject/Properties/AssemblyInfo.cs b/Server/TestProject/Properties/AssemblyInfo.cs
deleted file mode 100644
index 16e7cf6..0000000
--- a/Server/TestProject/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-[assembly: AssemblyTitle("TestProject")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("TestProject")]
-[assembly: AssemblyCopyright("Copyright ©  2021")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-[assembly: ComVisible(false)]
-
-[assembly: Guid("8a09db8e-64b1-4d55-991e-7f7b21996b45")]
-
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Server/TestProject/TestProject.csproj b/Server/TestProject/TestProject.csproj
deleted file mode 100644
index 2c1f949..0000000
--- a/Server/TestProject/TestProject.csproj
+++ /dev/null
@@ -1,94 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="..\packages\MSTest.TestAdapter.2.1.2\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.2.1.2\build\net45\MSTest.TestAdapter.props')" />
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{8A09DB8E-64B1-4D55-991E-7F7B21996B45}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>TestProject</RootNamespace>
-    <AssemblyName>TestProject</AssemblyName>
-    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
-    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
-    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
-    <IsCodedUITest>False</IsCodedUITest>
-    <TestProjectType>UnitTest</TestProjectType>
-    <NuGetPackageImportStamp>
-    </NuGetPackageImportStamp>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x64</PlatformTarget>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
-      <HintPath>..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <HintPath>..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <HintPath>..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
-    </Reference>
-    <Reference Include="Moq, Version=4.16.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
-      <HintPath>..\packages\Moq.4.16.1\lib\net45\Moq.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Configuration" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
-      <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="ParserTests\JsonParserTesting.cs" />
-    <Compile Include="ParserTests\JisParserTesting.cs" />
-    <Compile Include="TestingDataDownloader.cs" />
-    <Compile Include="ParserTests\TestingParser.cs" />
-    <Compile Include="ParserTests\LoginParserTesting.cs" />
-    <Compile Include="ParserTests\WeatherParserTesting.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="app.config" />
-    <None Include="packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\ServerApp\ServerApp.csproj">
-      <Project>{18fcfb20-b860-4147-8e7c-8a0dd84c55d4}</Project>
-      <Name>ServerApp</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
-    <PropertyGroup>
-      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
-    </PropertyGroup>
-    <Error Condition="!Exists('..\packages\MSTest.TestAdapter.2.1.2\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.2.1.2\build\net45\MSTest.TestAdapter.props'))" />
-    <Error Condition="!Exists('..\packages\MSTest.TestAdapter.2.1.2\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.2.1.2\build\net45\MSTest.TestAdapter.targets'))" />
-  </Target>
-  <Import Project="..\packages\MSTest.TestAdapter.2.1.2\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.2.1.2\build\net45\MSTest.TestAdapter.targets')" />
-</Project>
\ No newline at end of file
diff --git a/Server/TestProject/TestingDataDownloader.cs b/Server/TestProject/TestingDataDownloader.cs
deleted file mode 100644
index 3502151..0000000
--- a/Server/TestProject/TestingDataDownloader.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-﻿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()
-		{
-
-		}
-	}
-}
diff --git a/Server/TestProject/app.config b/Server/TestProject/app.config
deleted file mode 100644
index 58b89cf..0000000
--- a/Server/TestProject/app.config
+++ /dev/null
@@ -1,15 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/Server/TestProject/packages.config b/Server/TestProject/packages.config
deleted file mode 100644
index 2bf9538..0000000
--- a/Server/TestProject/packages.config
+++ /dev/null
@@ -1,9 +0,0 @@
-﻿<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Castle.Core" version="4.4.0" targetFramework="net472" />
-  <package id="Moq" version="4.16.1" targetFramework="net472" />
-  <package id="MSTest.TestAdapter" version="2.1.2" targetFramework="net472" />
-  <package id="MSTest.TestFramework" version="2.1.2" targetFramework="net472" />
-  <package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net472" />
-  <package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
-</packages>
\ No newline at end of file
