First commit

Edwin [2016-07-24 18:58:27]
First commit
Filename
PokemonGo.RocketAPI.Console/App.config
PokemonGo.RocketAPI.Console/PokemonGo.RocketAPI.Console.csproj
PokemonGo.RocketAPI.Console/Program.cs
PokemonGo.RocketAPI.Console/Properties/Resources.Designer.cs
PokemonGo.RocketAPI.Console/Properties/Resources.resx
PokemonGo.RocketAPI.Console/Settings.cs
PokemonGo.RocketAPI.Console/UserSettings.Designer.cs
PokemonGo.RocketAPI.Console/UserSettings.cs
PokemonGo.RocketAPI.Console/UserSettings.settings
PokemonGo.RocketAPI.Logic/Inventory.cs
PokemonGo.RocketAPI.Logic/Logic.cs
PokemonGo.RocketAPI.Logic/Navigation.cs
PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
PokemonGo.RocketAPI.Logic/Utils/GPXReader.cs
PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
PokemonGo.RocketAPI/Client.cs
PokemonGo.RocketAPI/Extensions/HttpClientExtensions.cs
PokemonGo.RocketAPI/Helpers/Git.cs
PokemonGo.RocketAPI/Helpers/RandomHelper.cs
PokemonGo.RocketAPI/Helpers/RetryHandler.cs
PokemonGo.RocketAPI/ISettings.cs
PokemonGo.RocketAPI/Logging/Logger.cs
PokemonGo.RocketAPI/Login/GoogleLogin.cs
PokemonGo.RocketAPI/Login/PtcLogin.cs
PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
PokemonGo.RocketAPI/PokemonInfo.cs
diff --git a/PokemonGo.RocketAPI.Console/App.config b/PokemonGo.RocketAPI.Console/App.config
index 4f58a92..33b0e91 100644
--- a/PokemonGo.RocketAPI.Console/App.config
+++ b/PokemonGo.RocketAPI.Console/App.config
@@ -1,75 +1,75 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-    <configSections>
-        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
-            <section name="PokemonGo.RocketAPI.Console.UserSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
-            <section name="PokemonGo.RocketAPI.Console.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
-        </sectionGroup>
-    </configSections>
-    <startup>
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
-    </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-  <userSettings>
-    <PokemonGo.RocketAPI.Console.UserSettings>
-      <setting name="DefaultAltitude" serializeAs="String">
-        <value>10</value>
-      </setting>
-      <setting name="KeepMinIVPercentage" serializeAs="String">
-        <value>85</value>
-      </setting>
-      <setting name="KeepMinCP" serializeAs="String">
-        <value>1000</value>
-      </setting>
-      <setting name="WalkingSpeedInKilometerPerHour" serializeAs="String">
-        <value>250</value>
-      </setting>
-      <setting name="DefaultLatitude" serializeAs="String">
-        <value>0</value>
-      </setting>
-      <setting name="DefaultLongitude" serializeAs="String">
-        <value>0</value>
-      </setting>
-      <setting name="EvolveAllPokemonWithEnoughCandy" serializeAs="String">
-        <value>False</value>
-      </setting>
-      <setting name="TransferDuplicatePokemon" serializeAs="String">
-        <value>True</value>
-      </setting>
-      <setting name="UsePokemonToNotCatchFilter" serializeAs="String">
-        <value>False</value>
-      </setting>
-      <setting name="KeepMinDuplicatePokemon" serializeAs="String">
-        <value>2</value>
-      </setting>
-      <setting name="AuthType" serializeAs="String">
-        <value>Google</value>
-      </setting>
-      <setting name="PtcUsername" serializeAs="String">
-        <value>username</value>
-      </setting>
-      <setting name="PtcPassword" serializeAs="String">
-        <value>password</value>
-      </setting>
-      <setting name="PrioritizeIVOverCP" serializeAs="String">
-        <value>True</value>
-      </setting>
-      <setting name="MaxTravelDistanceInMeters" serializeAs="String">
-        <value>1000</value>
-      </setting>
-      <setting name="UseGPXPathing" serializeAs="String">
-        <value>False</value>
-      </setting>
-      <setting name="GPXFile" serializeAs="String">
-        <value>GPXFile.GPX</value>
-      </setting>
-    </PokemonGo.RocketAPI.Console.UserSettings>
-  </userSettings>
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+    <configSections>
+        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
+            <section name="PokemonGo.RocketAPI.Console.UserSettings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+            <section name="PokemonGo.RocketAPI.Console.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
+        </sectionGroup>
+    </configSections>
+    <startup>
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+    </startup>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+  <userSettings>
+    <PokemonGo.RocketAPI.Console.UserSettings>
+      <setting name="DefaultAltitude" serializeAs="String">
+        <value>10</value>
+      </setting>
+      <setting name="KeepMinIVPercentage" serializeAs="String">
+        <value>85</value>
+      </setting>
+      <setting name="KeepMinCP" serializeAs="String">
+        <value>1000</value>
+      </setting>
+      <setting name="WalkingSpeedInKilometerPerHour" serializeAs="String">
+        <value>250</value>
+      </setting>
+      <setting name="DefaultLatitude" serializeAs="String">
+        <value>0</value>
+      </setting>
+      <setting name="DefaultLongitude" serializeAs="String">
+        <value>0</value>
+      </setting>
+      <setting name="EvolveAllPokemonWithEnoughCandy" serializeAs="String">
+        <value>False</value>
+      </setting>
+      <setting name="TransferDuplicatePokemon" serializeAs="String">
+        <value>True</value>
+      </setting>
+      <setting name="UsePokemonToNotCatchFilter" serializeAs="String">
+        <value>False</value>
+      </setting>
+      <setting name="KeepMinDuplicatePokemon" serializeAs="String">
+        <value>2</value>
+      </setting>
+      <setting name="AuthType" serializeAs="String">
+        <value>Google</value>
+      </setting>
+      <setting name="PtcUsername" serializeAs="String">
+        <value>username</value>
+      </setting>
+      <setting name="PtcPassword" serializeAs="String">
+        <value>password</value>
+      </setting>
+      <setting name="PrioritizeIVOverCP" serializeAs="String">
+        <value>True</value>
+      </setting>
+      <setting name="MaxTravelDistanceInMeters" serializeAs="String">
+        <value>1000</value>
+      </setting>
+      <setting name="UseGPXPathing" serializeAs="String">
+        <value>False</value>
+      </setting>
+      <setting name="GPXFile" serializeAs="String">
+        <value>GPXFile.GPX</value>
+      </setting>
+    </PokemonGo.RocketAPI.Console.UserSettings>
+  </userSettings>
 </configuration>
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Console/PokemonGo.RocketAPI.Console.csproj b/PokemonGo.RocketAPI.Console/PokemonGo.RocketAPI.Console.csproj
index 7dc5d0d..6896053 100644
--- a/PokemonGo.RocketAPI.Console/PokemonGo.RocketAPI.Console.csproj
+++ b/PokemonGo.RocketAPI.Console/PokemonGo.RocketAPI.Console.csproj
@@ -1,106 +1,106 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <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>{1FEA147E-F704-497B-A538-00B053B5F672}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>PokemonGo.RocketAPI.Console</RootNamespace>
-    <AssemblyName>PokemonGo.RocketAPI.Console</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
-    <AssemblyInfoFilePath>..\PokemonGo.RocketAPI\Properties\AssemblyInfo.cs</AssemblyInfoFilePath>
-    <UpdateAssemblyVersion>True</UpdateAssemblyVersion>
-    <UpdateAssemblyFileVersion>False</UpdateAssemblyFileVersion>
-    <UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
-    <AssemblyVersionSettings>YearStamp.MonthStamp.DayStamp.Increment</AssemblyVersionSettings>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\dotnet\Google.Protobuf.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Configuration" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Program.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Properties\Resources.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTime>True</DesignTime>
-      <DependentUpon>Resources.resx</DependentUpon>
-    </Compile>
-    <Compile Include="Settings.cs" />
-    <Compile Include="UserSettings.cs" />
-    <Compile Include="UserSettings.Designer.cs">
-      <AutoGen>True</AutoGen>
-      <DesignTimeSharedInput>True</DesignTimeSharedInput>
-      <DependentUpon>UserSettings.settings</DependentUpon>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config">
-      <SubType>Designer</SubType>
-    </None>
-    <None Include="packages.config" />
-    <None Include="UserSettings.settings">
-      <Generator>SettingsSingleFileGenerator</Generator>
-      <LastGenOutput>UserSettings.Designer.cs</LastGenOutput>
-    </None>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\PokemonGo.RocketAPI.Logic\PokemonGo.RocketAPI.Logic.csproj">
-      <Project>{0739E40D-C589-4AEB-93E5-EE8CD6773C60}</Project>
-      <Name>PokemonGo.RocketAPI.Logic</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\PokemonGo.RocketAPI\PokemonGo.RocketAPI.csproj">
-      <Project>{05D2DA44-1B8E-4CF7-94ED-4D52451CD095}</Project>
-      <Name>PokemonGo.RocketAPI</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Properties\Resources.resx">
-      <Generator>ResXFileCodeGenerator</Generator>
-      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <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>{1FEA147E-F704-497B-A538-00B053B5F672}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>PokemonGo.RocketAPI.Console</RootNamespace>
+    <AssemblyName>PokemonGo.RocketAPI.Console</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
+    <AssemblyInfoFilePath>..\PokemonGo.RocketAPI\Properties\AssemblyInfo.cs</AssemblyInfoFilePath>
+    <UpdateAssemblyVersion>True</UpdateAssemblyVersion>
+    <UpdateAssemblyFileVersion>False</UpdateAssemblyFileVersion>
+    <UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
+    <AssemblyVersionSettings>YearStamp.MonthStamp.DayStamp.Increment</AssemblyVersionSettings>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\dotnet\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Settings.cs" />
+    <Compile Include="UserSettings.cs" />
+    <Compile Include="UserSettings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+      <DependentUpon>UserSettings.settings</DependentUpon>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config">
+      <SubType>Designer</SubType>
+    </None>
+    <None Include="packages.config" />
+    <None Include="UserSettings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>UserSettings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\PokemonGo.RocketAPI.Logic\PokemonGo.RocketAPI.Logic.csproj">
+      <Project>{0739E40D-C589-4AEB-93E5-EE8CD6773C60}</Project>
+      <Name>PokemonGo.RocketAPI.Logic</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\PokemonGo.RocketAPI\PokemonGo.RocketAPI.csproj">
+      <Project>{05D2DA44-1B8E-4CF7-94ED-4D52451CD095}</Project>
+      <Name>PokemonGo.RocketAPI</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
   </Target>
   <Target Name="AfterBuild">
   </Target>
-  -->
+  -->
 </Project>
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Console/Program.cs b/PokemonGo.RocketAPI.Console/Program.cs
index 117317a..bc62dcf 100644
--- a/PokemonGo.RocketAPI.Console/Program.cs
+++ b/PokemonGo.RocketAPI.Console/Program.cs
@@ -1,56 +1,56 @@
-#region
-
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using PokemonGo.RocketAPI.Exceptions;
-using PokemonGo.RocketAPI.Logging;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Console
-{
-    internal class Program
-    {
-
-        private static void Main(string[] args)
-        {
-            AppDomain.CurrentDomain.UnhandledException
-                += delegate (object sender, UnhandledExceptionEventArgs eargs)
-                {
-                    Exception exception = (Exception)eargs.ExceptionObject;
-                    System.Console.WriteLine("Unhandled exception: " + exception);
-                    Environment.Exit(1);
-                };
-
-            Logger.SetLogger();
-
-            Task.Run(() =>
-            {
-                try
-                {
-                    new Logic.Logic(new Settings()).Execute().Wait();
-                }
-                catch (PtcOfflineException)
-                {
-                    Logger.Write("PTC Servers are probably down OR your credentials are wrong. Try google", LogLevel.Error);
-                    Logger.Write("Trying again in 60 seconds...");
-                    Thread.Sleep(60000);
-                    new Logic.Logic(new Settings()).Execute().Wait();
-                }
-                catch (AccountNotVerifiedException)
-                {
-                    Logger.Write("Account not verified. - Exiting");
-                    Environment.Exit(0);
-                }
-                catch (Exception ex)
-                {
-                    Logger.Write($"Unhandled exception: {ex}", LogLevel.Error);
-                    new Logic.Logic(new Settings()).Execute().Wait();
-                }
-            });
-             System.Console.ReadLine();
-        }
-    }
+#region
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using PokemonGo.RocketAPI.Exceptions;
+using PokemonGo.RocketAPI.Logging;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI.Console
+{
+    internal class Program
+    {
+
+        private static void Main(string[] args)
+        {
+            AppDomain.CurrentDomain.UnhandledException
+                += delegate (object sender, UnhandledExceptionEventArgs eargs)
+                {
+                    Exception exception = (Exception)eargs.ExceptionObject;
+                    System.Console.WriteLine("Unhandled exception: " + exception);
+                    Environment.Exit(1);
+                };
+
+            Logger.SetLogger();
+
+            Task.Run(() =>
+            {
+                try
+                {
+                    new Logic.Logic(new Settings()).Execute().Wait();
+                }
+                catch (PtcOfflineException)
+                {
+                    Logger.Write("PTC Servers are probably down OR your credentials are wrong. Try google", LogLevel.Error);
+                    Logger.Write("Trying again in 60 seconds...");
+                    Thread.Sleep(60000);
+                    new Logic.Logic(new Settings()).Execute().Wait();
+                }
+                catch (AccountNotVerifiedException)
+                {
+                    Logger.Write("Account not verified. - Exiting");
+                    Environment.Exit(0);
+                }
+                catch (Exception ex)
+                {
+                    Logger.Write($"Unhandled exception: {ex}", LogLevel.Error);
+                    new Logic.Logic(new Settings()).Execute().Wait();
+                }
+            });
+             System.Console.ReadLine();
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Console/Properties/Resources.Designer.cs b/PokemonGo.RocketAPI.Console/Properties/Resources.Designer.cs
index f3c0fa2..1aa73bd 100644
--- a/PokemonGo.RocketAPI.Console/Properties/Resources.Designer.cs
+++ b/PokemonGo.RocketAPI.Console/Properties/Resources.Designer.cs
@@ -1,63 +1,63 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     Dieser Code wurde von einem Tool generiert.
-//     Laufzeitversion:4.0.30319.42000
-//
-//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
-//     der Code erneut generiert wird.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace PokemonGo.RocketAPI.Console.Properties {
-    using System;
-
-
-    /// <summary>
-    ///   Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
-    /// </summary>
-    // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
-    // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
-    // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
-    // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
-    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    internal class Resources {
-
-        private static global::System.Resources.ResourceManager resourceMan;
-
-        private static global::System.Globalization.CultureInfo resourceCulture;
-
-        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
-        internal Resources() {
-        }
-
-        /// <summary>
-        ///   Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Resources.ResourceManager ResourceManager {
-            get {
-                if (object.ReferenceEquals(resourceMan, null)) {
-                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PokemonGo.RocketAPI.Console.Properties.Resources", typeof(Resources).Assembly);
-                    resourceMan = temp;
-                }
-                return resourceMan;
-            }
-        }
-
-        /// <summary>
-        ///   Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
-        ///   Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
-        /// </summary>
-        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
-        internal static global::System.Globalization.CultureInfo Culture {
-            get {
-                return resourceCulture;
-            }
-            set {
-                resourceCulture = value;
-            }
-        }
-    }
-}
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.42000
+//
+//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace PokemonGo.RocketAPI.Console.Properties {
+    using System;
+
+
+    /// <summary>
+    ///   Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+    /// </summary>
+    // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+    // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+    // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+    // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+
+        /// <summary>
+        ///   Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PokemonGo.RocketAPI.Console.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+        ///   Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}
diff --git a/PokemonGo.RocketAPI.Console/Properties/Resources.resx b/PokemonGo.RocketAPI.Console/Properties/Resources.resx
index 29dcb1b..1af7de1 100644
--- a/PokemonGo.RocketAPI.Console/Properties/Resources.resx
+++ b/PokemonGo.RocketAPI.Console/Properties/Resources.resx
@@ -1,120 +1,120 @@
-<?xml version="1.0" encoding="utf-8"?>
-<root>
-  <!--
-    Microsoft ResX Schema
-
-    Version 2.0
-
-    The primary goals of this format is to allow a simple XML format
-    that is mostly human readable. The generation and parsing of the
-    various data types are done through the TypeConverter classes
-    associated with the data types.
-
-    Example:
-
-    ... ado.net/XML headers & schema ...
-    <resheader name="resmimetype">text/microsoft-resx</resheader>
-    <resheader name="version">2.0</resheader>
-    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
-    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
-    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
-    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
-    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
-        <value>[base64 mime encoded serialized .NET Framework object]</value>
-    </data>
-    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
-        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
-        <comment>This is a comment</comment>
-    </data>
-
-    There are any number of "resheader" rows that contain simple
-    name/value pairs.
-
-    Each data row contains a name, and value. The row also contains a
-    type or mimetype. Type corresponds to a .NET class that support
-    text/value conversion through the TypeConverter architecture.
-    Classes that don't support this are serialized and stored with the
-    mimetype set.
-
-    The mimetype is used for serialized objects, and tells the
-    ResXResourceReader how to depersist the object. This is currently not
-    extensible. For a given mimetype the value must be set accordingly:
-
-    Note - application/x-microsoft.net.object.binary.base64 is the format
-    that the ResXResourceWriter will generate, however the reader can
-    read any of the formats listed below.
-
-    mimetype: application/x-microsoft.net.object.binary.base64
-    value   : The object must be serialized with
-            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.soap.base64
-    value   : The object must be serialized with
-            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
-            : and then encoded with base64 encoding.
-
-    mimetype: application/x-microsoft.net.object.bytearray.base64
-    value   : The object must be serialized into a byte array
-            : using a System.ComponentModel.TypeConverter
-            : and then encoded with base64 encoding.
-    -->
-  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
-    <xsd:element name="root" msdata:IsDataSet="true">
-      <xsd:complexType>
-        <xsd:choice maxOccurs="unbounded">
-          <xsd:element name="metadata">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" />
-              </xsd:sequence>
-              <xsd:attribute name="name" use="required" type="xsd:string" />
-              <xsd:attribute name="type" type="xsd:string" />
-              <xsd:attribute name="mimetype" type="xsd:string" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="assembly">
-            <xsd:complexType>
-              <xsd:attribute name="alias" type="xsd:string" />
-              <xsd:attribute name="name" type="xsd:string" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="data">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
-              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
-              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
-              <xsd:attribute ref="xml:space" />
-            </xsd:complexType>
-          </xsd:element>
-          <xsd:element name="resheader">
-            <xsd:complexType>
-              <xsd:sequence>
-                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
-              </xsd:sequence>
-              <xsd:attribute name="name" type="xsd:string" use="required" />
-            </xsd:complexType>
-          </xsd:element>
-        </xsd:choice>
-      </xsd:complexType>
-    </xsd:element>
-  </xsd:schema>
-  <resheader name="resmimetype">
-    <value>text/microsoft-resx</value>
-  </resheader>
-  <resheader name="version">
-    <value>2.0</value>
-  </resheader>
-  <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
-  <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
-  </resheader>
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!--
+    Microsoft ResX Schema
+
+    Version 2.0
+
+    The primary goals of this format is to allow a simple XML format
+    that is mostly human readable. The generation and parsing of the
+    various data types are done through the TypeConverter classes
+    associated with the data types.
+
+    Example:
+
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+
+    There are any number of "resheader" rows that contain simple
+    name/value pairs.
+
+    Each data row contains a name, and value. The row also contains a
+    type or mimetype. Type corresponds to a .NET class that support
+    text/value conversion through the TypeConverter architecture.
+    Classes that don't support this are serialized and stored with the
+    mimetype set.
+
+    The mimetype is used for serialized objects, and tells the
+    ResXResourceReader how to depersist the object. This is currently not
+    extensible. For a given mimetype the value must be set accordingly:
+
+    Note - application/x-microsoft.net.object.binary.base64 is the format
+    that the ResXResourceWriter will generate, however the reader can
+    read any of the formats listed below.
+
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
 </root>
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Console/Settings.cs b/PokemonGo.RocketAPI.Console/Settings.cs
index 16711c0..83176f3 100644
--- a/PokemonGo.RocketAPI.Console/Settings.cs
+++ b/PokemonGo.RocketAPI.Console/Settings.cs
@@ -1,167 +1,167 @@
-#region
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using PokemonGo.RocketAPI.Enums;
-using PokemonGo.RocketAPI.GeneratedCode;
-using PokemonGo.RocketAPI.Logging;
-using System.Text.RegularExpressions;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Console
-{
-    public class Settings : ISettings
-    {
-        public AuthType AuthType => (AuthType)Enum.Parse(typeof(AuthType), UserSettings.Default.AuthType, true);
-        public string PtcUsername => UserSettings.Default.PtcUsername;
-        public string PtcPassword => UserSettings.Default.PtcPassword;
-        public double DefaultLatitude => UserSettings.Default.DefaultLatitude;
-        public double DefaultLongitude => UserSettings.Default.DefaultLongitude;
-        public double DefaultAltitude => UserSettings.Default.DefaultAltitude;
-
-        public float KeepMinIVPercentage => UserSettings.Default.KeepMinIVPercentage;
-        public int KeepMinCP => UserSettings.Default.KeepMinCP;
-        public double WalkingSpeedInKilometerPerHour => UserSettings.Default.WalkingSpeedInKilometerPerHour;
-        public bool EvolveAllPokemonWithEnoughCandy => UserSettings.Default.EvolveAllPokemonWithEnoughCandy;
-        public bool TransferDuplicatePokemon => UserSettings.Default.TransferDuplicatePokemon;
-        public bool UsePokemonToNotCatchFilter => UserSettings.Default.UsePokemonToNotCatchFilter;
-        public int KeepMinDuplicatePokemon => UserSettings.Default.KeepMinDuplicatePokemon;
-        public bool PrioritizeIVOverCP => UserSettings.Default.PrioritizeIVOverCP;
-        public int MaxTravelDistanceInMeters => UserSettings.Default.MaxTravelDistanceInMeters;
-
-        public bool UseGPXPathing => UserSettings.Default.UseGPXPathing;
-        public string GPXFile => UserSettings.Default.GPXFile;
-
-        private ICollection<PokemonId> _pokemonsToEvolve;
-        private ICollection<PokemonId> _pokemonsNotToTransfer;
-        private ICollection<PokemonId> _pokemonsNotToCatch;
-
-        public ICollection<KeyValuePair<ItemId, int>> ItemRecycleFilter => new[]
-        {
-            new KeyValuePair<ItemId, int>(ItemId.ItemUnknown, 0),
-            new KeyValuePair<ItemId, int>(ItemId.ItemPokeBall, 20),
-            new KeyValuePair<ItemId, int>(ItemId.ItemGreatBall, 20),
-            new KeyValuePair<ItemId, int>(ItemId.ItemUltraBall, 50),
-            new KeyValuePair<ItemId, int>(ItemId.ItemMasterBall, 100),
-
-            new KeyValuePair<ItemId, int>(ItemId.ItemPotion, 0),
-            new KeyValuePair<ItemId, int>(ItemId.ItemSuperPotion, 0),
-            new KeyValuePair<ItemId, int>(ItemId.ItemHyperPotion, 20),
-            new KeyValuePair<ItemId, int>(ItemId.ItemMaxPotion, 50),
-
-            new KeyValuePair<ItemId, int>(ItemId.ItemRevive, 10),
-            new KeyValuePair<ItemId, int>(ItemId.ItemMaxRevive, 50),
-
-            new KeyValuePair<ItemId, int>(ItemId.ItemLuckyEgg, 200),
-
-            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseOrdinary, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseSpicy, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseCool, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseFloral, 100),
-
-            new KeyValuePair<ItemId, int>(ItemId.ItemTroyDisk, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemXAttack, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemXDefense, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemXMiracle, 100),
-
-            new KeyValuePair<ItemId, int>(ItemId.ItemRazzBerry, 20),
-            new KeyValuePair<ItemId, int>(ItemId.ItemBlukBerry, 10),
-            new KeyValuePair<ItemId, int>(ItemId.ItemNanabBerry, 10),
-            new KeyValuePair<ItemId, int>(ItemId.ItemWeparBerry, 30),
-            new KeyValuePair<ItemId, int>(ItemId.ItemPinapBerry, 30),
-
-            new KeyValuePair<ItemId, int>(ItemId.ItemSpecialCamera, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemIncubatorBasicUnlimited, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemIncubatorBasic, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemPokemonStorageUpgrade, 100),
-            new KeyValuePair<ItemId, int>(ItemId.ItemItemStorageUpgrade, 100),
-        };
-
-        public ICollection<PokemonId> PokemonsToEvolve
-        {
-            get
-            {
-                //Type of pokemons to evolve
-                var defaultText = new string[] { "Zubat", "Pidgey", "Rattata" };
-                _pokemonsToEvolve = _pokemonsToEvolve ?? LoadPokemonList("PokemonsToEvolve", defaultText);
-                return _pokemonsToEvolve;
-            }
-        }
-
-        public ICollection<PokemonId> PokemonsNotToTransfer
-        {
-            get
-            {
-                //Type of pokemons not to transfer
-                var defaultText = new string[] { "Dragonite", "Charizard", "Zapdos", "Snorlax", "Alakazam", "Mew", "Mewtwo" };
-                _pokemonsNotToTransfer = _pokemonsNotToTransfer ?? LoadPokemonList("PokemonsNotToTransfer", defaultText);
-                return _pokemonsNotToTransfer;
-            }
-        }
-
-        public ICollection<PokemonId> PokemonsNotToCatch
-        {
-            get
-            {
-                //Type of pokemons not to catch
-                var defaultText = new string[] { "Zubat", "Pidgey", "Rattata" };
-                _pokemonsNotToCatch = _pokemonsNotToCatch ?? LoadPokemonList("PokemonsNotToCatch", defaultText);
-                return _pokemonsNotToCatch;
-            }
-        }
-
-        private ICollection<PokemonId> LoadPokemonList(string filename, string[] defaultContent)
-        {
-            ICollection<PokemonId> result = new List<PokemonId>();
-            Func<string, ICollection<PokemonId>> addPokemonToResult = delegate (string pokemonName) {
-                PokemonId pokemon;
-                if (Enum.TryParse<PokemonId>(pokemonName, out pokemon))
-                {
-                    result.Add((PokemonId)pokemon);
-                }
-                return result;
-            };
-
-            string path = Directory.GetCurrentDirectory() + "\\Configs\\";
-            if (!Directory.Exists(path))
-            {
-                DirectoryInfo di = Directory.CreateDirectory(path);
-            }
-            if (!File.Exists(path + filename + ".txt"))
-            {
-                Logger.Write($"File: \"\\Configs\\{filename}.txt\" not found, creating new...", LogLevel.Warning);
-                using (var w = File.AppendText(path + filename + ".txt"))
-                {
-                    Array.ForEach(defaultContent, x => w.WriteLine(x));
-                    Array.ForEach(defaultContent, x => addPokemonToResult(x));
-                    w.Close();
-                }
-            }
-            if (File.Exists(path + filename + ".txt"))
-            {
-                Logger.Write($"Loading File: \"\\Configs\\{filename}.txt\"", LogLevel.Info);
-
-                var content = string.Empty;
-                using (StreamReader reader = new StreamReader(path + filename + ".txt"))
-                {
-                    content = reader.ReadToEnd();
-                    reader.Close();
-                }
-                content = Regex.Replace(content, @"\\/\*(.|\n)*?\*\/", ""); //todo: supposed to remove comment blocks
-
-                StringReader tr = new StringReader(content);
-
-                var pokemonName = tr.ReadLine();
-                while (pokemonName != null)
-                {
-                    addPokemonToResult(pokemonName);
-                    pokemonName = tr.ReadLine();
-                }
-            }
-            return result;
-        }
-    }
-}
+#region
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using PokemonGo.RocketAPI.Enums;
+using PokemonGo.RocketAPI.GeneratedCode;
+using PokemonGo.RocketAPI.Logging;
+using System.Text.RegularExpressions;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI.Console
+{
+    public class Settings : ISettings
+    {
+        public AuthType AuthType => (AuthType)Enum.Parse(typeof(AuthType), UserSettings.Default.AuthType, true);
+        public string PtcUsername => UserSettings.Default.PtcUsername;
+        public string PtcPassword => UserSettings.Default.PtcPassword;
+        public double DefaultLatitude => UserSettings.Default.DefaultLatitude;
+        public double DefaultLongitude => UserSettings.Default.DefaultLongitude;
+        public double DefaultAltitude => UserSettings.Default.DefaultAltitude;
+
+        public float KeepMinIVPercentage => UserSettings.Default.KeepMinIVPercentage;
+        public int KeepMinCP => UserSettings.Default.KeepMinCP;
+        public double WalkingSpeedInKilometerPerHour => UserSettings.Default.WalkingSpeedInKilometerPerHour;
+        public bool EvolveAllPokemonWithEnoughCandy => UserSettings.Default.EvolveAllPokemonWithEnoughCandy;
+        public bool TransferDuplicatePokemon => UserSettings.Default.TransferDuplicatePokemon;
+        public bool UsePokemonToNotCatchFilter => UserSettings.Default.UsePokemonToNotCatchFilter;
+        public int KeepMinDuplicatePokemon => UserSettings.Default.KeepMinDuplicatePokemon;
+        public bool PrioritizeIVOverCP => UserSettings.Default.PrioritizeIVOverCP;
+        public int MaxTravelDistanceInMeters => UserSettings.Default.MaxTravelDistanceInMeters;
+
+        public bool UseGPXPathing => UserSettings.Default.UseGPXPathing;
+        public string GPXFile => UserSettings.Default.GPXFile;
+
+        private ICollection<PokemonId> _pokemonsToEvolve;
+        private ICollection<PokemonId> _pokemonsNotToTransfer;
+        private ICollection<PokemonId> _pokemonsNotToCatch;
+
+        public ICollection<KeyValuePair<ItemId, int>> ItemRecycleFilter => new[]
+        {
+            new KeyValuePair<ItemId, int>(ItemId.ItemUnknown, 0),
+            new KeyValuePair<ItemId, int>(ItemId.ItemPokeBall, 20),
+            new KeyValuePair<ItemId, int>(ItemId.ItemGreatBall, 20),
+            new KeyValuePair<ItemId, int>(ItemId.ItemUltraBall, 50),
+            new KeyValuePair<ItemId, int>(ItemId.ItemMasterBall, 100),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemPotion, 0),
+            new KeyValuePair<ItemId, int>(ItemId.ItemSuperPotion, 0),
+            new KeyValuePair<ItemId, int>(ItemId.ItemHyperPotion, 20),
+            new KeyValuePair<ItemId, int>(ItemId.ItemMaxPotion, 50),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemRevive, 10),
+            new KeyValuePair<ItemId, int>(ItemId.ItemMaxRevive, 50),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemLuckyEgg, 200),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseOrdinary, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseSpicy, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseCool, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncenseFloral, 100),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemTroyDisk, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemXAttack, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemXDefense, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemXMiracle, 100),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemRazzBerry, 20),
+            new KeyValuePair<ItemId, int>(ItemId.ItemBlukBerry, 10),
+            new KeyValuePair<ItemId, int>(ItemId.ItemNanabBerry, 10),
+            new KeyValuePair<ItemId, int>(ItemId.ItemWeparBerry, 30),
+            new KeyValuePair<ItemId, int>(ItemId.ItemPinapBerry, 30),
+
+            new KeyValuePair<ItemId, int>(ItemId.ItemSpecialCamera, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncubatorBasicUnlimited, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemIncubatorBasic, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemPokemonStorageUpgrade, 100),
+            new KeyValuePair<ItemId, int>(ItemId.ItemItemStorageUpgrade, 100),
+        };
+
+        public ICollection<PokemonId> PokemonsToEvolve
+        {
+            get
+            {
+                //Type of pokemons to evolve
+                var defaultText = new string[] { "Zubat", "Pidgey", "Rattata" };
+                _pokemonsToEvolve = _pokemonsToEvolve ?? LoadPokemonList("PokemonsToEvolve", defaultText);
+                return _pokemonsToEvolve;
+            }
+        }
+
+        public ICollection<PokemonId> PokemonsNotToTransfer
+        {
+            get
+            {
+                //Type of pokemons not to transfer
+                var defaultText = new string[] { "Dragonite", "Charizard", "Zapdos", "Snorlax", "Alakazam", "Mew", "Mewtwo" };
+                _pokemonsNotToTransfer = _pokemonsNotToTransfer ?? LoadPokemonList("PokemonsNotToTransfer", defaultText);
+                return _pokemonsNotToTransfer;
+            }
+        }
+
+        public ICollection<PokemonId> PokemonsNotToCatch
+        {
+            get
+            {
+                //Type of pokemons not to catch
+                var defaultText = new string[] { "Zubat", "Pidgey", "Rattata" };
+                _pokemonsNotToCatch = _pokemonsNotToCatch ?? LoadPokemonList("PokemonsNotToCatch", defaultText);
+                return _pokemonsNotToCatch;
+            }
+        }
+
+        private ICollection<PokemonId> LoadPokemonList(string filename, string[] defaultContent)
+        {
+            ICollection<PokemonId> result = new List<PokemonId>();
+            Func<string, ICollection<PokemonId>> addPokemonToResult = delegate (string pokemonName) {
+                PokemonId pokemon;
+                if (Enum.TryParse<PokemonId>(pokemonName, out pokemon))
+                {
+                    result.Add((PokemonId)pokemon);
+                }
+                return result;
+            };
+
+            string path = Directory.GetCurrentDirectory() + "\\Configs\\";
+            if (!Directory.Exists(path))
+            {
+                DirectoryInfo di = Directory.CreateDirectory(path);
+            }
+            if (!File.Exists(path + filename + ".txt"))
+            {
+                Logger.Write($"File: \"\\Configs\\{filename}.txt\" not found, creating new...", LogLevel.Warning);
+                using (var w = File.AppendText(path + filename + ".txt"))
+                {
+                    Array.ForEach(defaultContent, x => w.WriteLine(x));
+                    Array.ForEach(defaultContent, x => addPokemonToResult(x));
+                    w.Close();
+                }
+            }
+            if (File.Exists(path + filename + ".txt"))
+            {
+                Logger.Write($"Loading File: \"\\Configs\\{filename}.txt\"", LogLevel.Info);
+
+                var content = string.Empty;
+                using (StreamReader reader = new StreamReader(path + filename + ".txt"))
+                {
+                    content = reader.ReadToEnd();
+                    reader.Close();
+                }
+                content = Regex.Replace(content, @"\\/\*(.|\n)*?\*\/", ""); //todo: supposed to remove comment blocks
+
+                StringReader tr = new StringReader(content);
+
+                var pokemonName = tr.ReadLine();
+                while (pokemonName != null)
+                {
+                    addPokemonToResult(pokemonName);
+                    pokemonName = tr.ReadLine();
+                }
+            }
+            return result;
+        }
+    }
+}
diff --git a/PokemonGo.RocketAPI.Console/UserSettings.Designer.cs b/PokemonGo.RocketAPI.Console/UserSettings.Designer.cs
index 1c5a32e..b20f503 100644
--- a/PokemonGo.RocketAPI.Console/UserSettings.Designer.cs
+++ b/PokemonGo.RocketAPI.Console/UserSettings.Designer.cs
@@ -1,230 +1,230 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     Dieser Code wurde von einem Tool generiert.
-//     Laufzeitversion:4.0.30319.42000
-//
-//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
-//     der Code erneut generiert wird.
-// </auto-generated>
-//------------------------------------------------------------------------------
-
-namespace PokemonGo.RocketAPI.Console {
-
-
-    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
-    internal sealed partial class UserSettings : global::System.Configuration.ApplicationSettingsBase {
-
-        private static UserSettings defaultInstance = ((UserSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new UserSettings())));
-
-        public static UserSettings Default {
-            get {
-                return defaultInstance;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("10")]
-        public double DefaultAltitude {
-            get {
-                return ((double)(this["DefaultAltitude"]));
-            }
-            set {
-                this["DefaultAltitude"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("85")]
-        public float KeepMinIVPercentage {
-            get {
-                return ((float)(this["KeepMinIVPercentage"]));
-            }
-            set {
-                this["KeepMinIVPercentage"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("1000")]
-        public int KeepMinCP {
-            get {
-                return ((int)(this["KeepMinCP"]));
-            }
-            set {
-                this["KeepMinCP"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("250")]
-        public double WalkingSpeedInKilometerPerHour {
-            get {
-                return ((double)(this["WalkingSpeedInKilometerPerHour"]));
-            }
-            set {
-                this["WalkingSpeedInKilometerPerHour"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("0")]
-        public double DefaultLatitude {
-            get {
-                return ((double)(this["DefaultLatitude"]));
-            }
-            set {
-                this["DefaultLatitude"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("0")]
-        public double DefaultLongitude {
-            get {
-                return ((double)(this["DefaultLongitude"]));
-            }
-            set {
-                this["DefaultLongitude"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("False")]
-        public bool EvolveAllPokemonWithEnoughCandy {
-            get {
-                return ((bool)(this["EvolveAllPokemonWithEnoughCandy"]));
-            }
-            set {
-                this["EvolveAllPokemonWithEnoughCandy"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("True")]
-        public bool TransferDuplicatePokemon {
-            get {
-                return ((bool)(this["TransferDuplicatePokemon"]));
-            }
-            set {
-                this["TransferDuplicatePokemon"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("False")]
-        public bool UsePokemonToNotCatchFilter {
-            get {
-                return ((bool)(this["UsePokemonToNotCatchFilter"]));
-            }
-            set {
-                this["UsePokemonToNotCatchFilter"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("2")]
-        public int KeepMinDuplicatePokemon {
-            get {
-                return ((int)(this["KeepMinDuplicatePokemon"]));
-            }
-            set {
-                this["KeepMinDuplicatePokemon"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("Google")]
-        public string AuthType {
-            get {
-                return ((string)(this["AuthType"]));
-            }
-            set {
-                this["AuthType"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("username")]
-        public string PtcUsername {
-            get {
-                return ((string)(this["PtcUsername"]));
-            }
-            set {
-                this["PtcUsername"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("password")]
-        public string PtcPassword {
-            get {
-                return ((string)(this["PtcPassword"]));
-            }
-            set {
-                this["PtcPassword"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("True")]
-        public bool PrioritizeIVOverCP {
-            get {
-                return ((bool)(this["PrioritizeIVOverCP"]));
-            }
-            set {
-                this["PrioritizeIVOverCP"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("1000")]
-        public int MaxTravelDistanceInMeters {
-            get {
-                return ((int)(this["MaxTravelDistanceInMeters"]));
-            }
-            set {
-                this["MaxTravelDistanceInMeters"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("False")]
-        public bool UseGPXPathing {
-            get {
-                return ((bool)(this["UseGPXPathing"]));
-            }
-            set {
-                this["UseGPXPathing"] = value;
-            }
-        }
-
-        [global::System.Configuration.UserScopedSettingAttribute()]
-        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
-        [global::System.Configuration.DefaultSettingValueAttribute("GPXFile.GPX")]
-        public string GPXFile {
-            get {
-                return ((string)(this["GPXFile"]));
-            }
-            set {
-                this["GPXFile"] = value;
-            }
-        }
-    }
-}
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.42000
+//
+//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace PokemonGo.RocketAPI.Console {
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
+    internal sealed partial class UserSettings : global::System.Configuration.ApplicationSettingsBase {
+
+        private static UserSettings defaultInstance = ((UserSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new UserSettings())));
+
+        public static UserSettings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("10")]
+        public double DefaultAltitude {
+            get {
+                return ((double)(this["DefaultAltitude"]));
+            }
+            set {
+                this["DefaultAltitude"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("85")]
+        public float KeepMinIVPercentage {
+            get {
+                return ((float)(this["KeepMinIVPercentage"]));
+            }
+            set {
+                this["KeepMinIVPercentage"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("1000")]
+        public int KeepMinCP {
+            get {
+                return ((int)(this["KeepMinCP"]));
+            }
+            set {
+                this["KeepMinCP"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("250")]
+        public double WalkingSpeedInKilometerPerHour {
+            get {
+                return ((double)(this["WalkingSpeedInKilometerPerHour"]));
+            }
+            set {
+                this["WalkingSpeedInKilometerPerHour"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("0")]
+        public double DefaultLatitude {
+            get {
+                return ((double)(this["DefaultLatitude"]));
+            }
+            set {
+                this["DefaultLatitude"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("0")]
+        public double DefaultLongitude {
+            get {
+                return ((double)(this["DefaultLongitude"]));
+            }
+            set {
+                this["DefaultLongitude"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("False")]
+        public bool EvolveAllPokemonWithEnoughCandy {
+            get {
+                return ((bool)(this["EvolveAllPokemonWithEnoughCandy"]));
+            }
+            set {
+                this["EvolveAllPokemonWithEnoughCandy"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool TransferDuplicatePokemon {
+            get {
+                return ((bool)(this["TransferDuplicatePokemon"]));
+            }
+            set {
+                this["TransferDuplicatePokemon"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("False")]
+        public bool UsePokemonToNotCatchFilter {
+            get {
+                return ((bool)(this["UsePokemonToNotCatchFilter"]));
+            }
+            set {
+                this["UsePokemonToNotCatchFilter"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("2")]
+        public int KeepMinDuplicatePokemon {
+            get {
+                return ((int)(this["KeepMinDuplicatePokemon"]));
+            }
+            set {
+                this["KeepMinDuplicatePokemon"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("Google")]
+        public string AuthType {
+            get {
+                return ((string)(this["AuthType"]));
+            }
+            set {
+                this["AuthType"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("username")]
+        public string PtcUsername {
+            get {
+                return ((string)(this["PtcUsername"]));
+            }
+            set {
+                this["PtcUsername"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("password")]
+        public string PtcPassword {
+            get {
+                return ((string)(this["PtcPassword"]));
+            }
+            set {
+                this["PtcPassword"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("True")]
+        public bool PrioritizeIVOverCP {
+            get {
+                return ((bool)(this["PrioritizeIVOverCP"]));
+            }
+            set {
+                this["PrioritizeIVOverCP"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("1000")]
+        public int MaxTravelDistanceInMeters {
+            get {
+                return ((int)(this["MaxTravelDistanceInMeters"]));
+            }
+            set {
+                this["MaxTravelDistanceInMeters"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("False")]
+        public bool UseGPXPathing {
+            get {
+                return ((bool)(this["UseGPXPathing"]));
+            }
+            set {
+                this["UseGPXPathing"] = value;
+            }
+        }
+
+        [global::System.Configuration.UserScopedSettingAttribute()]
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [global::System.Configuration.DefaultSettingValueAttribute("GPXFile.GPX")]
+        public string GPXFile {
+            get {
+                return ((string)(this["GPXFile"]));
+            }
+            set {
+                this["GPXFile"] = value;
+            }
+        }
+    }
+}
diff --git a/PokemonGo.RocketAPI.Console/UserSettings.cs b/PokemonGo.RocketAPI.Console/UserSettings.cs
index 6553b03..1d72304 100644
--- a/PokemonGo.RocketAPI.Console/UserSettings.cs
+++ b/PokemonGo.RocketAPI.Console/UserSettings.cs
@@ -1,28 +1,28 @@
-#region
-
-using System.ComponentModel;
-using System.Configuration;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Console
-{
-    // This class allows you to handle specific events on the settings class:
-    //  The SettingChanging event is raised before a setting's value is changed.
-    //  The PropertyChanged event is raised after a setting's value is changed.
-    //  The SettingsLoaded event is raised after the setting values are loaded.
-    //  The SettingsSaving event is raised before the setting values are saved.
-    internal sealed partial class UserSettings
-    {
-        private void SettingChangingEventHandler(object sender, SettingChangingEventArgs e)
-        {
-            // Add code to handle the SettingChangingEvent event here.
-        }
-
-        private void SettingsSavingEventHandler(object sender, CancelEventArgs e)
-        {
-            // Add code to handle the SettingsSaving event here.
-        }
-    }
+#region
+
+using System.ComponentModel;
+using System.Configuration;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI.Console
+{
+    // This class allows you to handle specific events on the settings class:
+    //  The SettingChanging event is raised before a setting's value is changed.
+    //  The PropertyChanged event is raised after a setting's value is changed.
+    //  The SettingsLoaded event is raised after the setting values are loaded.
+    //  The SettingsSaving event is raised before the setting values are saved.
+    internal sealed partial class UserSettings
+    {
+        private void SettingChangingEventHandler(object sender, SettingChangingEventArgs e)
+        {
+            // Add code to handle the SettingChangingEvent event here.
+        }
+
+        private void SettingsSavingEventHandler(object sender, CancelEventArgs e)
+        {
+            // Add code to handle the SettingsSaving event here.
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Console/UserSettings.settings b/PokemonGo.RocketAPI.Console/UserSettings.settings
index 5c0b59b..7ce5045 100644
--- a/PokemonGo.RocketAPI.Console/UserSettings.settings
+++ b/PokemonGo.RocketAPI.Console/UserSettings.settings
@@ -1,57 +1,57 @@
-<?xml version='1.0' encoding='utf-8'?>
-<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="PokemonGo.RocketAPI.Console" GeneratedClassName="UserSettings">
-  <Profiles />
-  <Settings>
-    <Setting Name="DefaultAltitude" Type="System.Double" Scope="User">
-      <Value Profile="(Default)">10</Value>
-    </Setting>
-    <Setting Name="KeepMinIVPercentage" Type="System.Single" Scope="User">
-      <Value Profile="(Default)">85</Value>
-    </Setting>
-    <Setting Name="KeepMinCP" Type="System.Int32" Scope="User">
-      <Value Profile="(Default)">1000</Value>
-    </Setting>
-    <Setting Name="WalkingSpeedInKilometerPerHour" Type="System.Double" Scope="User">
-      <Value Profile="(Default)">250</Value>
-    </Setting>
-    <Setting Name="DefaultLatitude" Type="System.Double" Scope="User">
-      <Value Profile="(Default)">0</Value>
-    </Setting>
-    <Setting Name="DefaultLongitude" Type="System.Double" Scope="User">
-      <Value Profile="(Default)">0</Value>
-    </Setting>
-    <Setting Name="EvolveAllPokemonWithEnoughCandy" Type="System.Boolean" Scope="User">
-      <Value Profile="(Default)">False</Value>
-    </Setting>
-    <Setting Name="TransferDuplicatePokemon" Type="System.Boolean" Scope="User">
-      <Value Profile="(Default)">True</Value>
-    </Setting>
-    <Setting Name="UsePokemonToNotCatchFilter" Type="System.Boolean" Scope="User">
-      <Value Profile="(Default)">False</Value>
-    </Setting>
-    <Setting Name="KeepMinDuplicatePokemon" Type="System.Int32" Scope="User">
-      <Value Profile="(Default)">2</Value>
-    </Setting>
-    <Setting Name="AuthType" Type="System.String" Scope="User">
-      <Value Profile="(Default)">Google</Value>
-    </Setting>
-    <Setting Name="PtcUsername" Type="System.String" Scope="User">
-      <Value Profile="(Default)">username</Value>
-    </Setting>
-    <Setting Name="PtcPassword" Type="System.String" Scope="User">
-      <Value Profile="(Default)">password</Value>
-    </Setting>
-    <Setting Name="PrioritizeIVOverCP" Type="System.Boolean" Scope="User">
-      <Value Profile="(Default)">True</Value>
-    </Setting>
-    <Setting Name="MaxTravelDistanceInMeters" Type="System.Int32" Scope="User">
-      <Value Profile="(Default)">1000</Value>
-    </Setting>
-    <Setting Name="UseGPXPathing" Type="System.Boolean" Scope="User">
-      <Value Profile="(Default)">False</Value>
-    </Setting>
-    <Setting Name="GPXFile" Type="System.String" Scope="User">
-      <Value Profile="(Default)">GPXFile.GPX</Value>
-    </Setting>
-  </Settings>
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="PokemonGo.RocketAPI.Console" GeneratedClassName="UserSettings">
+  <Profiles />
+  <Settings>
+    <Setting Name="DefaultAltitude" Type="System.Double" Scope="User">
+      <Value Profile="(Default)">10</Value>
+    </Setting>
+    <Setting Name="KeepMinIVPercentage" Type="System.Single" Scope="User">
+      <Value Profile="(Default)">85</Value>
+    </Setting>
+    <Setting Name="KeepMinCP" Type="System.Int32" Scope="User">
+      <Value Profile="(Default)">1000</Value>
+    </Setting>
+    <Setting Name="WalkingSpeedInKilometerPerHour" Type="System.Double" Scope="User">
+      <Value Profile="(Default)">250</Value>
+    </Setting>
+    <Setting Name="DefaultLatitude" Type="System.Double" Scope="User">
+      <Value Profile="(Default)">0</Value>
+    </Setting>
+    <Setting Name="DefaultLongitude" Type="System.Double" Scope="User">
+      <Value Profile="(Default)">0</Value>
+    </Setting>
+    <Setting Name="EvolveAllPokemonWithEnoughCandy" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">False</Value>
+    </Setting>
+    <Setting Name="TransferDuplicatePokemon" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="UsePokemonToNotCatchFilter" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">False</Value>
+    </Setting>
+    <Setting Name="KeepMinDuplicatePokemon" Type="System.Int32" Scope="User">
+      <Value Profile="(Default)">2</Value>
+    </Setting>
+    <Setting Name="AuthType" Type="System.String" Scope="User">
+      <Value Profile="(Default)">Google</Value>
+    </Setting>
+    <Setting Name="PtcUsername" Type="System.String" Scope="User">
+      <Value Profile="(Default)">username</Value>
+    </Setting>
+    <Setting Name="PtcPassword" Type="System.String" Scope="User">
+      <Value Profile="(Default)">password</Value>
+    </Setting>
+    <Setting Name="PrioritizeIVOverCP" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">True</Value>
+    </Setting>
+    <Setting Name="MaxTravelDistanceInMeters" Type="System.Int32" Scope="User">
+      <Value Profile="(Default)">1000</Value>
+    </Setting>
+    <Setting Name="UseGPXPathing" Type="System.Boolean" Scope="User">
+      <Value Profile="(Default)">False</Value>
+    </Setting>
+    <Setting Name="GPXFile" Type="System.String" Scope="User">
+      <Value Profile="(Default)">GPXFile.GPX</Value>
+    </Setting>
+  </Settings>
 </SettingsFile>
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Logic/Inventory.cs b/PokemonGo.RocketAPI.Logic/Inventory.cs
index 7574a33..069b8da 100644
--- a/PokemonGo.RocketAPI.Logic/Inventory.cs
+++ b/PokemonGo.RocketAPI.Logic/Inventory.cs
@@ -1,251 +1,251 @@
-#region
-
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using PokemonGo.RocketAPI.Enums;
-using PokemonGo.RocketAPI.GeneratedCode;
-using System.Collections.Concurrent;
-using System;
-using System.Threading;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Logic
-{
-    public class Inventory
-    {
-        private readonly Client _client;
-        public static DateTime _lastRefresh;
-        public static GetInventoryResponse _cachedInventory;
-
-        public Inventory(Client client)
-        {
-            _client = client;
-        }
-
-        public async Task<IEnumerable<PokemonData>> GetDuplicatePokemonToTransfer(bool keepPokemonsThatCanEvolve = false, bool prioritizeIVoverCP = false, IEnumerable<PokemonId> filter = null)
-        {
-            var myPokemon = await GetPokemons();
-
-            var pokemonList = myPokemon.Where(p => p.DeployedFortId == 0 && p.Favorite == 0 && p.Cp < _client.Settings.KeepMinCP).ToList();
-            if (filter != null)
-                pokemonList = pokemonList.Where(p => !filter.Contains(p.PokemonId)).ToList();
-
-            if (keepPokemonsThatCanEvolve)
-            {
-                var results = new List<PokemonData>();
-                var pokemonsThatCanBeTransfered = pokemonList.GroupBy(p => p.PokemonId)
-                    .Where(x => x.Count() > 2).ToList();
-
-                var myPokemonSettings = await GetPokemonSettings();
-                var pokemonSettings = myPokemonSettings.ToList();
-
-                var myPokemonFamilies = await GetPokemonFamilies();
-                var pokemonFamilies = myPokemonFamilies.ToArray();
-
-                foreach (var pokemon in pokemonsThatCanBeTransfered)
-                {
-                    var settings = pokemonSettings.Single(x => x.PokemonId == pokemon.Key);
-                    var familyCandy = pokemonFamilies.Single(x => settings.FamilyId == x.FamilyId);
-                    if (settings.CandyToEvolve == 0)
-                        continue;
-
-                    var amountToSkip = familyCandy.Candy / settings.CandyToEvolve;
-                    if (prioritizeIVoverCP)
-                    {
-                        results.AddRange(pokemonList.Where(x => x.PokemonId == pokemon.Key)
-                            .OrderByDescending(x => PokemonInfo.CalculatePokemonPerfection(x))
-                            .ThenBy(n => n.StaminaMax)
-                            .Skip(amountToSkip)
-                            .ToList());
-                    }
-                    else
-                    {
-                        results.AddRange(pokemonList.Where(x => x.PokemonId == pokemon.Key)
-                            .OrderByDescending(x => x.Cp)
-                            .ThenBy(n => n.StaminaMax)
-                            .Skip(amountToSkip)
-                            .ToList());
-                    }
-                }
-
-                return results;
-            }
-            if (prioritizeIVoverCP)
-            {
-                return pokemonList
-                .GroupBy(p => p.PokemonId)
-                .Where(x => x.Count() > 1)
-                .SelectMany(
-                    p =>
-                        p.OrderByDescending(x => PokemonInfo.CalculatePokemonPerfection(x))
-                            .ThenBy(n => n.StaminaMax)
-                            .Skip(_client.Settings.KeepMinDuplicatePokemon)
-                            .ToList());
-            }
-            else
-            {
-                return pokemonList
-                .GroupBy(p => p.PokemonId)
-                .Where(x => x.Count() > 1)
-                .SelectMany(
-                    p =>
-                        p.OrderByDescending(x => x.Cp)
-                            .ThenBy(n => n.StaminaMax)
-                            .Skip(_client.Settings.KeepMinDuplicatePokemon)
-                            .ToList());
-            }
-        }
-
-        public async Task<IEnumerable<PokemonData>> GetHighestsCP(int limit)
-        {
-            var myPokemon = await GetPokemons();
-            var pokemons = myPokemon.ToList();
-            return pokemons.OrderByDescending(x => x.Cp).ThenBy(n => n.StaminaMax).Take(limit);
-        }
-
-        public async Task<IEnumerable<PokemonData>> GetHighestsPerfect(int limit)
-        {
-            var myPokemon = await GetPokemons();
-            var pokemons = myPokemon.ToList();
-            return pokemons.OrderByDescending(PokemonInfo.CalculatePokemonPerfection).Take(limit);
-        }
-
-        public async Task<PokemonData> GetHighestPokemonOfTypeByCP(PokemonData pokemon)
-        {
-            var myPokemon = await GetPokemons();
-            var pokemons = myPokemon.ToList();
-            return pokemons.Where(x => x.PokemonId == pokemon.PokemonId)
-                .OrderByDescending(x => x.Cp)
-                .FirstOrDefault();
-        }
-
-        public async Task<int> GetItemAmountByType(MiscEnums.Item type)
-        {
-            var pokeballs = await GetItems();
-            return pokeballs.FirstOrDefault(i => (MiscEnums.Item)i.Item_ == type)?.Count ?? 0;
-        }
-
-        public async Task<IEnumerable<Item>> GetItems()
-        {
-            var inventory = await getCachedInventory(_client);
-            return inventory.InventoryDelta.InventoryItems
-                .Select(i => i.InventoryItemData?.Item)
-                .Where(p => p != null);
-        }
-
-        public async Task<IEnumerable<Item>> GetItemsToRecycle(ISettings settings)
-        {
-            var myItems = await GetItems();
-
-            return myItems
-                .Where(x => settings.ItemRecycleFilter.Any(f => f.Key == (ItemId)x.Item_ && x.Count > f.Value))
-                .Select(
-                    x =>
-                        new Item
-                        {
-                            Item_ = x.Item_,
-                            Count = x.Count - settings.ItemRecycleFilter.Single(f => f.Key == (ItemId)x.Item_).Value,
-                            Unseen = x.Unseen
-                        });
-        }
-
-        public async Task<IEnumerable<PlayerStats>> GetPlayerStats()
-        {
-            var inventory = await getCachedInventory(_client);
-            return inventory.InventoryDelta.InventoryItems
-                .Select(i => i.InventoryItemData?.PlayerStats)
-                .Where(p => p != null);
-        }
-
-        public async Task<IEnumerable<PokemonFamily>> GetPokemonFamilies()
-        {
-            var inventory = await getCachedInventory(_client);
-            return
-                inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.PokemonFamily)
-                    .Where(p => p != null && p.FamilyId != PokemonFamilyId.FamilyUnset);
-        }
-
-        public async Task<IEnumerable<PokemonData>> GetPokemons()
-        {
-            var inventory = await getCachedInventory(_client);
-            return
-                inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.Pokemon)
-                    .Where(p => p != null && p.PokemonId > 0);
-        }
-
-        public async Task<IEnumerable<PokemonSettings>> GetPokemonSettings()
-        {
-            var templates = await _client.GetItemTemplates();
-            return
-                templates.ItemTemplates.Select(i => i.PokemonSettings)
-                    .Where(p => p != null && p.FamilyId != PokemonFamilyId.FamilyUnset);
-        }
-
-
-        public async Task<IEnumerable<PokemonData>> GetPokemonToEvolve(IEnumerable<PokemonId> filter = null)
-        {
-            var myPokemons = await GetPokemons();
-            myPokemons = myPokemons.Where(p => p.DeployedFortId == 0).OrderBy(p => p.Cp); //Don't evolve pokemon in gyms
-            if (filter != null)
-            {
-                myPokemons = myPokemons.Where(p => filter.Contains(p.PokemonId));
-            }
-            var pokemons = myPokemons.ToList();
-
-            var myPokemonSettings = await GetPokemonSettings();
-            var pokemonSettings = myPokemonSettings.ToList();
-
-            var myPokemonFamilies = await GetPokemonFamilies();
-            var pokemonFamilies = myPokemonFamilies.ToArray();
-
-            var pokemonToEvolve = new List<PokemonData>();
-            foreach (var pokemon in pokemons)
-            {
-                var settings = pokemonSettings.Single(x => x.PokemonId == pokemon.PokemonId);
-                var familyCandy = pokemonFamilies.Single(x => settings.FamilyId == x.FamilyId);
-
-                //Don't evolve if we can't evolve it
-                if (settings.EvolutionIds.Count == 0)
-                    continue;
-
-                var pokemonCandyNeededAlready =
-                    pokemonToEvolve.Count(
-                        p => pokemonSettings.Single(x => x.PokemonId == p.PokemonId).FamilyId == settings.FamilyId) *
-                    settings.CandyToEvolve;
-                if (familyCandy.Candy - pokemonCandyNeededAlready > settings.CandyToEvolve)
-                    pokemonToEvolve.Add(pokemon);
-            }
-
-            return pokemonToEvolve;
-        }
-
-        public static async Task<GetInventoryResponse> getCachedInventory(Client _client, bool request = false)
-        {
-            var now = DateTime.UtcNow;
-            SemaphoreSlim ss = new SemaphoreSlim(10);
-
-            if (_lastRefresh != null && _lastRefresh.AddSeconds(30).Ticks > now.Ticks && request == false)
-            {
-                return _cachedInventory;
-            }
-            else
-            {
-                await ss.WaitAsync();
-                try
-                {
-                    _lastRefresh = now;
-                    _cachedInventory = await _client.GetInventory();
-                    return _cachedInventory;
-                }
-                finally
-                {
-                    ss.Release();
-                }
-            }
-        }
-
-    }
-}
+#region
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using PokemonGo.RocketAPI.Enums;
+using PokemonGo.RocketAPI.GeneratedCode;
+using System.Collections.Concurrent;
+using System;
+using System.Threading;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI.Logic
+{
+    public class Inventory
+    {
+        private readonly Client _client;
+        public static DateTime _lastRefresh;
+        public static GetInventoryResponse _cachedInventory;
+
+        public Inventory(Client client)
+        {
+            _client = client;
+        }
+
+        public async Task<IEnumerable<PokemonData>> GetDuplicatePokemonToTransfer(bool keepPokemonsThatCanEvolve = false, bool prioritizeIVoverCP = false, IEnumerable<PokemonId> filter = null)
+        {
+            var myPokemon = await GetPokemons();
+
+            var pokemonList = myPokemon.Where(p => p.DeployedFortId == 0 && p.Favorite == 0 && p.Cp < _client.Settings.KeepMinCP).ToList();
+            if (filter != null)
+                pokemonList = pokemonList.Where(p => !filter.Contains(p.PokemonId)).ToList();
+
+            if (keepPokemonsThatCanEvolve)
+            {
+                var results = new List<PokemonData>();
+                var pokemonsThatCanBeTransfered = pokemonList.GroupBy(p => p.PokemonId)
+                    .Where(x => x.Count() > 2).ToList();
+
+                var myPokemonSettings = await GetPokemonSettings();
+                var pokemonSettings = myPokemonSettings.ToList();
+
+                var myPokemonFamilies = await GetPokemonFamilies();
+                var pokemonFamilies = myPokemonFamilies.ToArray();
+
+                foreach (var pokemon in pokemonsThatCanBeTransfered)
+                {
+                    var settings = pokemonSettings.Single(x => x.PokemonId == pokemon.Key);
+                    var familyCandy = pokemonFamilies.Single(x => settings.FamilyId == x.FamilyId);
+                    if (settings.CandyToEvolve == 0)
+                        continue;
+
+                    var amountToSkip = familyCandy.Candy / settings.CandyToEvolve;
+                    if (prioritizeIVoverCP)
+                    {
+                        results.AddRange(pokemonList.Where(x => x.PokemonId == pokemon.Key)
+                            .OrderByDescending(x => PokemonInfo.CalculatePokemonPerfection(x))
+                            .ThenBy(n => n.StaminaMax)
+                            .Skip(amountToSkip)
+                            .ToList());
+                    }
+                    else
+                    {
+                        results.AddRange(pokemonList.Where(x => x.PokemonId == pokemon.Key)
+                            .OrderByDescending(x => x.Cp)
+                            .ThenBy(n => n.StaminaMax)
+                            .Skip(amountToSkip)
+                            .ToList());
+                    }
+                }
+
+                return results;
+            }
+            if (prioritizeIVoverCP)
+            {
+                return pokemonList
+                .GroupBy(p => p.PokemonId)
+                .Where(x => x.Count() > 1)
+                .SelectMany(
+                    p =>
+                        p.OrderByDescending(x => PokemonInfo.CalculatePokemonPerfection(x))
+                            .ThenBy(n => n.StaminaMax)
+                            .Skip(_client.Settings.KeepMinDuplicatePokemon)
+                            .ToList());
+            }
+            else
+            {
+                return pokemonList
+                .GroupBy(p => p.PokemonId)
+                .Where(x => x.Count() > 1)
+                .SelectMany(
+                    p =>
+                        p.OrderByDescending(x => x.Cp)
+                            .ThenBy(n => n.StaminaMax)
+                            .Skip(_client.Settings.KeepMinDuplicatePokemon)
+                            .ToList());
+            }
+        }
+
+        public async Task<IEnumerable<PokemonData>> GetHighestsCP(int limit)
+        {
+            var myPokemon = await GetPokemons();
+            var pokemons = myPokemon.ToList();
+            return pokemons.OrderByDescending(x => x.Cp).ThenBy(n => n.StaminaMax).Take(limit);
+        }
+
+        public async Task<IEnumerable<PokemonData>> GetHighestsPerfect(int limit)
+        {
+            var myPokemon = await GetPokemons();
+            var pokemons = myPokemon.ToList();
+            return pokemons.OrderByDescending(PokemonInfo.CalculatePokemonPerfection).Take(limit);
+        }
+
+        public async Task<PokemonData> GetHighestPokemonOfTypeByCP(PokemonData pokemon)
+        {
+            var myPokemon = await GetPokemons();
+            var pokemons = myPokemon.ToList();
+            return pokemons.Where(x => x.PokemonId == pokemon.PokemonId)
+                .OrderByDescending(x => x.Cp)
+                .FirstOrDefault();
+        }
+
+        public async Task<int> GetItemAmountByType(MiscEnums.Item type)
+        {
+            var pokeballs = await GetItems();
+            return pokeballs.FirstOrDefault(i => (MiscEnums.Item)i.Item_ == type)?.Count ?? 0;
+        }
+
+        public async Task<IEnumerable<Item>> GetItems()
+        {
+            var inventory = await getCachedInventory(_client);
+            return inventory.InventoryDelta.InventoryItems
+                .Select(i => i.InventoryItemData?.Item)
+                .Where(p => p != null);
+        }
+
+        public async Task<IEnumerable<Item>> GetItemsToRecycle(ISettings settings)
+        {
+            var myItems = await GetItems();
+
+            return myItems
+                .Where(x => settings.ItemRecycleFilter.Any(f => f.Key == (ItemId)x.Item_ && x.Count > f.Value))
+                .Select(
+                    x =>
+                        new Item
+                        {
+                            Item_ = x.Item_,
+                            Count = x.Count - settings.ItemRecycleFilter.Single(f => f.Key == (ItemId)x.Item_).Value,
+                            Unseen = x.Unseen
+                        });
+        }
+
+        public async Task<IEnumerable<PlayerStats>> GetPlayerStats()
+        {
+            var inventory = await getCachedInventory(_client);
+            return inventory.InventoryDelta.InventoryItems
+                .Select(i => i.InventoryItemData?.PlayerStats)
+                .Where(p => p != null);
+        }
+
+        public async Task<IEnumerable<PokemonFamily>> GetPokemonFamilies()
+        {
+            var inventory = await getCachedInventory(_client);
+            return
+                inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.PokemonFamily)
+                    .Where(p => p != null && p.FamilyId != PokemonFamilyId.FamilyUnset);
+        }
+
+        public async Task<IEnumerable<PokemonData>> GetPokemons()
+        {
+            var inventory = await getCachedInventory(_client);
+            return
+                inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.Pokemon)
+                    .Where(p => p != null && p.PokemonId > 0);
+        }
+
+        public async Task<IEnumerable<PokemonSettings>> GetPokemonSettings()
+        {
+            var templates = await _client.GetItemTemplates();
+            return
+                templates.ItemTemplates.Select(i => i.PokemonSettings)
+                    .Where(p => p != null && p.FamilyId != PokemonFamilyId.FamilyUnset);
+        }
+
+
+        public async Task<IEnumerable<PokemonData>> GetPokemonToEvolve(IEnumerable<PokemonId> filter = null)
+        {
+            var myPokemons = await GetPokemons();
+            myPokemons = myPokemons.Where(p => p.DeployedFortId == 0).OrderBy(p => p.Cp); //Don't evolve pokemon in gyms
+            if (filter != null)
+            {
+                myPokemons = myPokemons.Where(p => filter.Contains(p.PokemonId));
+            }
+            var pokemons = myPokemons.ToList();
+
+            var myPokemonSettings = await GetPokemonSettings();
+            var pokemonSettings = myPokemonSettings.ToList();
+
+            var myPokemonFamilies = await GetPokemonFamilies();
+            var pokemonFamilies = myPokemonFamilies.ToArray();
+
+            var pokemonToEvolve = new List<PokemonData>();
+            foreach (var pokemon in pokemons)
+            {
+                var settings = pokemonSettings.Single(x => x.PokemonId == pokemon.PokemonId);
+                var familyCandy = pokemonFamilies.Single(x => settings.FamilyId == x.FamilyId);
+
+                //Don't evolve if we can't evolve it
+                if (settings.EvolutionIds.Count == 0)
+                    continue;
+
+                var pokemonCandyNeededAlready =
+                    pokemonToEvolve.Count(
+                        p => pokemonSettings.Single(x => x.PokemonId == p.PokemonId).FamilyId == settings.FamilyId) *
+                    settings.CandyToEvolve;
+                if (familyCandy.Candy - pokemonCandyNeededAlready > settings.CandyToEvolve)
+                    pokemonToEvolve.Add(pokemon);
+            }
+
+            return pokemonToEvolve;
+        }
+
+        public static async Task<GetInventoryResponse> getCachedInventory(Client _client, bool request = false)
+        {
+            var now = DateTime.UtcNow;
+            SemaphoreSlim ss = new SemaphoreSlim(10);
+
+            if (_lastRefresh != null && _lastRefresh.AddSeconds(30).Ticks > now.Ticks && request == false)
+            {
+                return _cachedInventory;
+            }
+            else
+            {
+                await ss.WaitAsync();
+                try
+                {
+                    _lastRefresh = now;
+                    _cachedInventory = await _client.GetInventory();
+                    return _cachedInventory;
+                }
+                finally
+                {
+                    ss.Release();
+                }
+            }
+        }
+
+    }
+}
diff --git a/PokemonGo.RocketAPI.Logic/Logic.cs b/PokemonGo.RocketAPI.Logic/Logic.cs
index baf544c..14bc0f2 100644
--- a/PokemonGo.RocketAPI.Logic/Logic.cs
+++ b/PokemonGo.RocketAPI.Logic/Logic.cs
@@ -1,643 +1,643 @@
-#region
-
-using System;
-using System.Collections.Generic;
-using System.Device.Location;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using PokemonGo.RocketAPI.Enums;
-using PokemonGo.RocketAPI.Exceptions;
-using PokemonGo.RocketAPI.Extensions;
-using PokemonGo.RocketAPI.GeneratedCode;
-using PokemonGo.RocketAPI.Logic.Utils;
-using PokemonGo.RocketAPI.Helpers;
-using System.IO;
-using System.Text;
-using PokemonGo.RocketAPI.Logging;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Logic
-{
-    public class Logic
-    {
-        private readonly Client _client;
-        private readonly ISettings _clientSettings;
-        private readonly Inventory _inventory;
-        private readonly Statistics _stats;
-        private readonly Navigation _navigation;
-        private GetPlayerResponse _playerProfile;
-
-        private int recycleCounter = 0;
-
-        public Logic(ISettings clientSettings)
-        {
-            _clientSettings = clientSettings;
-            _client = new Client(_clientSettings);
-            _inventory = new Inventory(_client);
-            _stats = new Statistics();
-            _navigation = new Navigation(_client);
-        }
-
-        public async Task Execute()
-        {
-            Git.CheckVersion();
-
-            if (_clientSettings.DefaultLatitude == 0 || _clientSettings.DefaultLongitude == 0)
-            {
-                Logger.Write($"Please change first Latitude and/or Longitude because currently your using default values!", LogLevel.Error);
-                Logger.Write($"Window will be auto closed in 15 seconds!", LogLevel.Error);
-                await Task.Delay(15000);
-                System.Environment.Exit(1);
-            } else
-            {
-                Logger.Write($"Make sure Lat & Lng is right. Exit Program if not! Lat: {_client.CurrentLat} Lng: {_client.CurrentLng}", LogLevel.Warning);
-                for (int i = 3; i > 0; i--)
-                {
-                    Logger.Write($"Script will continue in {i * 5} seconds!", LogLevel.Warning);
-                    await Task.Delay(5000);
-                }
-            }
-
-            Logger.Write($"Logging in via: {_clientSettings.AuthType}", LogLevel.Info);
-            while (true)
-            {
-                try
-                {
-                    switch (_clientSettings.AuthType)
-                    {
-                        case AuthType.Ptc:
-                            await _client.DoPtcLogin(_clientSettings.PtcUsername, _clientSettings.PtcPassword);
-                            break;
-                        case AuthType.Google:
-                            await _client.DoGoogleLogin("GoogleAuth.ini");
-                            break;
-                        default:
-                            Logger.Write("wrong AuthType");
-                            Environment.Exit(0);
-                            break;
-                    }
-
-                    await _client.SetServer();
-
-                    await PostLoginExecute();
-                }
-                catch (Exception e)
-                {
-                    Logger.Write(e.Message + " from " + e.Source);
-                    Logger.Write("Got an exception, trying automatic restart..", LogLevel.Error);
-                    await Execute();
-                }
-                await Task.Delay(10000);
-            }
-        }
-
-        public async Task PostLoginExecute()
-        {
-            Logger.Write($"Client logged in", LogLevel.Info);
-
-            while (true)
-            {
-                await Inventory.getCachedInventory(_client);
-                _playerProfile = await _client.GetProfile();
-                var PlayerName = Statistics.GetUsername(_client, _playerProfile);
-                _stats.UpdateConsoleTitle(_inventory);
-                var _currentLevelInfos = await Statistics._getcurrentLevelInfos(_inventory);
-
-                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
-                if (_clientSettings.AuthType == AuthType.Ptc)
-                    Logger.Write($"PTC Account: {PlayerName}\n", LogLevel.None, ConsoleColor.Cyan);
-                Logger.Write($"Latitude: {_clientSettings.DefaultLatitude}", LogLevel.None, ConsoleColor.DarkGray);
-                Logger.Write($"Longitude: {_clientSettings.DefaultLongitude}", LogLevel.None, ConsoleColor.DarkGray);
-                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
-                Logger.Write("Your Account:\n");
-                Logger.Write($"Name: {PlayerName}", LogLevel.None, ConsoleColor.DarkGray);
-                Logger.Write($"Team: {_playerProfile.Profile.Team}", LogLevel.None, ConsoleColor.DarkGray);
-                Logger.Write($"Level: {_currentLevelInfos}", LogLevel.None, ConsoleColor.DarkGray);
-                Logger.Write($"Stardust: {_playerProfile.Profile.Currency.ToArray()[1].Amount}", LogLevel.None, ConsoleColor.DarkGray);
-                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
-                await DisplayHighests();
-                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
-
-                var PokemonsNotToTransfer = _clientSettings.PokemonsNotToTransfer;
-                var PokemonsNotToCatch = _clientSettings.PokemonsNotToCatch;
-                var PokemonsToEvolve = _clientSettings.PokemonsToEvolve;
-
-                if (_clientSettings.EvolveAllPokemonWithEnoughCandy) await EvolveAllPokemonWithEnoughCandy(_clientSettings.PokemonsToEvolve);
-                if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();
-                await PokemonToCSV();
-                await RecycleItems();
-                await ExecuteFarmingPokestopsAndPokemons(_clientSettings.UseGPXPathing);
-
-                /*
-            * Example calls below
-            *
-            var profile = await _client.GetProfile();
-            var settings = await _client.GetSettings();
-            var mapObjects = await _client.GetMapObjects();
-            var inventory = await _client.GetInventory();
-            var pokemons = inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.Pokemon).Where(p => p != null && p?.PokemonId > 0);
-            */
-
-                await Task.Delay(10000);
-            }
-        }
-
-        private async Task ExecuteFarmingPokestopsAndPokemons(bool path = false)
-        {
-            if (!path)
-                await ExecuteFarmingPokestopsAndPokemons();
-            else
-            {
-                //bool onTrack = true;
-                List<GPXReader.trk> Tracks = GetGPXTracks(_clientSettings.GPXFile);
-                int curTrkPt = 0;
-                int maxTrkPt = 0;
-                int curTrk = 0;
-                int maxTrk = Tracks.Count - 1;
-                int curTrkSeg = 0;
-                int maxTrkSeg = 0;
-                while (curTrk <= maxTrk)
-                {
-                    var Track = Tracks.ElementAt(curTrk);
-                    var trackSegments = Track.Segments;
-                    maxTrkSeg = trackSegments.Count - 1;
-                    while (curTrkSeg <= maxTrkSeg)
-                    {
-                        List<GPXReader.trkpt> TrackPoints = Track.Segments.ElementAt(0).TrackPoints;
-                        maxTrkPt = TrackPoints.Count - 1;
-                        var mapObjects = await _client.GetMapObjects();
-                        while (curTrkPt <= maxTrkPt)
-                        {
-                            GPXReader.trkpt nextPoint = TrackPoints.ElementAt(curTrkPt);
-                            if (LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, Convert.ToDouble(nextPoint.Lat), Convert.ToDouble(nextPoint.Lon)) > 5000)
-                            {
-                                Logger.Write($"Your desired destination of {nextPoint.Lat}, {nextPoint.Lon} is too far from your current position of {_client.CurrentLat}, {_client.CurrentLng}", LogLevel.Error);
-                                break;
-                            }
-
-                            Logger.Write($"Your desired destination is {nextPoint.Lat}, your location is {nextPoint.Lon} {_client.CurrentLat}, {_client.CurrentLng}", LogLevel.Warning);
-
-                            // Wasn't sure how to make this pretty. Edit as needed.
-                            var pokeStops =
-                                mapObjects.MapCells.SelectMany(i => i.Forts)
-                                    .Where(
-                                        i =>
-                                            i.Type == FortType.Checkpoint &&
-                                            i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime() &&
-                                            ( // Make sure PokeStop is within 40 meters, otherwise we cannot hit them.
-                                            LocationUtils.CalculateDistanceInMeters(
-                                                _client.CurrentLat, _client.CurrentLng,
-                                                    i.Latitude, i.Longitude) < 40)
-                                            );
-
-                            var pokestopList = pokeStops.ToList();
-
-                            while (pokestopList.Any())
-                            {
-                                pokestopList = pokestopList.OrderBy(i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude)).ToList();
-                                var pokeStop = pokestopList[0];
-                                pokestopList.RemoveAt(0);
-
-                                var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
-
-                                var fortSearch = await _client.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
-                                if (fortSearch.ExperienceAwarded > 0)
-                                {
-                                    _stats.AddExperience(fortSearch.ExperienceAwarded);
-                                    _stats.UpdateConsoleTitle(_inventory);
-                                    //todo: fix egg crash
-                                    Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop);
-                                }
-
-                                await Task.Delay(1000);
-                                await RecycleItems();
-                                if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();
-
-
-                            }
-
-                            var update = await _navigation.HumanPathWalking(TrackPoints.ElementAt(curTrkPt), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
-
-                            if (curTrkPt >= maxTrkPt)
-                                curTrkPt = 0;
-                            else
-                                curTrkPt++;
-
-                        }//end trkpts
-                        if (curTrkSeg >= maxTrkSeg)
-                            curTrkSeg = 0;
-                        else
-                            curTrkSeg++;
-                    }//end trksegs
-                    if (curTrk >= maxTrkSeg)
-                        curTrk = 0;
-                    else
-                        curTrk++;
-                }//end tracks
-            }
-        }
-        private async Task ExecuteFarmingPokestopsAndPokemons()
-        {
-            var distanceFromStart = LocationUtils.CalculateDistanceInMeters(
-                _clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude,
-                _client.CurrentLat, _client.CurrentLng);
-
-            // Edge case for when the client somehow ends up outside the defined radius
-            if (_clientSettings.MaxTravelDistanceInMeters != 0 &&
-                distanceFromStart > _clientSettings.MaxTravelDistanceInMeters)
-            {
-                Logger.Write($"You're outside of your defined radius! Walking to start in 5 seconds...", LogLevel.Warning);
-                await Task.Delay(5000);
-                var update = await _navigation.HumanLikeWalking(
-                    new GeoCoordinate(_clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude),
-                    _clientSettings.WalkingSpeedInKilometerPerHour, null);
-                var ToStart = await _navigation.HumanLikeWalking(
-                    new GeoCoordinate(_clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude),
-                    _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
-            }
-
-            var mapObjects = await _client.GetMapObjects();
-
-            var pokeStops =
-                Navigation.pathByNearestNeighbour(
-                mapObjects.MapCells.SelectMany(i => i.Forts)
-                    .Where(
-                        i =>
-                            i.Type == FortType.Checkpoint &&
-                            i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime() &&
-                            (_clientSettings.MaxTravelDistanceInMeters == 0 ||
-                            LocationUtils.CalculateDistanceInMeters(
-                                _clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude,
-                                    i.Latitude, i.Longitude) < _clientSettings.MaxTravelDistanceInMeters))
-                            .OrderBy(
-                            i =>
-                            LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude)).ToArray());
-            var pokestopList = pokeStops.ToList();
-            if (pokestopList.Count <= 0)
-            {
-                Logger.Write($"No PokeStops within {_clientSettings.MaxTravelDistanceInMeters}m. Choose a different GPS location or increase MaxTravelDistanceInMeters.", LogLevel.Error);
-                return;
-            }
-            Logger.Write($"Found {pokeStops.Count()} pokestops", LogLevel.None, ConsoleColor.Green);
-
-            foreach (var pokeStop in pokeStops)
-            {
-                await ExecuteCatchAllNearbyPokemons();
-
-                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokeStop.Latitude, pokeStop.Longitude);
-                var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
-
-                Logger.Write($"Name: {fortInfo.Name} in {distance:0.##} m distance", LogLevel.Pokestop);
-                var update = await _navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
-
-                var fortSearch = await _client.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
-                if (fortSearch.ExperienceAwarded > 0)
-                {
-                    _stats.AddExperience(fortSearch.ExperienceAwarded);
-                    _stats.UpdateConsoleTitle(_inventory);
-                    string EggReward = fortSearch.PokemonDataEgg != null ? "1" : "0";
-                    Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Eggs: {EggReward}, Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop);
-                    recycleCounter++;
-                }
-                await RandomHelper.RandomDelay(50, 200);
-                if (recycleCounter >= 5)
-                    await RecycleItems();
-            }
-        }
-
-        private async Task CatchEncounter(EncounterResponse encounter, MapPokemon pokemon)
-        {
-            CatchPokemonResponse caughtPokemonResponse;
-            int attemptCounter = 1;
-            do
-            {
-                var bestBerry = await GetBestBerry(encounter?.WildPokemon);
-                var inventoryBerries = await _inventory.GetItems();
-                var probability = encounter?.CaptureProbability?.CaptureProbability_?.FirstOrDefault();
-
-                var bestPokeball = await GetBestBall(encounter?.WildPokemon);
-                if (bestPokeball == MiscEnums.Item.ITEM_UNKNOWN)
-                {
-                    Logger.Write($"You don't own any Pokeballs :( - We missed a {pokemon.PokemonId} with CP {encounter?.WildPokemon?.PokemonData?.Cp}", LogLevel.Warning);
-                    return;
-                }
-
-                var berries = inventoryBerries.Where(p => (ItemId)p.Item_ == bestBerry).FirstOrDefault();
-                if (bestBerry != ItemId.ItemUnknown && probability.HasValue && probability.Value < 0.35 && PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData) >= _clientSettings.KeepMinIVPercentage)
-                {
-                    var useRaspberry = await _client.UseCaptureItem(pokemon.EncounterId, bestBerry, pokemon.SpawnpointId);
-                    Logger.Write($"{bestBerry} used, remaining: {berries.Count}", LogLevel.Berry);
-                    await RandomHelper.RandomDelay(50, 200);
-                }
-
-                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
-                caughtPokemonResponse = await _client.CatchPokemon(pokemon.EncounterId, pokemon.SpawnpointId, pokemon.Latitude, pokemon.Longitude, bestPokeball);
-
-                if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
-                {
-                    foreach (int xp in caughtPokemonResponse.Scores.Xp)
-                        _stats.AddExperience(xp);
-                    _stats.IncreasePokemons();
-                    var profile = await _client.GetProfile();
-                    _stats.GetStardust(profile.Profile.Currency.ToArray()[1].Amount);
-                }
-                _stats.UpdateConsoleTitle(_inventory);
-
-                if (encounter?.CaptureProbability?.CaptureProbability_ != null)
-                {
-                    string catchStatus = attemptCounter > 1 ? $"{caughtPokemonResponse.Status} Attempt #{attemptCounter}" : $"{caughtPokemonResponse.Status}";
-                    string receivedXP = catchStatus == "CatchSuccess" ? $"and received XP {caughtPokemonResponse.Scores.Xp.Sum()}" : $"";
-                    Logger.Write($"({catchStatus}) | {pokemon.PokemonId} Lvl {PokemonInfo.GetLevel(encounter?.WildPokemon?.PokemonData)} (CP {encounter?.WildPokemon?.PokemonData?.Cp}/{PokemonInfo.CalculateMaxCP(encounter?.WildPokemon?.PokemonData)} | {Math.Round(PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")} % perfect) | Chance: {(float)((int)(encounter?.CaptureProbability?.CaptureProbability_.First() * 100)) / 100} | {Math.Round(distance)}m dist | with {bestPokeball} {receivedXP}", LogLevel.Pokemon);
-                }
-
-                attemptCounter++;
-                await RandomHelper.RandomDelay(750, 1250);
-            }
-            while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape);
-        }
-
-        private async Task ExecuteCatchAllNearbyPokemons()
-        {
-            var mapObjects = await _client.GetMapObjects();
-
-            var pokemons =
-                mapObjects.MapCells.SelectMany(i => i.CatchablePokemons)
-                .OrderBy(
-                    i =>
-                    LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
-
-            if (_clientSettings.UsePokemonToNotCatchFilter)
-            {
-                ICollection<PokemonId> filter = _clientSettings.PokemonsNotToCatch;
-                pokemons = mapObjects.MapCells.SelectMany(i => i.CatchablePokemons).Where(p => !filter.Contains(p.PokemonId)).OrderBy(i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
-            }
-
-            if (pokemons != null && pokemons.Any())
-                Logger.Write($"Found {pokemons.Count()} catchable Pokemon", LogLevel.None, ConsoleColor.Green);
-            else
-                return;
-
-            foreach (var pokemon in pokemons)
-            {
-                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
-                await Task.Delay(distance > 100 ? 1000 : 100);
-
-                var encounter = await _client.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnpointId);
-
-                if (encounter.Status == EncounterResponse.Types.Status.EncounterSuccess)
-                    await CatchEncounter(encounter, pokemon);
-                else
-                    Logger.Write($"Encounter problem: {encounter.Status}", LogLevel.Warning);
-                if (pokemons.ElementAtOrDefault(pokemons.Count() - 1) != pokemon)
-                    await RandomHelper.RandomDelay(50, 200);
-            }
-
-            if (_clientSettings.EvolveAllPokemonWithEnoughCandy) await EvolveAllPokemonWithEnoughCandy(_clientSettings.PokemonsToEvolve);
-            if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();
-        }
-
-        private async Task EvolveAllPokemonWithEnoughCandy(IEnumerable<PokemonId> filter = null)
-        {
-            await Inventory.getCachedInventory(_client, true);
-            var pokemonToEvolve = await _inventory.GetPokemonToEvolve(filter);
-            if (pokemonToEvolve != null && pokemonToEvolve.Any())
-                Logger.Write($"{pokemonToEvolve.Count()} Pokemon:", LogLevel.Evolve);
-
-            foreach (var pokemon in pokemonToEvolve)
-            {
-                var evolvePokemonOutProto = await _client.EvolvePokemon((ulong)pokemon.Id);
-
-                Logger.Write(
-                    evolvePokemonOutProto.Result == EvolvePokemonOut.Types.EvolvePokemonStatus.PokemonEvolvedSuccess
-                        ? $"{pokemon.PokemonId} successfully for {evolvePokemonOutProto.ExpAwarded} xp"
-                        : $"Failed: {pokemon.PokemonId}. EvolvePokemonOutProto.Result was {evolvePokemonOutProto.Result}, stopping evolving {pokemon.PokemonId}"
-                    , LogLevel.Evolve);
-
-                await Task.Delay(1000);
-            }
-        }
-
-        private async Task TransferDuplicatePokemon(bool keepPokemonsThatCanEvolve = false)
-        {
-            await Inventory.getCachedInventory(_client, true);
-            var duplicatePokemons = await _inventory.GetDuplicatePokemonToTransfer(keepPokemonsThatCanEvolve, _clientSettings.PrioritizeIVOverCP, _clientSettings.PokemonsNotToTransfer);
-            if (duplicatePokemons != null && duplicatePokemons.Any())
-                Logger.Write($"{duplicatePokemons.Count()} Pokemon:", LogLevel.Transfer);
-
-            foreach (var duplicatePokemon in duplicatePokemons)
-            {
-                var transfer = await _client.TransferPokemon(duplicatePokemon.Id);
-
-                _stats.IncreasePokemonsTransfered();
-                _stats.UpdateConsoleTitle(_inventory);
-
-                var bestPokemonOfType = await _inventory.GetHighestPokemonOfTypeByCP(duplicatePokemon);
-                Logger.Write($"{duplicatePokemon.PokemonId} (CP {duplicatePokemon.Cp} | {PokemonInfo.CalculatePokemonPerfection(duplicatePokemon).ToString("0.00")} % perfect) | (Best: {bestPokemonOfType.Cp} CP | {PokemonInfo.CalculatePokemonPerfection(bestPokemonOfType).ToString("0.00")} % perfect)", LogLevel.Transfer);
-                await Task.Delay(500);
-            }
-        }
-
-        private async Task RecycleItems()
-        {
-            await Inventory.getCachedInventory(_client, true);
-            var items = await _inventory.GetItemsToRecycle(_clientSettings);
-            if (items != null && items.Any())
-                Logger.Write($"{items.Count()} {(items.Count() == 1 ? "Item" : "Items")}:", LogLevel.Recycling);
-
-            foreach (var item in items)
-            {
-                var transfer = await _client.RecycleItem((ItemId)item.Item_, item.Count);
-                Logger.Write($"{item.Count}x {(ItemId)item.Item_}", LogLevel.Recycling);
-
-                _stats.AddItemsRemoved(item.Count);
-                _stats.UpdateConsoleTitle(_inventory);
-
-                await Task.Delay(100);
-            }
-            recycleCounter = 0;
-        }
-
-        private async Task<MiscEnums.Item> GetBestBall(WildPokemon pokemon)
-        {
-            var pokemonCp = pokemon?.PokemonData?.Cp;
-
-            var items = await _inventory.GetItems();
-            var balls = items.Where(i => ((MiscEnums.Item)i.Item_ == MiscEnums.Item.ITEM_POKE_BALL
-                                      || (MiscEnums.Item)i.Item_ == MiscEnums.Item.ITEM_GREAT_BALL
-                                      || (MiscEnums.Item)i.Item_ == MiscEnums.Item.ITEM_ULTRA_BALL
-                                      || (MiscEnums.Item)i.Item_ == MiscEnums.Item.ITEM_MASTER_BALL) && i.Count > 0).GroupBy(i => ((MiscEnums.Item)i.Item_)).ToList();
-            if (balls.Count == 0) return MiscEnums.Item.ITEM_UNKNOWN;
-
-            var pokeBalls = balls.Any(g => g.Key == MiscEnums.Item.ITEM_POKE_BALL);
-            var greatBalls = balls.Any(g => g.Key == MiscEnums.Item.ITEM_GREAT_BALL);
-            var ultraBalls = balls.Any(g => g.Key == MiscEnums.Item.ITEM_ULTRA_BALL);
-            var masterBalls = balls.Any(g => g.Key == MiscEnums.Item.ITEM_MASTER_BALL);
-
-            if (masterBalls && pokemonCp >= 2000)
-                return MiscEnums.Item.ITEM_MASTER_BALL;
-            else if (ultraBalls && pokemonCp >= 2000)
-                return MiscEnums.Item.ITEM_ULTRA_BALL;
-            else if (greatBalls && pokemonCp >= 2000)
-                return MiscEnums.Item.ITEM_GREAT_BALL;
-
-            if (ultraBalls && pokemonCp >= 1000)
-                return MiscEnums.Item.ITEM_ULTRA_BALL;
-            else if (greatBalls && pokemonCp >= 1000)
-                return MiscEnums.Item.ITEM_GREAT_BALL;
-
-            if (greatBalls && pokemonCp >= 500)
-                return MiscEnums.Item.ITEM_GREAT_BALL;
-
-            return balls.OrderBy(g => g.Key).First().Key;
-        }
-
-        private async Task<ItemId> GetBestBerry(WildPokemon pokemon)
-        {
-            var pokemonCp = pokemon?.PokemonData?.Cp;
-
-            var items = await _inventory.GetItems();
-            var berries = items.Where(i => (ItemId)i.Item_ == ItemId.ItemRazzBerry
-                                        || (ItemId)i.Item_ == ItemId.ItemBlukBerry
-                                        || (ItemId)i.Item_ == ItemId.ItemNanabBerry
-                                        || (ItemId)i.Item_ == ItemId.ItemWeparBerry
-                                        || (ItemId)i.Item_ == ItemId.ItemPinapBerry).GroupBy(i => ((ItemId)i.Item_)).ToList();
-            if (berries.Count == 0 || pokemonCp <= 350) return ItemId.ItemUnknown;
-
-            var razzBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_RAZZ_BERRY);
-            var blukBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_BLUK_BERRY);
-            var nanabBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_NANAB_BERRY);
-            var weparBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_WEPAR_BERRY);
-            var pinapBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_PINAP_BERRY);
-
-            if (pinapBerryCount > 0 && pokemonCp >= 2000)
-                return ItemId.ItemPinapBerry;
-            else if (weparBerryCount > 0 && pokemonCp >= 2000)
-                return ItemId.ItemWeparBerry;
-            else if (nanabBerryCount > 0 && pokemonCp >= 2000)
-                return ItemId.ItemNanabBerry;
-            else if (nanabBerryCount > 0 && pokemonCp >= 2000)
-                return ItemId.ItemBlukBerry;
-
-            if (weparBerryCount > 0 && pokemonCp >= 1500)
-                return ItemId.ItemWeparBerry;
-            else if (nanabBerryCount > 0 && pokemonCp >= 1500)
-                return ItemId.ItemNanabBerry;
-            else if (blukBerryCount > 0 && pokemonCp >= 1500)
-                return ItemId.ItemBlukBerry;
-
-            if (nanabBerryCount > 0 && pokemonCp >= 1000)
-                return ItemId.ItemNanabBerry;
-            else if (blukBerryCount > 0 && pokemonCp >= 1000)
-                return ItemId.ItemBlukBerry;
-
-            if (blukBerryCount > 0 && pokemonCp >= 500)
-                return ItemId.ItemBlukBerry;
-
-            return berries.OrderBy(g => g.Key).First().Key;
-        }
-
-        private async Task DisplayPlayerLevelInTitle(bool updateOnly = false)
-        {
-            _playerProfile = _playerProfile.Profile != null ? _playerProfile : await _client.GetProfile();
-            var playerName = _playerProfile.Profile.Username ?? "";
-            var playerStats = await _inventory.GetPlayerStats();
-            var playerStat = playerStats.FirstOrDefault();
-            if (playerStat != null)
-            {
-                var message =
-                    $" {playerName} | Level {playerStat.Level:0} - ({playerStat.Experience - playerStat.PrevLevelXp:0} / {playerStat.NextLevelXp - playerStat.PrevLevelXp:0} XP)";
-                Console.Title = message;
-                if (updateOnly == false)
-                    Logger.Write(message);
-            }
-            if (updateOnly == false)
-                await Task.Delay(5000);
-        }
-
-        private async Task DisplayHighests()
-        {
-            Logger.Write($"====== DisplayHighestsCP ======", LogLevel.Info, ConsoleColor.Yellow);
-            var highestsPokemonCP = await _inventory.GetHighestsCP(10);
-            foreach (var pokemon in highestsPokemonCP)
-                Logger.Write($"# CP {pokemon.Cp.ToString().PadLeft(4, ' ')}/{PokemonInfo.CalculateMaxCP(pokemon).ToString().PadLeft(4, ' ')} | ({PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect)\t| Lvl {PokemonInfo.GetLevel(pokemon).ToString("00")}\t NAME: '{pokemon.PokemonId}'");
-            Logger.Write($"====== DisplayHighestsPerfect ======", LogLevel.Info, ConsoleColor.Yellow);
-            var highestsPokemonPerfect = await _inventory.GetHighestsPerfect(10);
-            foreach (var pokemon in highestsPokemonPerfect)
-            {
-                Logger.Write($"# CP {pokemon.Cp.ToString().PadLeft(4, ' ')}/{PokemonInfo.CalculateMaxCP(pokemon).ToString().PadLeft(4, ' ')} | ({PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect)\t| Lvl {PokemonInfo.GetLevel(pokemon).ToString("00")}\t NAME: '{pokemon.PokemonId}'");
-            }
-        }
-
-        private async Task PokemonToCSV(string filename = "PokeList.csv")
-        {
-            string path = Directory.GetCurrentDirectory() + "\\Export\\";
-            if (!Directory.Exists(path))
-                Directory.CreateDirectory(path);
-            if (Directory.Exists(path))
-            {
-                try
-                {
-                    if (File.Exists(path + filename))
-                        File.Delete(path + filename);
-                    if (!File.Exists(path + filename))
-                    {
-                        var AllPokemon = await _inventory.GetHighestsPerfect(1000);
-                        var csvExportPokemonAll = new StringBuilder();
-                        var columnnames = string.Format("{0};{1};{2};{3}", "#", "NAME", "CP", "PERFECTION");
-                        csvExportPokemonAll.AppendLine(columnnames);
-                        foreach (var pokemon in AllPokemon)
-                        {
-                            int POKENUMBER = (int)pokemon.PokemonId;
-                            var NAME = $"{pokemon.PokemonId}";
-                            var CP = $"{pokemon.Cp}";
-                            string PERFECTION = PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00");
-                            var pokedata = string.Format("{0};{1};{2};{3}", POKENUMBER, NAME, CP, PERFECTION);
-                            csvExportPokemonAll.AppendLine(pokedata);
-                        }
-                        Logger.Write($"Export all Pokemon to \"\\Export\\{filename}\"", LogLevel.Info);
-                        File.WriteAllText(path + filename, csvExportPokemonAll.ToString());
-                    }
-                }
-                catch
-                {
-                    Logger.Write("Export all Pokemons to CSV not possible. File seems be in use!", LogLevel.Warning);
-                }
-            }
-        }
-
-        private async Task LoadAndDisplayGPXFile()
-        {
-            string xmlString = File.ReadAllText(_clientSettings.GPXFile);
-            GPXReader Readgpx = new GPXReader(xmlString);
-            foreach (GPXReader.trk trk in Readgpx.Tracks)
-            {
-                foreach (GPXReader.trkseg trkseg in trk.Segments)
-                {
-                    foreach (GPXReader.trkpt trpkt in trkseg.TrackPoints)
-                    {
-                        Console.WriteLine(trpkt.ToString());
-                    }
-                }
-            }
-            await Task.Delay(0);
-        }
-
-        private GPXReader.trk GetGPXTrack(string gpxFile)
-        {
-            string xmlString = File.ReadAllText(_clientSettings.GPXFile);
-            GPXReader Readgpx = new GPXReader(xmlString);
-            return Readgpx.Tracks.ElementAt(0);
-        }
-
-        private List<GPXReader.trk> GetGPXTracks(string gpxFile)
-        {
-            string xmlString = File.ReadAllText(_clientSettings.GPXFile);
-            GPXReader Readgpx = new GPXReader(xmlString);
-            return Readgpx.Tracks;
-        }
-
-    }
+#region
+
+using System;
+using System.Collections.Generic;
+using System.Device.Location;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using PokemonGo.RocketAPI.Enums;
+using PokemonGo.RocketAPI.Exceptions;
+using PokemonGo.RocketAPI.Extensions;
+using PokemonGo.RocketAPI.GeneratedCode;
+using PokemonGo.RocketAPI.Logic.Utils;
+using PokemonGo.RocketAPI.Helpers;
+using System.IO;
+using System.Text;
+using PokemonGo.RocketAPI.Logging;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI.Logic
+{
+    public class Logic
+    {
+        private readonly Client _client;
+        private readonly ISettings _clientSettings;
+        private readonly Inventory _inventory;
+        private readonly Statistics _stats;
+        private readonly Navigation _navigation;
+        private GetPlayerResponse _playerProfile;
+
+        private int recycleCounter = 0;
+
+        public Logic(ISettings clientSettings)
+        {
+            _clientSettings = clientSettings;
+            _client = new Client(_clientSettings);
+            _inventory = new Inventory(_client);
+            _stats = new Statistics();
+            _navigation = new Navigation(_client);
+        }
+
+        public async Task Execute()
+        {
+            Git.CheckVersion();
+
+            if (_clientSettings.DefaultLatitude == 0 || _clientSettings.DefaultLongitude == 0)
+            {
+                Logger.Write($"Please change first Latitude and/or Longitude because currently your using default values!", LogLevel.Error);
+                Logger.Write($"Window will be auto closed in 15 seconds!", LogLevel.Error);
+                await Task.Delay(15000);
+                System.Environment.Exit(1);
+            } else
+            {
+                Logger.Write($"Make sure Lat & Lng is right. Exit Program if not! Lat: {_client.CurrentLat} Lng: {_client.CurrentLng}", LogLevel.Warning);
+                for (int i = 3; i > 0; i--)
+                {
+                    Logger.Write($"Script will continue in {i * 5} seconds!", LogLevel.Warning);
+                    await Task.Delay(5000);
+                }
+            }
+
+            Logger.Write($"Logging in via: {_clientSettings.AuthType}", LogLevel.Info);
+            while (true)
+            {
+                try
+                {
+                    switch (_clientSettings.AuthType)
+                    {
+                        case AuthType.Ptc:
+                            await _client.DoPtcLogin(_clientSettings.PtcUsername, _clientSettings.PtcPassword);
+                            break;
+                        case AuthType.Google:
+                            await _client.DoGoogleLogin("GoogleAuth.ini");
+                            break;
+                        default:
+                            Logger.Write("wrong AuthType");
+                            Environment.Exit(0);
+                            break;
+                    }
+
+                    await _client.SetServer();
+
+                    await PostLoginExecute();
+                }
+                catch (Exception e)
+                {
+                    Logger.Write(e.Message + " from " + e.Source);
+                    Logger.Write("Got an exception, trying automatic restart..", LogLevel.Error);
+                    await Execute();
+                }
+                await Task.Delay(10000);
+            }
+        }
+
+        public async Task PostLoginExecute()
+        {
+            Logger.Write($"Client logged in", LogLevel.Info);
+
+            while (true)
+            {
+                await Inventory.getCachedInventory(_client);
+                _playerProfile = await _client.GetProfile();
+                var PlayerName = Statistics.GetUsername(_client, _playerProfile);
+                _stats.UpdateConsoleTitle(_inventory);
+                var _currentLevelInfos = await Statistics._getcurrentLevelInfos(_inventory);
+
+                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
+                if (_clientSettings.AuthType == AuthType.Ptc)
+                    Logger.Write($"PTC Account: {PlayerName}\n", LogLevel.None, ConsoleColor.Cyan);
+                Logger.Write($"Latitude: {_clientSettings.DefaultLatitude}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write($"Longitude: {_clientSettings.DefaultLongitude}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
+                Logger.Write("Your Account:\n");
+                Logger.Write($"Name: {PlayerName}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write($"Team: {_playerProfile.Profile.Team}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write($"Level: {_currentLevelInfos}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write($"Stardust: {_playerProfile.Profile.Currency.ToArray()[1].Amount}", LogLevel.None, ConsoleColor.DarkGray);
+                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
+                await DisplayHighests();
+                Logger.Write("----------------------------", LogLevel.None, ConsoleColor.Yellow);
+
+                var PokemonsNotToTransfer = _clientSettings.PokemonsNotToTransfer;
+                var PokemonsNotToCatch = _clientSettings.PokemonsNotToCatch;
+                var PokemonsToEvolve = _clientSettings.PokemonsToEvolve;
+
+                if (_clientSettings.EvolveAllPokemonWithEnoughCandy) await EvolveAllPokemonWithEnoughCandy(_clientSettings.PokemonsToEvolve);
+                if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();
+                await PokemonToCSV();
+                await RecycleItems();
+                await ExecuteFarmingPokestopsAndPokemons(_clientSettings.UseGPXPathing);
+
+                /*
+            * Example calls below
+            *
+            var profile = await _client.GetProfile();
+            var settings = await _client.GetSettings();
+            var mapObjects = await _client.GetMapObjects();
+            var inventory = await _client.GetInventory();
+            var pokemons = inventory.InventoryDelta.InventoryItems.Select(i => i.InventoryItemData?.Pokemon).Where(p => p != null && p?.PokemonId > 0);
+            */
+
+                await Task.Delay(10000);
+            }
+        }
+
+        private async Task ExecuteFarmingPokestopsAndPokemons(bool path = false)
+        {
+            if (!path)
+                await ExecuteFarmingPokestopsAndPokemons();
+            else
+            {
+                //bool onTrack = true;
+                List<GPXReader.trk> Tracks = GetGPXTracks(_clientSettings.GPXFile);
+                int curTrkPt = 0;
+                int maxTrkPt = 0;
+                int curTrk = 0;
+                int maxTrk = Tracks.Count - 1;
+                int curTrkSeg = 0;
+                int maxTrkSeg = 0;
+                while (curTrk <= maxTrk)
+                {
+                    var Track = Tracks.ElementAt(curTrk);
+                    var trackSegments = Track.Segments;
+                    maxTrkSeg = trackSegments.Count - 1;
+                    while (curTrkSeg <= maxTrkSeg)
+                    {
+                        List<GPXReader.trkpt> TrackPoints = Track.Segments.ElementAt(0).TrackPoints;
+                        maxTrkPt = TrackPoints.Count - 1;
+                        var mapObjects = await _client.GetMapObjects();
+                        while (curTrkPt <= maxTrkPt)
+                        {
+                            GPXReader.trkpt nextPoint = TrackPoints.ElementAt(curTrkPt);
+                            if (LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, Convert.ToDouble(nextPoint.Lat), Convert.ToDouble(nextPoint.Lon)) > 5000)
+                            {
+                                Logger.Write($"Your desired destination of {nextPoint.Lat}, {nextPoint.Lon} is too far from your current position of {_client.CurrentLat}, {_client.CurrentLng}", LogLevel.Error);
+                                break;
+                            }
+
+                            Logger.Write($"Your desired destination is {nextPoint.Lat}, your location is {nextPoint.Lon} {_client.CurrentLat}, {_client.CurrentLng}", LogLevel.Warning);
+
+                            // Wasn't sure how to make this pretty. Edit as needed.
+                            var pokeStops =
+                                mapObjects.MapCells.SelectMany(i => i.Forts)
+                                    .Where(
+                                        i =>
+                                            i.Type == FortType.Checkpoint &&
+                                            i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime() &&
+                                            ( // Make sure PokeStop is within 40 meters, otherwise we cannot hit them.
+                                            LocationUtils.CalculateDistanceInMeters(
+                                                _client.CurrentLat, _client.CurrentLng,
+                                                    i.Latitude, i.Longitude) < 40)
+                                            );
+
+                            var pokestopList = pokeStops.ToList();
+
+                            while (pokestopList.Any())
+                            {
+                                pokestopList = pokestopList.OrderBy(i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude)).ToList();
+                                var pokeStop = pokestopList[0];
+                                pokestopList.RemoveAt(0);
+
+                                var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
+
+                                var fortSearch = await _client.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
+                                if (fortSearch.ExperienceAwarded > 0)
+                                {
+                                    _stats.AddExperience(fortSearch.ExperienceAwarded);
+                                    _stats.UpdateConsoleTitle(_inventory);
+                                    //todo: fix egg crash
+                                    Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop);
+                                }
+
+                                await Task.Delay(1000);
+                                await RecycleItems();
+                                if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();
+
+
+                            }
+
+                            var update = await _navigation.HumanPathWalking(TrackPoints.ElementAt(curTrkPt), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
+
+                            if (curTrkPt >= maxTrkPt)
+                                curTrkPt = 0;
+                            else
+                                curTrkPt++;
+
+                        }//end trkpts
+                        if (curTrkSeg >= maxTrkSeg)
+                            curTrkSeg = 0;
+                        else
+                            curTrkSeg++;
+                    }//end trksegs
+                    if (curTrk >= maxTrkSeg)
+                        curTrk = 0;
+                    else
+                        curTrk++;
+                }//end tracks
+            }
+        }
+        private async Task ExecuteFarmingPokestopsAndPokemons()
+        {
+            var distanceFromStart = LocationUtils.CalculateDistanceInMeters(
+                _clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude,
+                _client.CurrentLat, _client.CurrentLng);
+
+            // Edge case for when the client somehow ends up outside the defined radius
+            if (_clientSettings.MaxTravelDistanceInMeters != 0 &&
+                distanceFromStart > _clientSettings.MaxTravelDistanceInMeters)
+            {
+                Logger.Write($"You're outside of your defined radius! Walking to start in 5 seconds...", LogLevel.Warning);
+                await Task.Delay(5000);
+                var update = await _navigation.HumanLikeWalking(
+                    new GeoCoordinate(_clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude),
+                    _clientSettings.WalkingSpeedInKilometerPerHour, null);
+                var ToStart = await _navigation.HumanLikeWalking(
+                    new GeoCoordinate(_clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude),
+                    _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
+            }
+
+            var mapObjects = await _client.GetMapObjects();
+
+            var pokeStops =
+                Navigation.pathByNearestNeighbour(
+                mapObjects.MapCells.SelectMany(i => i.Forts)
+                    .Where(
+                        i =>
+                            i.Type == FortType.Checkpoint &&
+                            i.CooldownCompleteTimestampMs < DateTime.UtcNow.ToUnixTime() &&
+                            (_clientSettings.MaxTravelDistanceInMeters == 0 ||
+                            LocationUtils.CalculateDistanceInMeters(
+                                _clientSettings.DefaultLatitude, _clientSettings.DefaultLongitude,
+                                    i.Latitude, i.Longitude) < _clientSettings.MaxTravelDistanceInMeters))
+                            .OrderBy(
+                            i =>
+                            LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude)).ToArray());
+            var pokestopList = pokeStops.ToList();
+            if (pokestopList.Count <= 0)
+            {
+                Logger.Write($"No PokeStops within {_clientSettings.MaxTravelDistanceInMeters}m. Choose a different GPS location or increase MaxTravelDistanceInMeters.", LogLevel.Error);
+                return;
+            }
+            Logger.Write($"Found {pokeStops.Count()} pokestops", LogLevel.None, ConsoleColor.Green);
+
+            foreach (var pokeStop in pokeStops)
+            {
+                await ExecuteCatchAllNearbyPokemons();
+
+                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokeStop.Latitude, pokeStop.Longitude);
+                var fortInfo = await _client.GetFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
+
+                Logger.Write($"Name: {fortInfo.Name} in {distance:0.##} m distance", LogLevel.Pokestop);
+                var update = await _navigation.HumanLikeWalking(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude), _clientSettings.WalkingSpeedInKilometerPerHour, ExecuteCatchAllNearbyPokemons);
+
+                var fortSearch = await _client.SearchFort(pokeStop.Id, pokeStop.Latitude, pokeStop.Longitude);
+                if (fortSearch.ExperienceAwarded > 0)
+                {
+                    _stats.AddExperience(fortSearch.ExperienceAwarded);
+                    _stats.UpdateConsoleTitle(_inventory);
+                    string EggReward = fortSearch.PokemonDataEgg != null ? "1" : "0";
+                    Logger.Write($"XP: {fortSearch.ExperienceAwarded}, Gems: {fortSearch.GemsAwarded}, Eggs: {EggReward}, Items: {StringUtils.GetSummedFriendlyNameOfItemAwardList(fortSearch.ItemsAwarded)}", LogLevel.Pokestop);
+                    recycleCounter++;
+                }
+                await RandomHelper.RandomDelay(50, 200);
+                if (recycleCounter >= 5)
+                    await RecycleItems();
+            }
+        }
+
+        private async Task CatchEncounter(EncounterResponse encounter, MapPokemon pokemon)
+        {
+            CatchPokemonResponse caughtPokemonResponse;
+            int attemptCounter = 1;
+            do
+            {
+                var bestBerry = await GetBestBerry(encounter?.WildPokemon);
+                var inventoryBerries = await _inventory.GetItems();
+                var probability = encounter?.CaptureProbability?.CaptureProbability_?.FirstOrDefault();
+
+                var bestPokeball = await GetBestBall(encounter?.WildPokemon);
+                if (bestPokeball == MiscEnums.Item.ITEM_UNKNOWN)
+                {
+                    Logger.Write($"You don't own any Pokeballs :( - We missed a {pokemon.PokemonId} with CP {encounter?.WildPokemon?.PokemonData?.Cp}", LogLevel.Warning);
+                    return;
+                }
+
+                var berries = inventoryBerries.Where(p => (ItemId)p.Item_ == bestBerry).FirstOrDefault();
+                if (bestBerry != ItemId.ItemUnknown && probability.HasValue && probability.Value < 0.35 && PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData) >= _clientSettings.KeepMinIVPercentage)
+                {
+                    var useRaspberry = await _client.UseCaptureItem(pokemon.EncounterId, bestBerry, pokemon.SpawnpointId);
+                    Logger.Write($"{bestBerry} used, remaining: {berries.Count}", LogLevel.Berry);
+                    await RandomHelper.RandomDelay(50, 200);
+                }
+
+                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
+                caughtPokemonResponse = await _client.CatchPokemon(pokemon.EncounterId, pokemon.SpawnpointId, pokemon.Latitude, pokemon.Longitude, bestPokeball);
+
+                if (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchSuccess)
+                {
+                    foreach (int xp in caughtPokemonResponse.Scores.Xp)
+                        _stats.AddExperience(xp);
+                    _stats.IncreasePokemons();
+                    var profile = await _client.GetProfile();
+                    _stats.GetStardust(profile.Profile.Currency.ToArray()[1].Amount);
+                }
+                _stats.UpdateConsoleTitle(_inventory);
+
+                if (encounter?.CaptureProbability?.CaptureProbability_ != null)
+                {
+                    string catchStatus = attemptCounter > 1 ? $"{caughtPokemonResponse.Status} Attempt #{attemptCounter}" : $"{caughtPokemonResponse.Status}";
+                    string receivedXP = catchStatus == "CatchSuccess" ? $"and received XP {caughtPokemonResponse.Scores.Xp.Sum()}" : $"";
+                    Logger.Write($"({catchStatus}) | {pokemon.PokemonId} Lvl {PokemonInfo.GetLevel(encounter?.WildPokemon?.PokemonData)} (CP {encounter?.WildPokemon?.PokemonData?.Cp}/{PokemonInfo.CalculateMaxCP(encounter?.WildPokemon?.PokemonData)} | {Math.Round(PokemonInfo.CalculatePokemonPerfection(encounter?.WildPokemon?.PokemonData)).ToString("0.00")} % perfect) | Chance: {(float)((int)(encounter?.CaptureProbability?.CaptureProbability_.First() * 100)) / 100} | {Math.Round(distance)}m dist | with {bestPokeball} {receivedXP}", LogLevel.Pokemon);
+                }
+
+                attemptCounter++;
+                await RandomHelper.RandomDelay(750, 1250);
+            }
+            while (caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchMissed || caughtPokemonResponse.Status == CatchPokemonResponse.Types.CatchStatus.CatchEscape);
+        }
+
+        private async Task ExecuteCatchAllNearbyPokemons()
+        {
+            var mapObjects = await _client.GetMapObjects();
+
+            var pokemons =
+                mapObjects.MapCells.SelectMany(i => i.CatchablePokemons)
+                .OrderBy(
+                    i =>
+                    LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
+
+            if (_clientSettings.UsePokemonToNotCatchFilter)
+            {
+                ICollection<PokemonId> filter = _clientSettings.PokemonsNotToCatch;
+                pokemons = mapObjects.MapCells.SelectMany(i => i.CatchablePokemons).Where(p => !filter.Contains(p.PokemonId)).OrderBy(i => LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, i.Latitude, i.Longitude));
+            }
+
+            if (pokemons != null && pokemons.Any())
+                Logger.Write($"Found {pokemons.Count()} catchable Pokemon", LogLevel.None, ConsoleColor.Green);
+            else
+                return;
+
+            foreach (var pokemon in pokemons)
+            {
+                var distance = LocationUtils.CalculateDistanceInMeters(_client.CurrentLat, _client.CurrentLng, pokemon.Latitude, pokemon.Longitude);
+                await Task.Delay(distance > 100 ? 1000 : 100);
+
+                var encounter = await _client.EncounterPokemon(pokemon.EncounterId, pokemon.SpawnpointId);
+
+                if (encounter.Status == EncounterResponse.Types.Status.EncounterSuccess)
+                    await CatchEncounter(encounter, pokemon);
+                else
+                    Logger.Write($"Encounter problem: {encounter.Status}", LogLevel.Warning);
+                if (pokemons.ElementAtOrDefault(pokemons.Count() - 1) != pokemon)
+                    await RandomHelper.RandomDelay(50, 200);
+            }
+
+            if (_clientSettings.EvolveAllPokemonWithEnoughCandy) await EvolveAllPokemonWithEnoughCandy(_clientSettings.PokemonsToEvolve);
+            if (_clientSettings.TransferDuplicatePokemon) await TransferDuplicatePokemon();
+        }
+
+        private async Task EvolveAllPokemonWithEnoughCandy(IEnumerable<PokemonId> filter = null)
+        {
+            await Inventory.getCachedInventory(_client, true);
+            var pokemonToEvolve = await _inventory.GetPokemonToEvolve(filter);
+            if (pokemonToEvolve != null && pokemonToEvolve.Any())
+                Logger.Write($"{pokemonToEvolve.Count()} Pokemon:", LogLevel.Evolve);
+
+            foreach (var pokemon in pokemonToEvolve)
+            {
+                var evolvePokemonOutProto = await _client.EvolvePokemon((ulong)pokemon.Id);
+
+                Logger.Write(
+                    evolvePokemonOutProto.Result == EvolvePokemonOut.Types.EvolvePokemonStatus.PokemonEvolvedSuccess
+                        ? $"{pokemon.PokemonId} successfully for {evolvePokemonOutProto.ExpAwarded} xp"
+                        : $"Failed: {pokemon.PokemonId}. EvolvePokemonOutProto.Result was {evolvePokemonOutProto.Result}, stopping evolving {pokemon.PokemonId}"
+                    , LogLevel.Evolve);
+
+                await Task.Delay(1000);
+            }
+        }
+
+        private async Task TransferDuplicatePokemon(bool keepPokemonsThatCanEvolve = false)
+        {
+            await Inventory.getCachedInventory(_client, true);
+            var duplicatePokemons = await _inventory.GetDuplicatePokemonToTransfer(keepPokemonsThatCanEvolve, _clientSettings.PrioritizeIVOverCP, _clientSettings.PokemonsNotToTransfer);
+            if (duplicatePokemons != null && duplicatePokemons.Any())
+                Logger.Write($"{duplicatePokemons.Count()} Pokemon:", LogLevel.Transfer);
+
+            foreach (var duplicatePokemon in duplicatePokemons)
+            {
+                var transfer = await _client.TransferPokemon(duplicatePokemon.Id);
+
+                _stats.IncreasePokemonsTransfered();
+                _stats.UpdateConsoleTitle(_inventory);
+
+                var bestPokemonOfType = await _inventory.GetHighestPokemonOfTypeByCP(duplicatePokemon);
+                Logger.Write($"{duplicatePokemon.PokemonId} (CP {duplicatePokemon.Cp} | {PokemonInfo.CalculatePokemonPerfection(duplicatePokemon).ToString("0.00")} % perfect) | (Best: {bestPokemonOfType.Cp} CP | {PokemonInfo.CalculatePokemonPerfection(bestPokemonOfType).ToString("0.00")} % perfect)", LogLevel.Transfer);
+                await Task.Delay(500);
+            }
+        }
+
+        private async Task RecycleItems()
+        {
+            await Inventory.getCachedInventory(_client, true);
+            var items = await _inventory.GetItemsToRecycle(_clientSettings);
+            if (items != null && items.Any())
+                Logger.Write($"{items.Count()} {(items.Count() == 1 ? "Item" : "Items")}:", LogLevel.Recycling);
+
+            foreach (var item in items)
+            {
+                var transfer = await _client.RecycleItem((ItemId)item.Item_, item.Count);
+                Logger.Write($"{item.Count}x {(ItemId)item.Item_}", LogLevel.Recycling);
+
+                _stats.AddItemsRemoved(item.Count);
+                _stats.UpdateConsoleTitle(_inventory);
+
+                await Task.Delay(100);
+            }
+            recycleCounter = 0;
+        }
+
+        private async Task<MiscEnums.Item> GetBestBall(WildPokemon pokemon)
+        {
+            var pokemonCp = pokemon?.PokemonData?.Cp;
+
+            var items = await _inventory.GetItems();
+            var balls = items.Where(i => ((MiscEnums.Item)i.Item_ == MiscEnums.Item.ITEM_POKE_BALL
+                                      || (MiscEnums.Item)i.Item_ == MiscEnums.Item.ITEM_GREAT_BALL
+                                      || (MiscEnums.Item)i.Item_ == MiscEnums.Item.ITEM_ULTRA_BALL
+                                      || (MiscEnums.Item)i.Item_ == MiscEnums.Item.ITEM_MASTER_BALL) && i.Count > 0).GroupBy(i => ((MiscEnums.Item)i.Item_)).ToList();
+            if (balls.Count == 0) return MiscEnums.Item.ITEM_UNKNOWN;
+
+            var pokeBalls = balls.Any(g => g.Key == MiscEnums.Item.ITEM_POKE_BALL);
+            var greatBalls = balls.Any(g => g.Key == MiscEnums.Item.ITEM_GREAT_BALL);
+            var ultraBalls = balls.Any(g => g.Key == MiscEnums.Item.ITEM_ULTRA_BALL);
+            var masterBalls = balls.Any(g => g.Key == MiscEnums.Item.ITEM_MASTER_BALL);
+
+            if (masterBalls && pokemonCp >= 2000)
+                return MiscEnums.Item.ITEM_MASTER_BALL;
+            else if (ultraBalls && pokemonCp >= 2000)
+                return MiscEnums.Item.ITEM_ULTRA_BALL;
+            else if (greatBalls && pokemonCp >= 2000)
+                return MiscEnums.Item.ITEM_GREAT_BALL;
+
+            if (ultraBalls && pokemonCp >= 1000)
+                return MiscEnums.Item.ITEM_ULTRA_BALL;
+            else if (greatBalls && pokemonCp >= 1000)
+                return MiscEnums.Item.ITEM_GREAT_BALL;
+
+            if (greatBalls && pokemonCp >= 500)
+                return MiscEnums.Item.ITEM_GREAT_BALL;
+
+            return balls.OrderBy(g => g.Key).First().Key;
+        }
+
+        private async Task<ItemId> GetBestBerry(WildPokemon pokemon)
+        {
+            var pokemonCp = pokemon?.PokemonData?.Cp;
+
+            var items = await _inventory.GetItems();
+            var berries = items.Where(i => (ItemId)i.Item_ == ItemId.ItemRazzBerry
+                                        || (ItemId)i.Item_ == ItemId.ItemBlukBerry
+                                        || (ItemId)i.Item_ == ItemId.ItemNanabBerry
+                                        || (ItemId)i.Item_ == ItemId.ItemWeparBerry
+                                        || (ItemId)i.Item_ == ItemId.ItemPinapBerry).GroupBy(i => ((ItemId)i.Item_)).ToList();
+            if (berries.Count == 0 || pokemonCp <= 350) return ItemId.ItemUnknown;
+
+            var razzBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_RAZZ_BERRY);
+            var blukBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_BLUK_BERRY);
+            var nanabBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_NANAB_BERRY);
+            var weparBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_WEPAR_BERRY);
+            var pinapBerryCount = await _inventory.GetItemAmountByType(MiscEnums.Item.ITEM_PINAP_BERRY);
+
+            if (pinapBerryCount > 0 && pokemonCp >= 2000)
+                return ItemId.ItemPinapBerry;
+            else if (weparBerryCount > 0 && pokemonCp >= 2000)
+                return ItemId.ItemWeparBerry;
+            else if (nanabBerryCount > 0 && pokemonCp >= 2000)
+                return ItemId.ItemNanabBerry;
+            else if (nanabBerryCount > 0 && pokemonCp >= 2000)
+                return ItemId.ItemBlukBerry;
+
+            if (weparBerryCount > 0 && pokemonCp >= 1500)
+                return ItemId.ItemWeparBerry;
+            else if (nanabBerryCount > 0 && pokemonCp >= 1500)
+                return ItemId.ItemNanabBerry;
+            else if (blukBerryCount > 0 && pokemonCp >= 1500)
+                return ItemId.ItemBlukBerry;
+
+            if (nanabBerryCount > 0 && pokemonCp >= 1000)
+                return ItemId.ItemNanabBerry;
+            else if (blukBerryCount > 0 && pokemonCp >= 1000)
+                return ItemId.ItemBlukBerry;
+
+            if (blukBerryCount > 0 && pokemonCp >= 500)
+                return ItemId.ItemBlukBerry;
+
+            return berries.OrderBy(g => g.Key).First().Key;
+        }
+
+        private async Task DisplayPlayerLevelInTitle(bool updateOnly = false)
+        {
+            _playerProfile = _playerProfile.Profile != null ? _playerProfile : await _client.GetProfile();
+            var playerName = _playerProfile.Profile.Username ?? "";
+            var playerStats = await _inventory.GetPlayerStats();
+            var playerStat = playerStats.FirstOrDefault();
+            if (playerStat != null)
+            {
+                var message =
+                    $" {playerName} | Level {playerStat.Level:0} - ({playerStat.Experience - playerStat.PrevLevelXp:0} / {playerStat.NextLevelXp - playerStat.PrevLevelXp:0} XP)";
+                Console.Title = message;
+                if (updateOnly == false)
+                    Logger.Write(message);
+            }
+            if (updateOnly == false)
+                await Task.Delay(5000);
+        }
+
+        private async Task DisplayHighests()
+        {
+            Logger.Write($"====== DisplayHighestsCP ======", LogLevel.Info, ConsoleColor.Yellow);
+            var highestsPokemonCP = await _inventory.GetHighestsCP(10);
+            foreach (var pokemon in highestsPokemonCP)
+                Logger.Write($"# CP {pokemon.Cp.ToString().PadLeft(4, ' ')}/{PokemonInfo.CalculateMaxCP(pokemon).ToString().PadLeft(4, ' ')} | ({PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect)\t| Lvl {PokemonInfo.GetLevel(pokemon).ToString("00")}\t NAME: '{pokemon.PokemonId}'");
+            Logger.Write($"====== DisplayHighestsPerfect ======", LogLevel.Info, ConsoleColor.Yellow);
+            var highestsPokemonPerfect = await _inventory.GetHighestsPerfect(10);
+            foreach (var pokemon in highestsPokemonPerfect)
+            {
+                Logger.Write($"# CP {pokemon.Cp.ToString().PadLeft(4, ' ')}/{PokemonInfo.CalculateMaxCP(pokemon).ToString().PadLeft(4, ' ')} | ({PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00")}% perfect)\t| Lvl {PokemonInfo.GetLevel(pokemon).ToString("00")}\t NAME: '{pokemon.PokemonId}'");
+            }
+        }
+
+        private async Task PokemonToCSV(string filename = "PokeList.csv")
+        {
+            string path = Directory.GetCurrentDirectory() + "\\Export\\";
+            if (!Directory.Exists(path))
+                Directory.CreateDirectory(path);
+            if (Directory.Exists(path))
+            {
+                try
+                {
+                    if (File.Exists(path + filename))
+                        File.Delete(path + filename);
+                    if (!File.Exists(path + filename))
+                    {
+                        var AllPokemon = await _inventory.GetHighestsPerfect(1000);
+                        var csvExportPokemonAll = new StringBuilder();
+                        var columnnames = string.Format("{0};{1};{2};{3}", "#", "NAME", "CP", "PERFECTION");
+                        csvExportPokemonAll.AppendLine(columnnames);
+                        foreach (var pokemon in AllPokemon)
+                        {
+                            int POKENUMBER = (int)pokemon.PokemonId;
+                            var NAME = $"{pokemon.PokemonId}";
+                            var CP = $"{pokemon.Cp}";
+                            string PERFECTION = PokemonInfo.CalculatePokemonPerfection(pokemon).ToString("0.00");
+                            var pokedata = string.Format("{0};{1};{2};{3}", POKENUMBER, NAME, CP, PERFECTION);
+                            csvExportPokemonAll.AppendLine(pokedata);
+                        }
+                        Logger.Write($"Export all Pokemon to \"\\Export\\{filename}\"", LogLevel.Info);
+                        File.WriteAllText(path + filename, csvExportPokemonAll.ToString());
+                    }
+                }
+                catch
+                {
+                    Logger.Write("Export all Pokemons to CSV not possible. File seems be in use!", LogLevel.Warning);
+                }
+            }
+        }
+
+        private async Task LoadAndDisplayGPXFile()
+        {
+            string xmlString = File.ReadAllText(_clientSettings.GPXFile);
+            GPXReader Readgpx = new GPXReader(xmlString);
+            foreach (GPXReader.trk trk in Readgpx.Tracks)
+            {
+                foreach (GPXReader.trkseg trkseg in trk.Segments)
+                {
+                    foreach (GPXReader.trkpt trpkt in trkseg.TrackPoints)
+                    {
+                        Console.WriteLine(trpkt.ToString());
+                    }
+                }
+            }
+            await Task.Delay(0);
+        }
+
+        private GPXReader.trk GetGPXTrack(string gpxFile)
+        {
+            string xmlString = File.ReadAllText(_clientSettings.GPXFile);
+            GPXReader Readgpx = new GPXReader(xmlString);
+            return Readgpx.Tracks.ElementAt(0);
+        }
+
+        private List<GPXReader.trk> GetGPXTracks(string gpxFile)
+        {
+            string xmlString = File.ReadAllText(_clientSettings.GPXFile);
+            GPXReader Readgpx = new GPXReader(xmlString);
+            return Readgpx.Tracks;
+        }
+
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Logic/Navigation.cs b/PokemonGo.RocketAPI.Logic/Navigation.cs
index 1486473..857b49d 100644
--- a/PokemonGo.RocketAPI.Logic/Navigation.cs
+++ b/PokemonGo.RocketAPI.Logic/Navigation.cs
@@ -1,162 +1,162 @@
-#region
-
-using System;
-using System.Device.Location;
-using System.Threading.Tasks;
-using PokemonGo.RocketAPI.GeneratedCode;
-using PokemonGo.RocketAPI.Logic.Utils;
-using PokemonGo.RocketAPI.Logging;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Logic
-{
-    public class Navigation
-    {
-
-        private const double SpeedDownTo = 10 / 3.6;
-        private readonly Client _client;
-
-        public Navigation(Client client)
-        {
-            _client = client;
-        }
-
-        public async Task<PlayerUpdateResponse> HumanLikeWalking(GeoCoordinate targetLocation,
-            double walkingSpeedInKilometersPerHour, Func<Task> functionExecutedWhileWalking)
-        {
-            var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6;
-
-            var sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
-            var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
-            Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!", LogLevel.Navigation);
-
-            var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
-            var nextWaypointDistance = speedInMetersPerSecond;
-            var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
-
-            //Initial walking
-            var requestSendDateTime = DateTime.Now;
-            var result =
-                await
-                    _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, _client.Settings.DefaultAltitude);
-            do
-            {
-                var millisecondsUntilGetUpdatePlayerLocationResponse =
-                    (DateTime.Now - requestSendDateTime).TotalMilliseconds;
-
-                sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
-                var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
-
-                if (currentDistanceToTarget < 40)
-                {
-                    if (speedInMetersPerSecond > SpeedDownTo)
-                    {
-                        Logger.Write($"We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.", LogLevel.Navigation);
-                        speedInMetersPerSecond = SpeedDownTo;
-                    }
-                }
-
-                nextWaypointDistance = Math.Min(currentDistanceToTarget,
-                    millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
-                nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
-                waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
-
-                requestSendDateTime = DateTime.Now;
-                result =
-                    await
-                        _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
-                            _client.Settings.DefaultAltitude);
-                if (functionExecutedWhileWalking != null)
-                    await functionExecutedWhileWalking();// look for pokemon
-                await Task.Delay(Math.Min((int)(distanceToTarget / speedInMetersPerSecond * 100), 3000));
-            } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30);
-
-            return result;
-        }
-
-        public async Task<PlayerUpdateResponse> HumanPathWalking(GPXReader.trkpt trk, double walkingSpeedInKilometersPerHour, Func<Task> functionExecutedWhileWalking)
-        {
-            //PlayerUpdateResponse result = null;
-
-            var targetLocation = new GeoCoordinate(Convert.ToDouble(trk.Lat), Convert.ToDouble(trk.Lon));
-
-            var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6;
-
-            var sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
-            var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
-            // Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget/speedInMetersPerSecond:0.##} seconds!", LogLevel.Info);
-
-            var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
-            var nextWaypointDistance = speedInMetersPerSecond;
-            var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing, Convert.ToDouble(trk.Ele));
-
-            //Initial walking
-
-            var requestSendDateTime = DateTime.Now;
-            var result =
-                await
-                    _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, waypoint.Altitude);
-
-            do
-            {
-                var millisecondsUntilGetUpdatePlayerLocationResponse =
-                    (DateTime.Now - requestSendDateTime).TotalMilliseconds;
-
-                sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
-                var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
-
-                //if (currentDistanceToTarget < 40)
-                //{
-                //    if (speedInMetersPerSecond > SpeedDownTo)
-                //    {
-                //        //Logger.Write("We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.", LogLevel.Info);
-                //        speedInMetersPerSecond = SpeedDownTo;
-                //    }
-                //}
-
-                nextWaypointDistance = Math.Min(currentDistanceToTarget,
-                    millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
-                nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
-                waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
-
-                requestSendDateTime = DateTime.Now;
-                result =
-                    await
-                        _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
-                            waypoint.Altitude);
-                if (functionExecutedWhileWalking != null)
-                    await functionExecutedWhileWalking();// look for pokemon
-                await Task.Delay(Math.Min((int)(distanceToTarget / speedInMetersPerSecond * 1000), 3000));
-            } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30);
-
-            return result;
-        }
-
-        public static FortData[] pathByNearestNeighbour(FortData[] pokeStops)
-        {
-            for (var i = 1; i < pokeStops.Length - 1; i++)
-            {
-                var closest = i + 1;
-                var cloestDist = LocationUtils.CalculateDistanceInMeters(pokeStops[i].Latitude, pokeStops[i].Longitude, pokeStops[closest].Latitude, pokeStops[closest].Longitude);
-                for (var j = closest; j < pokeStops.Length; j++)
-                {
-                    var initialDist = cloestDist;
-                    var newDist = LocationUtils.CalculateDistanceInMeters(pokeStops[i].Latitude, pokeStops[i].Longitude, pokeStops[j].Latitude, pokeStops[j].Longitude);
-                    if (initialDist > newDist)
-                    {
-                        cloestDist = newDist;
-                        closest = j;
-                    }
-
-                }
-                var tmpPok = pokeStops[closest];
-                pokeStops[closest] = pokeStops[i + 1];
-                pokeStops[i + 1] = tmpPok;
-            }
-
-            return pokeStops;
-        }
-    }
+#region
+
+using System;
+using System.Device.Location;
+using System.Threading.Tasks;
+using PokemonGo.RocketAPI.GeneratedCode;
+using PokemonGo.RocketAPI.Logic.Utils;
+using PokemonGo.RocketAPI.Logging;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI.Logic
+{
+    public class Navigation
+    {
+
+        private const double SpeedDownTo = 10 / 3.6;
+        private readonly Client _client;
+
+        public Navigation(Client client)
+        {
+            _client = client;
+        }
+
+        public async Task<PlayerUpdateResponse> HumanLikeWalking(GeoCoordinate targetLocation,
+            double walkingSpeedInKilometersPerHour, Func<Task> functionExecutedWhileWalking)
+        {
+            var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6;
+
+            var sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
+            var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
+            Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget / speedInMetersPerSecond:0.##} seconds!", LogLevel.Navigation);
+
+            var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
+            var nextWaypointDistance = speedInMetersPerSecond;
+            var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+
+            //Initial walking
+            var requestSendDateTime = DateTime.Now;
+            var result =
+                await
+                    _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, _client.Settings.DefaultAltitude);
+            do
+            {
+                var millisecondsUntilGetUpdatePlayerLocationResponse =
+                    (DateTime.Now - requestSendDateTime).TotalMilliseconds;
+
+                sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
+                var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
+
+                if (currentDistanceToTarget < 40)
+                {
+                    if (speedInMetersPerSecond > SpeedDownTo)
+                    {
+                        Logger.Write($"We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.", LogLevel.Navigation);
+                        speedInMetersPerSecond = SpeedDownTo;
+                    }
+                }
+
+                nextWaypointDistance = Math.Min(currentDistanceToTarget,
+                    millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
+                nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
+                waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+
+                requestSendDateTime = DateTime.Now;
+                result =
+                    await
+                        _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
+                            _client.Settings.DefaultAltitude);
+                if (functionExecutedWhileWalking != null)
+                    await functionExecutedWhileWalking();// look for pokemon
+                await Task.Delay(Math.Min((int)(distanceToTarget / speedInMetersPerSecond * 100), 3000));
+            } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30);
+
+            return result;
+        }
+
+        public async Task<PlayerUpdateResponse> HumanPathWalking(GPXReader.trkpt trk, double walkingSpeedInKilometersPerHour, Func<Task> functionExecutedWhileWalking)
+        {
+            //PlayerUpdateResponse result = null;
+
+            var targetLocation = new GeoCoordinate(Convert.ToDouble(trk.Lat), Convert.ToDouble(trk.Lon));
+
+            var speedInMetersPerSecond = walkingSpeedInKilometersPerHour / 3.6;
+
+            var sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
+            var distanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
+            // Logger.Write($"Distance to target location: {distanceToTarget:0.##} meters. Will take {distanceToTarget/speedInMetersPerSecond:0.##} seconds!", LogLevel.Info);
+
+            var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
+            var nextWaypointDistance = speedInMetersPerSecond;
+            var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing, Convert.ToDouble(trk.Ele));
+
+            //Initial walking
+
+            var requestSendDateTime = DateTime.Now;
+            var result =
+                await
+                    _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude, waypoint.Altitude);
+
+            do
+            {
+                var millisecondsUntilGetUpdatePlayerLocationResponse =
+                    (DateTime.Now - requestSendDateTime).TotalMilliseconds;
+
+                sourceLocation = new GeoCoordinate(_client.CurrentLat, _client.CurrentLng);
+                var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
+
+                //if (currentDistanceToTarget < 40)
+                //{
+                //    if (speedInMetersPerSecond > SpeedDownTo)
+                //    {
+                //        //Logger.Write("We are within 40 meters of the target. Speeding down to 10 km/h to not pass the target.", LogLevel.Info);
+                //        speedInMetersPerSecond = SpeedDownTo;
+                //    }
+                //}
+
+                nextWaypointDistance = Math.Min(currentDistanceToTarget,
+                    millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
+                nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
+                waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+
+                requestSendDateTime = DateTime.Now;
+                result =
+                    await
+                        _client.UpdatePlayerLocation(waypoint.Latitude, waypoint.Longitude,
+                            waypoint.Altitude);
+                if (functionExecutedWhileWalking != null)
+                    await functionExecutedWhileWalking();// look for pokemon
+                await Task.Delay(Math.Min((int)(distanceToTarget / speedInMetersPerSecond * 1000), 3000));
+            } while (LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation) >= 30);
+
+            return result;
+        }
+
+        public static FortData[] pathByNearestNeighbour(FortData[] pokeStops)
+        {
+            for (var i = 1; i < pokeStops.Length - 1; i++)
+            {
+                var closest = i + 1;
+                var cloestDist = LocationUtils.CalculateDistanceInMeters(pokeStops[i].Latitude, pokeStops[i].Longitude, pokeStops[closest].Latitude, pokeStops[closest].Longitude);
+                for (var j = closest; j < pokeStops.Length; j++)
+                {
+                    var initialDist = cloestDist;
+                    var newDist = LocationUtils.CalculateDistanceInMeters(pokeStops[i].Latitude, pokeStops[i].Longitude, pokeStops[j].Latitude, pokeStops[j].Longitude);
+                    if (initialDist > newDist)
+                    {
+                        cloestDist = newDist;
+                        closest = j;
+                    }
+
+                }
+                var tmpPok = pokeStops[closest];
+                pokeStops[closest] = pokeStops[i + 1];
+                pokeStops[i + 1] = tmpPok;
+            }
+
+            return pokeStops;
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj b/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
index 5c6e5a4..c3ce1c7 100644
--- a/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
+++ b/PokemonGo.RocketAPI.Logic/PokemonGo.RocketAPI.Logic.csproj
@@ -1,80 +1,80 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <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>{0739E40D-C589-4AEB-93E5-EE8CD6773C60}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>PokemonGo.RocketAPI.Logic</RootNamespace>
-    <AssemblyName>PokemonGo.RocketAPI.Logic</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
-    <AssemblyInfoFilePath>..\PokemonGo.RocketAPI\Properties\AssemblyInfo.cs</AssemblyInfoFilePath>
-    <UpdateAssemblyVersion>True</UpdateAssemblyVersion>
-    <UpdateAssemblyFileVersion>False</UpdateAssemblyFileVersion>
-    <UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
-    <AssemblyVersionSettings>YearStamp.MonthStamp.DayStamp.Increment</AssemblyVersionSettings>
-  </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>
-  </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="Google.Protobuf">
-      <HintPath>..\PokemonGo.RocketAPI\bin\Debug\Google.Protobuf.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Configuration" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Device" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Inventory.cs" />
-    <Compile Include="Logic.cs" />
-    <Compile Include="Navigation.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Utils\GPXReader.cs" />
-    <Compile Include="Utils\LocationUtils.cs" />
-    <Compile Include="Utils\Statistics.cs" />
-    <Compile Include="Utils\StringUtils.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\PokemonGo.RocketAPI\PokemonGo.RocketAPI.csproj">
-      <Project>{05d2da44-1b8e-4cf7-94ed-4d52451cd095}</Project>
-      <Name>PokemonGo.RocketAPI</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="app.config" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <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>{0739E40D-C589-4AEB-93E5-EE8CD6773C60}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>PokemonGo.RocketAPI.Logic</RootNamespace>
+    <AssemblyName>PokemonGo.RocketAPI.Logic</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
+    <AssemblyInfoFilePath>..\PokemonGo.RocketAPI\Properties\AssemblyInfo.cs</AssemblyInfoFilePath>
+    <UpdateAssemblyVersion>True</UpdateAssemblyVersion>
+    <UpdateAssemblyFileVersion>False</UpdateAssemblyFileVersion>
+    <UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
+    <AssemblyVersionSettings>YearStamp.MonthStamp.DayStamp.Increment</AssemblyVersionSettings>
+  </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>
+  </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="Google.Protobuf">
+      <HintPath>..\PokemonGo.RocketAPI\bin\Debug\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Device" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Inventory.cs" />
+    <Compile Include="Logic.cs" />
+    <Compile Include="Navigation.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Utils\GPXReader.cs" />
+    <Compile Include="Utils\LocationUtils.cs" />
+    <Compile Include="Utils\Statistics.cs" />
+    <Compile Include="Utils\StringUtils.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\PokemonGo.RocketAPI\PokemonGo.RocketAPI.csproj">
+      <Project>{05d2da44-1b8e-4cf7-94ed-4d52451cd095}</Project>
+      <Name>PokemonGo.RocketAPI</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
   </Target>
   <Target Name="AfterBuild">
   </Target>
-  -->
+  -->
 </Project>
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Logic/Utils/GPXReader.cs b/PokemonGo.RocketAPI.Logic/Utils/GPXReader.cs
index b80b187..1cac8b2 100644
--- a/PokemonGo.RocketAPI.Logic/Utils/GPXReader.cs
+++ b/PokemonGo.RocketAPI.Logic/Utils/GPXReader.cs
@@ -1,723 +1,723 @@
-using PokemonGo.RocketAPI.Logging;
-using System;
-using System.Collections.Generic;
-using System.Xml;
-namespace PokemonGo.RocketAPI.Logic.Utils
-{
-    public class GPXReader
-    {
-        private XmlDocument _GPX = new XmlDocument();
-
-        private string _Name = "";
-
-        public string Name
-        {
-            get { return _Name; }
-            set { _Name = value; }
-        }
-
-        public string Description = "";
-        public string Author = "";
-        public string EMail = "";
-        public string Time = "";
-        public string KeyWords = "";
-        public string URL = "";
-        public string URLName = "";
-        public GPSBoundary Bounds = new GPSBoundary();
-        public List<wpt> WayPoints = new List<wpt>();
-        public List<rte> Routes = new List<rte>();
-        public List<trk> Tracks = new List<trk>();
-
-        public GPXReader(string XML)
-        {
-            if (!XML.Equals(""))
-            {
-                _GPX.LoadXml(XML);
-                if ((_GPX.DocumentElement).Name.Equals("gpx"))
-                {
-                    XmlNodeList GPXNodes = ((_GPX.GetElementsByTagName("gpx"))[0]).ChildNodes;
-                    foreach (XmlNode Node in GPXNodes)
-                    {
-
-                        switch (Node.Name)
-                        {
-                            case "name":
-                                Name = Node.InnerText;
-                                break;
-                            case "desc":
-                                Description = Node.InnerText;
-                                break;
-                            case "author":
-                                Author = Node.InnerText;
-                                break;
-                            case "email":
-                                EMail = Node.InnerText;
-                                break;
-                            case "time":
-                                Time = Node.InnerText;
-                                break;
-                            case "keywords":
-                                KeyWords = Node.InnerText;
-                                break;
-                            case "bounds":
-                                Bounds = new GPSBoundary();
-                                foreach (XmlAttribute Att in (Node).Attributes)
-                                {
-                                    switch (Att.Name)
-                                    {
-                                        case "minlat":
-                                            Bounds.Min.lat = Att.Value;
-                                            break;
-                                        case "minlon":
-                                            Bounds.Min.lon = Att.Value;
-                                            break;
-                                        case "maxlat":
-                                            Bounds.Max.lat = Att.Value;
-                                            break;
-                                        case "maxlon":
-                                            Bounds.Max.lon = Att.Value;
-                                            break;
-                                    }
-                                }
-                                break;
-                            case "wpt":
-                                wpt NewWayPoint = new wpt(Node);
-                                WayPoints.Add(NewWayPoint);
-                                break;
-                            case "rte":
-                                rte NewRoute = new rte(Node);
-                                Routes.Add(NewRoute);
-                                break;
-                            case "trk":
-                                trk Track = new trk(Node);
-                                Tracks.Add(Track);
-                                break;
-                            case "url":
-                                URL = Node.InnerText;
-                                break;
-                            case "urlname":
-                                URLName = Node.InnerText;
-                                break;
-                            case "topografix:active_point":
-                            case "topografix:map":
-                                break;
-                            default:
-                                Logger.Write("Unhandled data in GPX file, attempting to skip.", LogLevel.Info);
-                                break;
-                        }
-                    }
-                }
-            }
-        }
-
-        public class travelbug
-        {
-            public string ID = "";
-            public string Reference = "";
-            public string Groundspeak_Name = "";
-
-            public travelbug(XmlNode TravelBugNode)
-            {
-                ID = TravelBugNode.Attributes["id"].Value.ToString();
-                Reference = TravelBugNode.Attributes["ref"].Value.ToString();
-                foreach (XmlNode TBChildNode in TravelBugNode.ChildNodes)
-                {
-                    switch (TBChildNode.Name)
-                    {
-                        case "groundspeak:name":
-                            Groundspeak_Name = TBChildNode.InnerText;
-                            break;
-                        default:
-                            throw new Exception("Unhandled Child Node: " + TBChildNode.Name);
-                    }
-                }
-            }
-        }
-
-        public class cachelog
-        {
-            public string ID = "";
-            public string Groundspeak_Date = "";
-            public string Groundspeak_Type = "";
-            public string Groundspeak_Finder = "";
-            public string Groundspeak_FinderID = "";
-            public string Groundspeak_Text = "";
-            public string Groundspeak_TextEncoded = "";
-            public GPSCoordinates Groundspeak_LogWayPoint = new GPSCoordinates();
-
-            public cachelog(XmlNode ChildNode)
-            {
-                ID = ChildNode.Attributes["id"].Value.ToString();
-                foreach (XmlNode Node in ChildNode.ChildNodes)
-                {
-                    switch (Node.Name)
-                    {
-                        case "groundspeak:date":
-                            Groundspeak_Date = Node.InnerText;
-                            break;
-                        case "groundspeak:type":
-                            Groundspeak_Type = Node.InnerText;
-                            break;
-                        case "groundspeak:finder":
-                            Groundspeak_Finder = Node.InnerText;
-                            Groundspeak_FinderID = Node.Attributes["id"].Value.ToString();
-                            break;
-                        case "groundspeak:text":
-                            Groundspeak_Text = Node.InnerText;
-                            Groundspeak_TextEncoded = Node.Attributes["encoded"].Value.ToString();
-                            break;
-                        case "groundspeak:log_wpt":
-                            Groundspeak_LogWayPoint.lat = Node.Attributes["lat"].Value.ToString();
-                            Groundspeak_LogWayPoint.lon = Node.Attributes["lon"].Value.ToString();
-                            break;
-                        default:
-                            throw new Exception("Unhandled Child Node: " + Node.Name);
-                    }
-                }
-            }
-        }
-
-        public class cache
-        {
-            public string ID = "";
-            public string Available = "";
-            public string Archived = "";
-            public string Xmlns = "";
-
-            public string Groundspeak_Name = "";
-            public string Groundspeak_PlacedBy = "";
-            public string Groundspeak_Owner = "";
-            public string Groundspeak_OwnerID = "";
-            public string Groundspeak_Type = "";
-            public string Groundspeak_Container = "";
-            public string Groundspeak_Difficulty = "";
-            public string Groundspeak_Terrain = "";
-            public string Groundspeak_Country = "";
-            public string Groundspeak_State = "";
-            public string Groundspeak_ShortDescription = "";
-            public bool Groundspeak_ShortDescriptionIsHTML = false;
-            public string Groundspeak_LongDescription = "";
-            public bool Groundspeak_LongDescriptionIsHTML = false;
-            public string Groundspeak_EncodedHint = "";
-
-            public List<cachelog> Groundspeak_Logs = new List<cachelog>();
-            public List<travelbug> Groundspeak_Travelbugs = new List<travelbug>();
-            public List<Attribute> Groundspeak_Attributes = new List<Attribute>();
-
-            public cache(XmlNode Node)
-            {
-                #region Attributes
-
-                foreach (XmlAttribute Attribute in Node.Attributes)
-                {
-                    switch (Attribute.Name)
-                    {
-                        case "id":
-                            ID = Attribute.Value;
-                            break;
-                        case "available":
-                            Available = Attribute.Value;
-                            break;
-                        case "archived":
-                            Archived = Attribute.Value;
-                            break;
-                        case "xmlns:groundspeak":
-                            Xmlns = Attribute.Value;
-                            break;
-                        default:
-                            throw new Exception("Unhandled Attribute: " + Attribute.Name);
-                    }
-                }
-                #endregion Attributes
-
-                foreach (XmlNode ChildNode in Node.ChildNodes)
-                {
-                    switch (ChildNode.Name)
-                    {
-                        case "groundspeak:name":
-                            Groundspeak_Name = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:placed_by":
-                            Groundspeak_PlacedBy = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:owner":
-                            Groundspeak_Owner = ChildNode.InnerText;
-                            Groundspeak_OwnerID = ChildNode.Attributes["id"].Value.ToString();
-                            break;
-                        case "groundspeak:type":
-                            Groundspeak_Type = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:container":
-                            Groundspeak_Container = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:difficulty":
-                            Groundspeak_Difficulty = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:terrain":
-                            Groundspeak_Terrain = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:country":
-                            Groundspeak_Country = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:state":
-                            Groundspeak_State = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:short_description":
-                            Groundspeak_ShortDescription = ChildNode.InnerText;
-                            if (ChildNode.Attributes["html"].Value.Equals("True"))
-                            {
-                                Groundspeak_ShortDescriptionIsHTML = true;
-                            }
-                            break;
-                        case "groundspeak:long_description":
-                            Groundspeak_LongDescription = ChildNode.InnerText;
-                            if (ChildNode.Attributes["html"].Value.Equals("True"))
-                            {
-                                Groundspeak_LongDescriptionIsHTML = true;
-                            }
-                            break;
-                        case "groundspeak:encoded_hints":
-                            Groundspeak_EncodedHint = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:logs":
-                            foreach (XmlNode LogNode in ChildNode.ChildNodes)
-                            {
-                                cachelog Groundspeak_LogEntry = new cachelog(LogNode);
-                                Groundspeak_Logs.Add(Groundspeak_LogEntry);
-                            }
-                            break;
-                        case "groundspeak:travelbugs":
-                            foreach (XmlNode TravelBugNode in ChildNode.ChildNodes)
-                            {
-                                travelbug Travelbug = new travelbug(TravelBugNode);
-                                Groundspeak_Travelbugs.Add(Travelbug);
-                            }
-                            break;
-                        case "groundspeak:attributes":
-                            foreach (XmlNode AttributeNode in ChildNode.ChildNodes)
-                            {
-                                Attribute CacheAttribute = new Attribute(AttributeNode);
-                                Groundspeak_Attributes.Add(CacheAttribute);
-                            }
-                            break;
-                        default:
-                            throw new Exception("Unhandled Child Node: " + ChildNode.Name);
-                    }
-                }
-            }
-
-            public cache()
-            {
-            }
-        }
-
-
-        //WayPoint contains Caches and other Objects
-
-        public class wpt
-        {
-            public GPSCoordinates Coordinates = new GPSCoordinates();
-            public string Name = "";
-            public string Desc = "";
-            public string Time = "";
-            public string URLName = "";
-            public string URL = "";
-            public string Sym = "";
-            public string Type = "";
-            public string Ele = "0";
-            public string Cmt = "";
-            public string Opencaching_Awesomeness = "";
-            public string Opencaching_Difficulty = "";
-            public string Opencaching_Terrain = "";
-            public string Opencaching_Size = "";
-            public string Opencaching_VerificationPhrase = "";
-            public string Opencaching_VerificationNumber = "";
-            public string Opencaching_VerificationQR = "";
-            public string Opencaching_VerificationChirp = "";
-            public string Opencaching_SeriesID = "";
-            public string Opencaching_SeriesName = "";
-            public List<string> Opencaching_Tags = new List<string>();
-
-            public cache Groundspeak_Cache = new cache();
-
-            public wpt(XmlNode Node)
-            {
-                Coordinates.lat = Node.Attributes["lat"].Value.ToString();
-                Coordinates.lon = Node.Attributes["lon"].Value.ToString();
-                foreach (XmlNode ChildNode in Node.ChildNodes)
-                {
-                    switch (ChildNode.Name)
-                    {
-                        case "time":
-                            Time = ChildNode.InnerText;
-                            break;
-                        case "name":
-                            Name = ChildNode.InnerText;
-                            break;
-                        case "desc":
-                            Desc = ChildNode.InnerText;
-                            break;
-                        case "url":
-                            URL = ChildNode.InnerText;
-                            break;
-                        case "urlname":
-                            URLName = ChildNode.InnerText;
-                            break;
-                        case "sym":
-                            Sym = ChildNode.InnerText;
-                            break;
-                        case "type":
-                            Type = ChildNode.InnerText;
-                            break;
-                        case "ele":
-                            Ele = ChildNode.InnerText;
-                            break;
-                        case "cmt":
-                            Cmt = ChildNode.InnerText;
-                            break;
-                        case "groundspeak:cache":
-                            Groundspeak_Cache = new cache(ChildNode);
-                            break;
-                        case "ox:opencaching":
-                            foreach (XmlNode OpenCachingChildNode in ChildNode.ChildNodes)
-                            {
-                                switch (OpenCachingChildNode.Name)
-                                {
-                                    case "ox:ratings":
-                                        foreach (XmlNode OpenCachingRatingsChildNode in OpenCachingChildNode.ChildNodes)
-                                        {
-                                            switch (OpenCachingRatingsChildNode.Name)
-                                            {
-                                                case "ox:awesomeness":
-                                                    Opencaching_Awesomeness = (OpenCachingRatingsChildNode).InnerText;
-                                                    break;
-                                                case "ox:difficulty":
-                                                    Opencaching_Difficulty = (OpenCachingRatingsChildNode).InnerText;
-                                                    break;
-                                                case "ox:terrain":
-                                                    Opencaching_Terrain = (OpenCachingRatingsChildNode).InnerText;
-                                                    break;
-                                                case "ox:size":
-                                                    Opencaching_Size = (OpenCachingRatingsChildNode).InnerText;
-                                                    break;
-                                                default:
-                                                    throw new Exception("Unhandled for Child Object: " + OpenCachingRatingsChildNode.Name);
-                                            }
-                                        }
-                                        break;
-                                    case "ox:tags":
-                                        foreach (XmlNode OpenCachingTagNode in OpenCachingChildNode.ChildNodes)
-                                        {
-                                            switch (OpenCachingTagNode.Name)
-                                            {
-                                                case "ox:tag":
-                                                    Opencaching_Tags.Add((OpenCachingTagNode).InnerXml);
-                                                    break;
-                                                default:
-                                                    throw new Exception("Unhandled for Child Object: " + OpenCachingTagNode.Name);
-                                            }
-                                        }
-
-                                        break;
-                                    case "ox:verification":
-                                        foreach (XmlNode OpenCachingVerificationNode in OpenCachingChildNode.ChildNodes)
-                                        {
-                                            switch (OpenCachingVerificationNode.Name)
-                                            {
-                                                case "ox:phrase":
-                                                    Opencaching_VerificationPhrase = OpenCachingChildNode.InnerText;
-                                                    break;
-                                                case "ox:number":
-                                                    Opencaching_VerificationNumber = OpenCachingChildNode.InnerText;
-                                                    break;
-                                                case "ox:QR":
-                                                    Opencaching_VerificationQR = OpenCachingChildNode.InnerText;
-                                                    break;
-                                                case "ox:chirp":
-                                                    Opencaching_VerificationChirp = OpenCachingChildNode.InnerText;
-                                                    break;
-                                                default:
-                                                    throw new Exception("Unhandled for Child Object: " + OpenCachingVerificationNode.Name);
-                                            }
-                                        }
-                                        break;
-                                    case "ox:series":
-                                        Opencaching_SeriesName = OpenCachingChildNode.InnerText;
-                                        Opencaching_SeriesID = (OpenCachingChildNode).Attributes["id"].Value.ToString();
-                                        break;
-                                    default:
-                                        throw new Exception("Unhandled for Child Object: " + OpenCachingChildNode.Name);
-                                }
-                            }
-                            break;
-                        default:
-                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
-                    }
-                }
-            }
-        }
-
-        public class GPSBoundary
-        {
-            public GPSCoordinates Min = new GPSCoordinates();
-            public GPSCoordinates Max = new GPSCoordinates();
-
-            public GPSBoundary()
-            {
-            }
-        }
-
-        public class GPSCoordinates
-        {
-            public string lat = "";
-            public string lon = "";
-
-            public GPSCoordinates()
-            {
-            }
-        }
-
-        public class Attribute : IComparable<Attribute>
-        {
-            public string ID = "";
-            public string Inc = "";
-            public string Description = "";
-
-            public Attribute(XmlNode AttributeNode)
-            {
-                ID = AttributeNode.Attributes["id"].Value.ToString();
-                Inc = AttributeNode.Attributes["inc"].Value.ToString();
-                Description = AttributeNode.InnerText;
-            }
-
-            public Attribute()
-            {
-            }
-
-
-            public int CompareTo(Attribute other)
-            {
-                return this.Description.CompareTo(other.Description);
-
-            }
-        }
-
-        //Route ans Route Points
-
-        public class rte
-        {
-            public string Name = "";
-            public string Desc = "";
-            public string Number = "";
-            public string URL = "";
-            public string URLName = "";
-            List<rtept> RoutePoints = new List<rtept>();
-
-            public rte(XmlNode Node)
-            {
-                foreach (XmlNode ChildNode in Node.ChildNodes)
-                {
-                    switch (ChildNode.Name)
-                    {
-                        case "name":
-                            Name = ChildNode.InnerText;
-                            break;
-                        case "desc":
-                            Desc = ChildNode.InnerText;
-                            break;
-                        case "number":
-                            Number = ChildNode.InnerText;
-                            break;
-                        case "rtept":
-                            rtept RoutePoint = new rtept(ChildNode);
-                            RoutePoints.Add(RoutePoint);
-                            break;
-                        case "url":
-                            URL = ChildNode.InnerText;
-                            break;
-                        case "urlname":
-                            URLName = ChildNode.InnerText;
-                            break;
-                        case "topografix:color":
-                            break;
-                        default:
-                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
-                    }
-                }
-            }
-        }
-
-        public class rtept
-        {
-            public string Lat = "";
-            public string Lon = "";
-            public string Ele = "";
-            public string Time = "";
-            public string Name = "";
-            public string Cmt = "";
-            public string Desc = "";
-            public string Sym = "";
-            public string Type = "";
-            public string URL = "";
-            public string URLName = "";
-
-            public rtept(XmlNode Node)
-            {
-                Lat = Node.Attributes["lat"].Value.ToString();
-                Lon = Node.Attributes["lon"].Value.ToString();
-                foreach (XmlNode ChildNode in Node.ChildNodes)
-                {
-                    switch (ChildNode.Name)
-                    {
-                        case "ele":
-                            Ele = ChildNode.InnerText;
-                            break;
-                        case "time":
-                            Time = ChildNode.InnerText;
-                            break;
-                        case "name":
-                            Name = ChildNode.InnerText;
-                            break;
-                        case "cmt":
-                            Cmt = ChildNode.InnerText;
-                            break;
-                        case "desc":
-                            Desc = ChildNode.InnerText;
-                            break;
-                        case "sym":
-                            Sym = ChildNode.InnerText;
-                            break;
-                        case "type":
-                            Type = ChildNode.InnerText;
-                            break;
-                        case "url":
-                            URL = ChildNode.InnerText;
-                            break;
-                        case "urlname":
-                            URLName = ChildNode.InnerText;
-                            break;
-                        case "topografix:leg":
-                            break;
-                        default:
-                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
-                    }
-                }
-            }
-        }
-
-        //Tracks
-
-        public class trk
-        {
-            public string Name = "";
-            public string Desc = "";
-            public string Number = "";
-            public string URL = "";
-            public string URLName = "";
-            public List<trkseg> Segments = new List<trkseg>();
-
-            public trk(XmlNode Node)
-            {
-                foreach (XmlNode ChildNode in Node)
-                {
-                    switch (ChildNode.Name)
-                    {
-                        case "name":
-                            Name = ChildNode.InnerText;
-                            break;
-                        case "desc":
-                            Desc = ChildNode.InnerText;
-                            break;
-                        case "number":
-                            Number = ChildNode.InnerText;
-                            break;
-                        case "trkseg":
-                            trkseg Segment = new trkseg(ChildNode);
-                            Segments.Add(Segment);
-                            break;
-                        case "url":
-                            URL = ChildNode.InnerText;
-                            break;
-                        case "urlname":
-                            URLName = ChildNode.InnerText;
-                            break;
-                        case "topografix:color":
-                            break;
-                        default:
-                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
-                    }
-                }
-            }
-        }
-
-        public class trkseg
-        {
-            public List<trkpt> TrackPoints = new List<trkpt>();
-
-            public trkseg(XmlNode Node)
-            {
-                foreach (XmlNode ChildNode in Node)
-                {
-                    switch (ChildNode.Name)
-                    {
-                        case "trkpt":
-                            trkpt TrackPoint = new trkpt(ChildNode);
-                            TrackPoints.Add(TrackPoint);
-                            break;
-                        default:
-                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
-                    }
-                }
-            }
-        }
-
-        public class trkpt
-        {
-            public string Lat = "";
-            public string Lon = "";
-            public string Sym = "";
-            public string Ele = "0";
-            public string Time = "";
-            public string Cmt = "";
-            public string Name = "";
-            public string Desc = "";
-
-            public trkpt(XmlNode Node)
-            {
-                Lat = Node.Attributes["lat"].Value.ToString();
-                Lon = Node.Attributes["lon"].Value.ToString();
-                foreach (XmlNode ChildNode in Node)
-                {
-                    switch (ChildNode.Name)
-                    {
-                        case "sym":
-                            Sym = ChildNode.InnerText;
-                            break;
-                        case "ele":
-                            Ele = ChildNode.InnerText;
-                            break;
-                        case "time":
-                            Time = ChildNode.InnerText;
-                            break;
-                        case "cmt":
-                            Cmt = ChildNode.InnerText;
-                            break;
-                        case "name":
-                            Name = ChildNode.InnerText;
-                            break;
-                        case "desc":
-                            Desc = ChildNode.InnerText;
-                            break;
-                        default:
-                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
-                    }
-                }
-            }
-
-            public override string ToString()
-            {
-                return "Latitude: " + Lat + " Longitude: " + Lon + " Elevation: " + Ele;
-            }
-        }
-    }
+using PokemonGo.RocketAPI.Logging;
+using System;
+using System.Collections.Generic;
+using System.Xml;
+namespace PokemonGo.RocketAPI.Logic.Utils
+{
+    public class GPXReader
+    {
+        private XmlDocument _GPX = new XmlDocument();
+
+        private string _Name = "";
+
+        public string Name
+        {
+            get { return _Name; }
+            set { _Name = value; }
+        }
+
+        public string Description = "";
+        public string Author = "";
+        public string EMail = "";
+        public string Time = "";
+        public string KeyWords = "";
+        public string URL = "";
+        public string URLName = "";
+        public GPSBoundary Bounds = new GPSBoundary();
+        public List<wpt> WayPoints = new List<wpt>();
+        public List<rte> Routes = new List<rte>();
+        public List<trk> Tracks = new List<trk>();
+
+        public GPXReader(string XML)
+        {
+            if (!XML.Equals(""))
+            {
+                _GPX.LoadXml(XML);
+                if ((_GPX.DocumentElement).Name.Equals("gpx"))
+                {
+                    XmlNodeList GPXNodes = ((_GPX.GetElementsByTagName("gpx"))[0]).ChildNodes;
+                    foreach (XmlNode Node in GPXNodes)
+                    {
+
+                        switch (Node.Name)
+                        {
+                            case "name":
+                                Name = Node.InnerText;
+                                break;
+                            case "desc":
+                                Description = Node.InnerText;
+                                break;
+                            case "author":
+                                Author = Node.InnerText;
+                                break;
+                            case "email":
+                                EMail = Node.InnerText;
+                                break;
+                            case "time":
+                                Time = Node.InnerText;
+                                break;
+                            case "keywords":
+                                KeyWords = Node.InnerText;
+                                break;
+                            case "bounds":
+                                Bounds = new GPSBoundary();
+                                foreach (XmlAttribute Att in (Node).Attributes)
+                                {
+                                    switch (Att.Name)
+                                    {
+                                        case "minlat":
+                                            Bounds.Min.lat = Att.Value;
+                                            break;
+                                        case "minlon":
+                                            Bounds.Min.lon = Att.Value;
+                                            break;
+                                        case "maxlat":
+                                            Bounds.Max.lat = Att.Value;
+                                            break;
+                                        case "maxlon":
+                                            Bounds.Max.lon = Att.Value;
+                                            break;
+                                    }
+                                }
+                                break;
+                            case "wpt":
+                                wpt NewWayPoint = new wpt(Node);
+                                WayPoints.Add(NewWayPoint);
+                                break;
+                            case "rte":
+                                rte NewRoute = new rte(Node);
+                                Routes.Add(NewRoute);
+                                break;
+                            case "trk":
+                                trk Track = new trk(Node);
+                                Tracks.Add(Track);
+                                break;
+                            case "url":
+                                URL = Node.InnerText;
+                                break;
+                            case "urlname":
+                                URLName = Node.InnerText;
+                                break;
+                            case "topografix:active_point":
+                            case "topografix:map":
+                                break;
+                            default:
+                                Logger.Write("Unhandled data in GPX file, attempting to skip.", LogLevel.Info);
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+
+        public class travelbug
+        {
+            public string ID = "";
+            public string Reference = "";
+            public string Groundspeak_Name = "";
+
+            public travelbug(XmlNode TravelBugNode)
+            {
+                ID = TravelBugNode.Attributes["id"].Value.ToString();
+                Reference = TravelBugNode.Attributes["ref"].Value.ToString();
+                foreach (XmlNode TBChildNode in TravelBugNode.ChildNodes)
+                {
+                    switch (TBChildNode.Name)
+                    {
+                        case "groundspeak:name":
+                            Groundspeak_Name = TBChildNode.InnerText;
+                            break;
+                        default:
+                            throw new Exception("Unhandled Child Node: " + TBChildNode.Name);
+                    }
+                }
+            }
+        }
+
+        public class cachelog
+        {
+            public string ID = "";
+            public string Groundspeak_Date = "";
+            public string Groundspeak_Type = "";
+            public string Groundspeak_Finder = "";
+            public string Groundspeak_FinderID = "";
+            public string Groundspeak_Text = "";
+            public string Groundspeak_TextEncoded = "";
+            public GPSCoordinates Groundspeak_LogWayPoint = new GPSCoordinates();
+
+            public cachelog(XmlNode ChildNode)
+            {
+                ID = ChildNode.Attributes["id"].Value.ToString();
+                foreach (XmlNode Node in ChildNode.ChildNodes)
+                {
+                    switch (Node.Name)
+                    {
+                        case "groundspeak:date":
+                            Groundspeak_Date = Node.InnerText;
+                            break;
+                        case "groundspeak:type":
+                            Groundspeak_Type = Node.InnerText;
+                            break;
+                        case "groundspeak:finder":
+                            Groundspeak_Finder = Node.InnerText;
+                            Groundspeak_FinderID = Node.Attributes["id"].Value.ToString();
+                            break;
+                        case "groundspeak:text":
+                            Groundspeak_Text = Node.InnerText;
+                            Groundspeak_TextEncoded = Node.Attributes["encoded"].Value.ToString();
+                            break;
+                        case "groundspeak:log_wpt":
+                            Groundspeak_LogWayPoint.lat = Node.Attributes["lat"].Value.ToString();
+                            Groundspeak_LogWayPoint.lon = Node.Attributes["lon"].Value.ToString();
+                            break;
+                        default:
+                            throw new Exception("Unhandled Child Node: " + Node.Name);
+                    }
+                }
+            }
+        }
+
+        public class cache
+        {
+            public string ID = "";
+            public string Available = "";
+            public string Archived = "";
+            public string Xmlns = "";
+
+            public string Groundspeak_Name = "";
+            public string Groundspeak_PlacedBy = "";
+            public string Groundspeak_Owner = "";
+            public string Groundspeak_OwnerID = "";
+            public string Groundspeak_Type = "";
+            public string Groundspeak_Container = "";
+            public string Groundspeak_Difficulty = "";
+            public string Groundspeak_Terrain = "";
+            public string Groundspeak_Country = "";
+            public string Groundspeak_State = "";
+            public string Groundspeak_ShortDescription = "";
+            public bool Groundspeak_ShortDescriptionIsHTML = false;
+            public string Groundspeak_LongDescription = "";
+            public bool Groundspeak_LongDescriptionIsHTML = false;
+            public string Groundspeak_EncodedHint = "";
+
+            public List<cachelog> Groundspeak_Logs = new List<cachelog>();
+            public List<travelbug> Groundspeak_Travelbugs = new List<travelbug>();
+            public List<Attribute> Groundspeak_Attributes = new List<Attribute>();
+
+            public cache(XmlNode Node)
+            {
+                #region Attributes
+
+                foreach (XmlAttribute Attribute in Node.Attributes)
+                {
+                    switch (Attribute.Name)
+                    {
+                        case "id":
+                            ID = Attribute.Value;
+                            break;
+                        case "available":
+                            Available = Attribute.Value;
+                            break;
+                        case "archived":
+                            Archived = Attribute.Value;
+                            break;
+                        case "xmlns:groundspeak":
+                            Xmlns = Attribute.Value;
+                            break;
+                        default:
+                            throw new Exception("Unhandled Attribute: " + Attribute.Name);
+                    }
+                }
+                #endregion Attributes
+
+                foreach (XmlNode ChildNode in Node.ChildNodes)
+                {
+                    switch (ChildNode.Name)
+                    {
+                        case "groundspeak:name":
+                            Groundspeak_Name = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:placed_by":
+                            Groundspeak_PlacedBy = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:owner":
+                            Groundspeak_Owner = ChildNode.InnerText;
+                            Groundspeak_OwnerID = ChildNode.Attributes["id"].Value.ToString();
+                            break;
+                        case "groundspeak:type":
+                            Groundspeak_Type = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:container":
+                            Groundspeak_Container = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:difficulty":
+                            Groundspeak_Difficulty = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:terrain":
+                            Groundspeak_Terrain = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:country":
+                            Groundspeak_Country = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:state":
+                            Groundspeak_State = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:short_description":
+                            Groundspeak_ShortDescription = ChildNode.InnerText;
+                            if (ChildNode.Attributes["html"].Value.Equals("True"))
+                            {
+                                Groundspeak_ShortDescriptionIsHTML = true;
+                            }
+                            break;
+                        case "groundspeak:long_description":
+                            Groundspeak_LongDescription = ChildNode.InnerText;
+                            if (ChildNode.Attributes["html"].Value.Equals("True"))
+                            {
+                                Groundspeak_LongDescriptionIsHTML = true;
+                            }
+                            break;
+                        case "groundspeak:encoded_hints":
+                            Groundspeak_EncodedHint = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:logs":
+                            foreach (XmlNode LogNode in ChildNode.ChildNodes)
+                            {
+                                cachelog Groundspeak_LogEntry = new cachelog(LogNode);
+                                Groundspeak_Logs.Add(Groundspeak_LogEntry);
+                            }
+                            break;
+                        case "groundspeak:travelbugs":
+                            foreach (XmlNode TravelBugNode in ChildNode.ChildNodes)
+                            {
+                                travelbug Travelbug = new travelbug(TravelBugNode);
+                                Groundspeak_Travelbugs.Add(Travelbug);
+                            }
+                            break;
+                        case "groundspeak:attributes":
+                            foreach (XmlNode AttributeNode in ChildNode.ChildNodes)
+                            {
+                                Attribute CacheAttribute = new Attribute(AttributeNode);
+                                Groundspeak_Attributes.Add(CacheAttribute);
+                            }
+                            break;
+                        default:
+                            throw new Exception("Unhandled Child Node: " + ChildNode.Name);
+                    }
+                }
+            }
+
+            public cache()
+            {
+            }
+        }
+
+
+        //WayPoint contains Caches and other Objects
+
+        public class wpt
+        {
+            public GPSCoordinates Coordinates = new GPSCoordinates();
+            public string Name = "";
+            public string Desc = "";
+            public string Time = "";
+            public string URLName = "";
+            public string URL = "";
+            public string Sym = "";
+            public string Type = "";
+            public string Ele = "0";
+            public string Cmt = "";
+            public string Opencaching_Awesomeness = "";
+            public string Opencaching_Difficulty = "";
+            public string Opencaching_Terrain = "";
+            public string Opencaching_Size = "";
+            public string Opencaching_VerificationPhrase = "";
+            public string Opencaching_VerificationNumber = "";
+            public string Opencaching_VerificationQR = "";
+            public string Opencaching_VerificationChirp = "";
+            public string Opencaching_SeriesID = "";
+            public string Opencaching_SeriesName = "";
+            public List<string> Opencaching_Tags = new List<string>();
+
+            public cache Groundspeak_Cache = new cache();
+
+            public wpt(XmlNode Node)
+            {
+                Coordinates.lat = Node.Attributes["lat"].Value.ToString();
+                Coordinates.lon = Node.Attributes["lon"].Value.ToString();
+                foreach (XmlNode ChildNode in Node.ChildNodes)
+                {
+                    switch (ChildNode.Name)
+                    {
+                        case "time":
+                            Time = ChildNode.InnerText;
+                            break;
+                        case "name":
+                            Name = ChildNode.InnerText;
+                            break;
+                        case "desc":
+                            Desc = ChildNode.InnerText;
+                            break;
+                        case "url":
+                            URL = ChildNode.InnerText;
+                            break;
+                        case "urlname":
+                            URLName = ChildNode.InnerText;
+                            break;
+                        case "sym":
+                            Sym = ChildNode.InnerText;
+                            break;
+                        case "type":
+                            Type = ChildNode.InnerText;
+                            break;
+                        case "ele":
+                            Ele = ChildNode.InnerText;
+                            break;
+                        case "cmt":
+                            Cmt = ChildNode.InnerText;
+                            break;
+                        case "groundspeak:cache":
+                            Groundspeak_Cache = new cache(ChildNode);
+                            break;
+                        case "ox:opencaching":
+                            foreach (XmlNode OpenCachingChildNode in ChildNode.ChildNodes)
+                            {
+                                switch (OpenCachingChildNode.Name)
+                                {
+                                    case "ox:ratings":
+                                        foreach (XmlNode OpenCachingRatingsChildNode in OpenCachingChildNode.ChildNodes)
+                                        {
+                                            switch (OpenCachingRatingsChildNode.Name)
+                                            {
+                                                case "ox:awesomeness":
+                                                    Opencaching_Awesomeness = (OpenCachingRatingsChildNode).InnerText;
+                                                    break;
+                                                case "ox:difficulty":
+                                                    Opencaching_Difficulty = (OpenCachingRatingsChildNode).InnerText;
+                                                    break;
+                                                case "ox:terrain":
+                                                    Opencaching_Terrain = (OpenCachingRatingsChildNode).InnerText;
+                                                    break;
+                                                case "ox:size":
+                                                    Opencaching_Size = (OpenCachingRatingsChildNode).InnerText;
+                                                    break;
+                                                default:
+                                                    throw new Exception("Unhandled for Child Object: " + OpenCachingRatingsChildNode.Name);
+                                            }
+                                        }
+                                        break;
+                                    case "ox:tags":
+                                        foreach (XmlNode OpenCachingTagNode in OpenCachingChildNode.ChildNodes)
+                                        {
+                                            switch (OpenCachingTagNode.Name)
+                                            {
+                                                case "ox:tag":
+                                                    Opencaching_Tags.Add((OpenCachingTagNode).InnerXml);
+                                                    break;
+                                                default:
+                                                    throw new Exception("Unhandled for Child Object: " + OpenCachingTagNode.Name);
+                                            }
+                                        }
+
+                                        break;
+                                    case "ox:verification":
+                                        foreach (XmlNode OpenCachingVerificationNode in OpenCachingChildNode.ChildNodes)
+                                        {
+                                            switch (OpenCachingVerificationNode.Name)
+                                            {
+                                                case "ox:phrase":
+                                                    Opencaching_VerificationPhrase = OpenCachingChildNode.InnerText;
+                                                    break;
+                                                case "ox:number":
+                                                    Opencaching_VerificationNumber = OpenCachingChildNode.InnerText;
+                                                    break;
+                                                case "ox:QR":
+                                                    Opencaching_VerificationQR = OpenCachingChildNode.InnerText;
+                                                    break;
+                                                case "ox:chirp":
+                                                    Opencaching_VerificationChirp = OpenCachingChildNode.InnerText;
+                                                    break;
+                                                default:
+                                                    throw new Exception("Unhandled for Child Object: " + OpenCachingVerificationNode.Name);
+                                            }
+                                        }
+                                        break;
+                                    case "ox:series":
+                                        Opencaching_SeriesName = OpenCachingChildNode.InnerText;
+                                        Opencaching_SeriesID = (OpenCachingChildNode).Attributes["id"].Value.ToString();
+                                        break;
+                                    default:
+                                        throw new Exception("Unhandled for Child Object: " + OpenCachingChildNode.Name);
+                                }
+                            }
+                            break;
+                        default:
+                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
+                    }
+                }
+            }
+        }
+
+        public class GPSBoundary
+        {
+            public GPSCoordinates Min = new GPSCoordinates();
+            public GPSCoordinates Max = new GPSCoordinates();
+
+            public GPSBoundary()
+            {
+            }
+        }
+
+        public class GPSCoordinates
+        {
+            public string lat = "";
+            public string lon = "";
+
+            public GPSCoordinates()
+            {
+            }
+        }
+
+        public class Attribute : IComparable<Attribute>
+        {
+            public string ID = "";
+            public string Inc = "";
+            public string Description = "";
+
+            public Attribute(XmlNode AttributeNode)
+            {
+                ID = AttributeNode.Attributes["id"].Value.ToString();
+                Inc = AttributeNode.Attributes["inc"].Value.ToString();
+                Description = AttributeNode.InnerText;
+            }
+
+            public Attribute()
+            {
+            }
+
+
+            public int CompareTo(Attribute other)
+            {
+                return this.Description.CompareTo(other.Description);
+
+            }
+        }
+
+        //Route ans Route Points
+
+        public class rte
+        {
+            public string Name = "";
+            public string Desc = "";
+            public string Number = "";
+            public string URL = "";
+            public string URLName = "";
+            List<rtept> RoutePoints = new List<rtept>();
+
+            public rte(XmlNode Node)
+            {
+                foreach (XmlNode ChildNode in Node.ChildNodes)
+                {
+                    switch (ChildNode.Name)
+                    {
+                        case "name":
+                            Name = ChildNode.InnerText;
+                            break;
+                        case "desc":
+                            Desc = ChildNode.InnerText;
+                            break;
+                        case "number":
+                            Number = ChildNode.InnerText;
+                            break;
+                        case "rtept":
+                            rtept RoutePoint = new rtept(ChildNode);
+                            RoutePoints.Add(RoutePoint);
+                            break;
+                        case "url":
+                            URL = ChildNode.InnerText;
+                            break;
+                        case "urlname":
+                            URLName = ChildNode.InnerText;
+                            break;
+                        case "topografix:color":
+                            break;
+                        default:
+                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
+                    }
+                }
+            }
+        }
+
+        public class rtept
+        {
+            public string Lat = "";
+            public string Lon = "";
+            public string Ele = "";
+            public string Time = "";
+            public string Name = "";
+            public string Cmt = "";
+            public string Desc = "";
+            public string Sym = "";
+            public string Type = "";
+            public string URL = "";
+            public string URLName = "";
+
+            public rtept(XmlNode Node)
+            {
+                Lat = Node.Attributes["lat"].Value.ToString();
+                Lon = Node.Attributes["lon"].Value.ToString();
+                foreach (XmlNode ChildNode in Node.ChildNodes)
+                {
+                    switch (ChildNode.Name)
+                    {
+                        case "ele":
+                            Ele = ChildNode.InnerText;
+                            break;
+                        case "time":
+                            Time = ChildNode.InnerText;
+                            break;
+                        case "name":
+                            Name = ChildNode.InnerText;
+                            break;
+                        case "cmt":
+                            Cmt = ChildNode.InnerText;
+                            break;
+                        case "desc":
+                            Desc = ChildNode.InnerText;
+                            break;
+                        case "sym":
+                            Sym = ChildNode.InnerText;
+                            break;
+                        case "type":
+                            Type = ChildNode.InnerText;
+                            break;
+                        case "url":
+                            URL = ChildNode.InnerText;
+                            break;
+                        case "urlname":
+                            URLName = ChildNode.InnerText;
+                            break;
+                        case "topografix:leg":
+                            break;
+                        default:
+                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
+                    }
+                }
+            }
+        }
+
+        //Tracks
+
+        public class trk
+        {
+            public string Name = "";
+            public string Desc = "";
+            public string Number = "";
+            public string URL = "";
+            public string URLName = "";
+            public List<trkseg> Segments = new List<trkseg>();
+
+            public trk(XmlNode Node)
+            {
+                foreach (XmlNode ChildNode in Node)
+                {
+                    switch (ChildNode.Name)
+                    {
+                        case "name":
+                            Name = ChildNode.InnerText;
+                            break;
+                        case "desc":
+                            Desc = ChildNode.InnerText;
+                            break;
+                        case "number":
+                            Number = ChildNode.InnerText;
+                            break;
+                        case "trkseg":
+                            trkseg Segment = new trkseg(ChildNode);
+                            Segments.Add(Segment);
+                            break;
+                        case "url":
+                            URL = ChildNode.InnerText;
+                            break;
+                        case "urlname":
+                            URLName = ChildNode.InnerText;
+                            break;
+                        case "topografix:color":
+                            break;
+                        default:
+                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
+                    }
+                }
+            }
+        }
+
+        public class trkseg
+        {
+            public List<trkpt> TrackPoints = new List<trkpt>();
+
+            public trkseg(XmlNode Node)
+            {
+                foreach (XmlNode ChildNode in Node)
+                {
+                    switch (ChildNode.Name)
+                    {
+                        case "trkpt":
+                            trkpt TrackPoint = new trkpt(ChildNode);
+                            TrackPoints.Add(TrackPoint);
+                            break;
+                        default:
+                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
+                    }
+                }
+            }
+        }
+
+        public class trkpt
+        {
+            public string Lat = "";
+            public string Lon = "";
+            public string Sym = "";
+            public string Ele = "0";
+            public string Time = "";
+            public string Cmt = "";
+            public string Name = "";
+            public string Desc = "";
+
+            public trkpt(XmlNode Node)
+            {
+                Lat = Node.Attributes["lat"].Value.ToString();
+                Lon = Node.Attributes["lon"].Value.ToString();
+                foreach (XmlNode ChildNode in Node)
+                {
+                    switch (ChildNode.Name)
+                    {
+                        case "sym":
+                            Sym = ChildNode.InnerText;
+                            break;
+                        case "ele":
+                            Ele = ChildNode.InnerText;
+                            break;
+                        case "time":
+                            Time = ChildNode.InnerText;
+                            break;
+                        case "cmt":
+                            Cmt = ChildNode.InnerText;
+                            break;
+                        case "name":
+                            Name = ChildNode.InnerText;
+                            break;
+                        case "desc":
+                            Desc = ChildNode.InnerText;
+                            break;
+                        default:
+                            throw new Exception("Unhandled for Child Object: " + ChildNode.Name);
+                    }
+                }
+            }
+
+            public override string ToString()
+            {
+                return "Latitude: " + Lat + " Longitude: " + Lon + " Elevation: " + Ele;
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs b/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
index e250a36..d1c5cb4 100644
--- a/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
+++ b/PokemonGo.RocketAPI.Logic/Utils/LocationUtils.cs
@@ -1,108 +1,108 @@
-#region
-
-using System;
-using System.Device.Location;
-
-#endregion
-
-namespace PokemonGo.RocketAPI.Logic.Utils
-{
-    public static class LocationUtils
-    {
-        public static double CalculateDistanceInMeters(double sourceLat, double sourceLng, double destLat, double destLng)
-        // from http://stackoverflow.com/questions/6366408/calculating-distance-between-two-latitude-and-longitude-geocoordinates
-        {
-            var sourceLocation = new GeoCoordinate(sourceLat, sourceLng);
-            var targetLocation = new GeoCoordinate(destLat, destLng);
-
-            return sourceLocation.GetDistanceTo(targetLocation);
-        }
-
-        public static double CalculateDistanceInMeters(GeoCoordinate sourceLocation, GeoCoordinate destinationLocation)
-        {
-            return CalculateDistanceInMeters(sourceLocation.Latitude, sourceLocation.Longitude, destinationLocation.Latitude, destinationLocation.Longitude);
-        }
-
-        public static GeoCoordinate CreateWaypoint(GeoCoordinate sourceLocation, double distanceInMeters, double bearingDegrees)
-        //from http://stackoverflow.com/a/17545955
-        {
-            var distanceKm = distanceInMeters / 1000.0;
-            var distanceRadians = distanceKm / 6371; //6371 = Earth's radius in km
-
-            var bearingRadians = ToRad(bearingDegrees);
-            var sourceLatitudeRadians = ToRad(sourceLocation.Latitude);
-            var sourceLongitudeRadians = ToRad(sourceLocation.Longitude);
-
-            var targetLatitudeRadians = Math.Asin(Math.Sin(sourceLatitudeRadians) * Math.Cos(distanceRadians)
-                                                  +
-                                                  Math.Cos(sourceLatitudeRadians) * Math.Sin(distanceRadians) *
-                                                  Math.Cos(bearingRadians));
-
-            var targetLongitudeRadians = sourceLongitudeRadians + Math.Atan2(Math.Sin(bearingRadians)
-                                                                             * Math.Sin(distanceRadians) *
-                                                                             Math.Cos(sourceLatitudeRadians),
-                Math.Cos(distanceRadians)
-                - Math.Sin(sourceLatitudeRadians) * Math.Sin(targetLatitudeRadians));
-
-            // adjust toLonRadians to be in the range -180 to +180...
-            targetLongitudeRadians = (targetLongitudeRadians + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
-
-            return new GeoCoordinate(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians));
-        }
-
-        public static GeoCoordinate CreateWaypoint(GeoCoordinate sourceLocation, double distanceInMeters, double bearingDegrees, double altitude)
-        //from http://stackoverflow.com/a/17545955
-        {
-            var distanceKm = distanceInMeters / 1000.0;
-            var distanceRadians = distanceKm / 6371; //6371 = Earth's radius in km
-
-            var bearingRadians = ToRad(bearingDegrees);
-            var sourceLatitudeRadians = ToRad(sourceLocation.Latitude);
-            var sourceLongitudeRadians = ToRad(sourceLocation.Longitude);
-
-            var targetLatitudeRadians = Math.Asin(Math.Sin(sourceLatitudeRadians) * Math.Cos(distanceRadians)
-                                                  +
-                                                  Math.Cos(sourceLatitudeRadians) * Math.Sin(distanceRadians) *
-                                                  Math.Cos(bearingRadians));
-
-            var targetLongitudeRadians = sourceLongitudeRadians + Math.Atan2(Math.Sin(bearingRadians)
-                                                                             * Math.Sin(distanceRadians) *
-                                                                             Math.Cos(sourceLatitudeRadians),
-                Math.Cos(distanceRadians)
-                - Math.Sin(sourceLatitudeRadians) * Math.Sin(targetLatitudeRadians));
-
-            // adjust toLonRadians to be in the range -180 to +180...
-            targetLongitudeRadians = (targetLongitudeRadians + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
-
-            return new GeoCoordinate(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians), altitude);
-        }
-
-        public static double DegreeBearing(GeoCoordinate sourceLocation, GeoCoordinate targetLocation)
-        // from http://stackoverflow.com/questions/2042599/direction-between-2-latitude-longitude-points-in-c-sharp
-        {
-            var dLon = ToRad(targetLocation.Longitude - sourceLocation.Longitude);
-            var dPhi = Math.Log(
-                Math.Tan(ToRad(targetLocation.Latitude) / 2 + Math.PI / 4) /
-                Math.Tan(ToRad(sourceLocation.Latitude) / 2 + Math.PI / 4));
-            if (Math.Abs(dLon) > Math.PI)
-                dLon = dLon > 0 ? -(2 * Math.PI - dLon) : 2 * Math.PI + dLon;
-            return ToBearing(Math.Atan2(dLon, dPhi));
-        }
-
-        public static double ToBearing(double radians)
-        {
-            // convert radians to degrees (as bearing: 0...360)
-            return (ToDegrees(radians) + 360) % 360;
-        }
-
-        public static double ToDegrees(double radians)
-        {
-            return radians * 180 / Math.PI;
-        }
-
-        public static double ToRad(double degrees)
-        {
-            return degrees * (Math.PI / 180);
-        }
-    }
+#region
+
+using System;
+using System.Device.Location;
+
+#endregion
+
+namespace PokemonGo.RocketAPI.Logic.Utils
+{
+    public static class LocationUtils
+    {
+        public static double CalculateDistanceInMeters(double sourceLat, double sourceLng, double destLat, double destLng)
+        // from http://stackoverflow.com/questions/6366408/calculating-distance-between-two-latitude-and-longitude-geocoordinates
+        {
+            var sourceLocation = new GeoCoordinate(sourceLat, sourceLng);
+            var targetLocation = new GeoCoordinate(destLat, destLng);
+
+            return sourceLocation.GetDistanceTo(targetLocation);
+        }
+
+        public static double CalculateDistanceInMeters(GeoCoordinate sourceLocation, GeoCoordinate destinationLocation)
+        {
+            return CalculateDistanceInMeters(sourceLocation.Latitude, sourceLocation.Longitude, destinationLocation.Latitude, destinationLocation.Longitude);
+        }
+
+        public static GeoCoordinate CreateWaypoint(GeoCoordinate sourceLocation, double distanceInMeters, double bearingDegrees)
+        //from http://stackoverflow.com/a/17545955
+        {
+            var distanceKm = distanceInMeters / 1000.0;
+            var distanceRadians = distanceKm / 6371; //6371 = Earth's radius in km
+
+            var bearingRadians = ToRad(bearingDegrees);
+            var sourceLatitudeRadians = ToRad(sourceLocation.Latitude);
+            var sourceLongitudeRadians = ToRad(sourceLocation.Longitude);
+
+            var targetLatitudeRadians = Math.Asin(Math.Sin(sourceLatitudeRadians) * Math.Cos(distanceRadians)
+                                                  +
+                                                  Math.Cos(sourceLatitudeRadians) * Math.Sin(distanceRadians) *
+                                                  Math.Cos(bearingRadians));
+
+            var targetLongitudeRadians = sourceLongitudeRadians + Math.Atan2(Math.Sin(bearingRadians)
+                                                                             * Math.Sin(distanceRadians) *
+                                                                             Math.Cos(sourceLatitudeRadians),
+                Math.Cos(distanceRadians)
+                - Math.Sin(sourceLatitudeRadians) * Math.Sin(targetLatitudeRadians));
+
+            // adjust toLonRadians to be in the range -180 to +180...
+            targetLongitudeRadians = (targetLongitudeRadians + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
+
+            return new GeoCoordinate(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians));
+        }
+
+        public static GeoCoordinate CreateWaypoint(GeoCoordinate sourceLocation, double distanceInMeters, double bearingDegrees, double altitude)
+        //from http://stackoverflow.com/a/17545955
+        {
+            var distanceKm = distanceInMeters / 1000.0;
+            var distanceRadians = distanceKm / 6371; //6371 = Earth's radius in km
+
+            var bearingRadians = ToRad(bearingDegrees);
+            var sourceLatitudeRadians = ToRad(sourceLocation.Latitude);
+            var sourceLongitudeRadians = ToRad(sourceLocation.Longitude);
+
+            var targetLatitudeRadians = Math.Asin(Math.Sin(sourceLatitudeRadians) * Math.Cos(distanceRadians)
+                                                  +
+                                                  Math.Cos(sourceLatitudeRadians) * Math.Sin(distanceRadians) *
+                                                  Math.Cos(bearingRadians));
+
+            var targetLongitudeRadians = sourceLongitudeRadians + Math.Atan2(Math.Sin(bearingRadians)
+                                                                             * Math.Sin(distanceRadians) *
+                                                                             Math.Cos(sourceLatitudeRadians),
+                Math.Cos(distanceRadians)
+                - Math.Sin(sourceLatitudeRadians) * Math.Sin(targetLatitudeRadians));
+
+            // adjust toLonRadians to be in the range -180 to +180...
+            targetLongitudeRadians = (targetLongitudeRadians + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
+
+            return new GeoCoordinate(ToDegrees(targetLatitudeRadians), ToDegrees(targetLongitudeRadians), altitude);
+        }
+
+        public static double DegreeBearing(GeoCoordinate sourceLocation, GeoCoordinate targetLocation)
+        // from http://stackoverflow.com/questions/2042599/direction-between-2-latitude-longitude-points-in-c-sharp
+        {
+            var dLon = ToRad(targetLocation.Longitude - sourceLocation.Longitude);
+            var dPhi = Math.Log(
+                Math.Tan(ToRad(targetLocation.Latitude) / 2 + Math.PI / 4) /
+                Math.Tan(ToRad(sourceLocation.Latitude) / 2 + Math.PI / 4));
+            if (Math.Abs(dLon) > Math.PI)
+                dLon = dLon > 0 ? -(2 * Math.PI - dLon) : 2 * Math.PI + dLon;
+            return ToBearing(Math.Atan2(dLon, dPhi));
+        }
+
+        public static double ToBearing(double radians)
+        {
+            // convert radians to degrees (as bearing: 0...360)
+            return (ToDegrees(radians) + 360) % 360;
+        }
+
+        public static double ToDegrees(double radians)
+        {
+            return radians * 180 / Math.PI;
+        }
+
+        public static double ToRad(double degrees)
+        {
+            return degrees * (Math.PI / 180);
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs b/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
index 0bd86cf..effe0b9 100644
--- a/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
+++ b/PokemonGo.RocketAPI.Logic/Utils/Statistics.cs
@@ -1,187 +1,187 @@
-#region
-
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using PokemonGo.RocketAPI.GeneratedCode;
-using PokemonGo.RocketAPI.Enums;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Logic.Utils
-{
-    internal class Statistics
-    {
-        public static int TotalExperience;
-        public static int TotalPokemons;
-        public static int TotalItemsRemoved;
-        public static int TotalPokemonsTransfered;
-        public static int TotalStardust;
-        public static string CurrentLevelInfos;
-        public static int Currentlevel = -1;
-        public static string PlayerName;
-
-        public static DateTime InitSessionDateTime = DateTime.Now;
-        public static TimeSpan Duration = DateTime.Now - InitSessionDateTime;
-
-        public static async Task<string> _getcurrentLevelInfos(Inventory inventory)
-        {
-            var stats = await inventory.GetPlayerStats();
-            var output = string.Empty;
-            var stat = stats.FirstOrDefault();
-            if (stat != null)
-            {
-                var ep = (stat.NextLevelXp - stat.PrevLevelXp) - (stat.Experience - stat.PrevLevelXp);
-                var hours = Math.Round(ep/(TotalExperience / _getSessionRuntime()), 2);
-
-                output = $"{stat.Level} (LvLUp in {hours}hours | {stat.Experience - stat.PrevLevelXp - GetXpDiff(stat.Level)}/{stat.NextLevelXp - stat.PrevLevelXp - GetXpDiff(stat.Level)} XP)";
-                //output = $"{stat.Level} (LvLUp in {_hours}hours // EXP required: {_ep})";
-            }
-            return output;
-        }
-
-        public static string GetUsername(Client client, GetPlayerResponse profile)
-        {
-            return PlayerName = client.Settings.AuthType == AuthType.Ptc ? client.Settings.PtcUsername : profile.Profile.Username;
-        }
-
-        public static double _getSessionRuntime()
-        {
-            return (DateTime.Now - InitSessionDateTime).TotalSeconds/3600;
-        }
-
-        public static string _getSessionRuntimeInTimeFormat()
-        {
-            return (DateTime.Now - InitSessionDateTime).ToString(@"dd\.hh\:mm\:ss");
-        }
-
-        public void AddExperience(int xp)
-        {
-            TotalExperience += xp;
-        }
-
-        public void AddItemsRemoved(int count)
-        {
-            TotalItemsRemoved += count;
-        }
-
-        public void GetStardust(int stardust)
-        {
-            TotalStardust = stardust;
-        }
-
-        public void IncreasePokemons()
-        {
-            TotalPokemons += 1;
-        }
-
-        public void IncreasePokemonsTransfered()
-        {
-            TotalPokemonsTransfered += 1;
-        }
-
-        public async void UpdateConsoleTitle(Inventory _inventory)
-        {
-            CurrentLevelInfos = await _getcurrentLevelInfos(_inventory);
-            Console.Title = ToString();
-        }
-
-        public override string ToString()
-        {
-            return
-                string.Format(
-                    "{0} - Runtime {1} - Lvl: {2:0} | EXP/H: {3:0} | P/H: {4:0} | Stardust: {5:0} | Transfered: {6:0} | Items Recycled: {7:0}",
-                    PlayerName, _getSessionRuntimeInTimeFormat(), CurrentLevelInfos, TotalExperience / _getSessionRuntime(),
-                    TotalPokemons / _getSessionRuntime(), TotalStardust, TotalPokemonsTransfered, TotalItemsRemoved);
-        }
-
-        public static int GetXpDiff(int level)
-        {
-            switch (level)
-            {
-                case 1:
-                    return 0;
-                case 2:
-                    return 1000;
-                case 3:
-                    return 2000;
-                case 4:
-                    return 3000;
-                case 5:
-                    return 4000;
-                case 6:
-                    return 5000;
-                case 7:
-                    return 6000;
-                case 8:
-                    return 7000;
-                case 9:
-                    return 8000;
-                case 10:
-                    return 9000;
-                case 11:
-                    return 10000;
-                case 12:
-                    return 10000;
-                case 13:
-                    return 10000;
-                case 14:
-                    return 10000;
-                case 15:
-                    return 15000;
-                case 16:
-                    return 20000;
-                case 17:
-                    return 20000;
-                case 18:
-                    return 20000;
-                case 19:
-                    return 25000;
-                case 20:
-                    return 25000;
-                case 21:
-                    return 50000;
-                case 22:
-                    return 75000;
-                case 23:
-                    return 100000;
-                case 24:
-                    return 125000;
-                case 25:
-                    return 150000;
-                case 26:
-                    return 190000;
-                case 27:
-                    return 200000;
-                case 28:
-                    return 250000;
-                case 29:
-                    return 300000;
-                case 30:
-                    return 350000;
-                case 31:
-                    return 500000;
-                case 32:
-                    return 500000;
-                case 33:
-                    return 750000;
-                case 34:
-                    return 1000000;
-                case 35:
-                    return 1250000;
-                case 36:
-                    return 1500000;
-                case 37:
-                    return 2000000;
-                case 38:
-                    return 2500000;
-                case 39:
-                    return 1000000;
-                case 40:
-                    return 1000000;
-            }
-            return 0;
-        }
-    }
+#region
+
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using PokemonGo.RocketAPI.GeneratedCode;
+using PokemonGo.RocketAPI.Enums;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI.Logic.Utils
+{
+    internal class Statistics
+    {
+        public static int TotalExperience;
+        public static int TotalPokemons;
+        public static int TotalItemsRemoved;
+        public static int TotalPokemonsTransfered;
+        public static int TotalStardust;
+        public static string CurrentLevelInfos;
+        public static int Currentlevel = -1;
+        public static string PlayerName;
+
+        public static DateTime InitSessionDateTime = DateTime.Now;
+        public static TimeSpan Duration = DateTime.Now - InitSessionDateTime;
+
+        public static async Task<string> _getcurrentLevelInfos(Inventory inventory)
+        {
+            var stats = await inventory.GetPlayerStats();
+            var output = string.Empty;
+            var stat = stats.FirstOrDefault();
+            if (stat != null)
+            {
+                var ep = (stat.NextLevelXp - stat.PrevLevelXp) - (stat.Experience - stat.PrevLevelXp);
+                var hours = Math.Round(ep/(TotalExperience / _getSessionRuntime()), 2);
+
+                output = $"{stat.Level} (LvLUp in {hours}hours | {stat.Experience - stat.PrevLevelXp - GetXpDiff(stat.Level)}/{stat.NextLevelXp - stat.PrevLevelXp - GetXpDiff(stat.Level)} XP)";
+                //output = $"{stat.Level} (LvLUp in {_hours}hours // EXP required: {_ep})";
+            }
+            return output;
+        }
+
+        public static string GetUsername(Client client, GetPlayerResponse profile)
+        {
+            return PlayerName = client.Settings.AuthType == AuthType.Ptc ? client.Settings.PtcUsername : profile.Profile.Username;
+        }
+
+        public static double _getSessionRuntime()
+        {
+            return (DateTime.Now - InitSessionDateTime).TotalSeconds/3600;
+        }
+
+        public static string _getSessionRuntimeInTimeFormat()
+        {
+            return (DateTime.Now - InitSessionDateTime).ToString(@"dd\.hh\:mm\:ss");
+        }
+
+        public void AddExperience(int xp)
+        {
+            TotalExperience += xp;
+        }
+
+        public void AddItemsRemoved(int count)
+        {
+            TotalItemsRemoved += count;
+        }
+
+        public void GetStardust(int stardust)
+        {
+            TotalStardust = stardust;
+        }
+
+        public void IncreasePokemons()
+        {
+            TotalPokemons += 1;
+        }
+
+        public void IncreasePokemonsTransfered()
+        {
+            TotalPokemonsTransfered += 1;
+        }
+
+        public async void UpdateConsoleTitle(Inventory _inventory)
+        {
+            CurrentLevelInfos = await _getcurrentLevelInfos(_inventory);
+            Console.Title = ToString();
+        }
+
+        public override string ToString()
+        {
+            return
+                string.Format(
+                    "{0} - Runtime {1} - Lvl: {2:0} | EXP/H: {3:0} | P/H: {4:0} | Stardust: {5:0} | Transfered: {6:0} | Items Recycled: {7:0}",
+                    PlayerName, _getSessionRuntimeInTimeFormat(), CurrentLevelInfos, TotalExperience / _getSessionRuntime(),
+                    TotalPokemons / _getSessionRuntime(), TotalStardust, TotalPokemonsTransfered, TotalItemsRemoved);
+        }
+
+        public static int GetXpDiff(int level)
+        {
+            switch (level)
+            {
+                case 1:
+                    return 0;
+                case 2:
+                    return 1000;
+                case 3:
+                    return 2000;
+                case 4:
+                    return 3000;
+                case 5:
+                    return 4000;
+                case 6:
+                    return 5000;
+                case 7:
+                    return 6000;
+                case 8:
+                    return 7000;
+                case 9:
+                    return 8000;
+                case 10:
+                    return 9000;
+                case 11:
+                    return 10000;
+                case 12:
+                    return 10000;
+                case 13:
+                    return 10000;
+                case 14:
+                    return 10000;
+                case 15:
+                    return 15000;
+                case 16:
+                    return 20000;
+                case 17:
+                    return 20000;
+                case 18:
+                    return 20000;
+                case 19:
+                    return 25000;
+                case 20:
+                    return 25000;
+                case 21:
+                    return 50000;
+                case 22:
+                    return 75000;
+                case 23:
+                    return 100000;
+                case 24:
+                    return 125000;
+                case 25:
+                    return 150000;
+                case 26:
+                    return 190000;
+                case 27:
+                    return 200000;
+                case 28:
+                    return 250000;
+                case 29:
+                    return 300000;
+                case 30:
+                    return 350000;
+                case 31:
+                    return 500000;
+                case 32:
+                    return 500000;
+                case 33:
+                    return 750000;
+                case 34:
+                    return 1000000;
+                case 35:
+                    return 1250000;
+                case 36:
+                    return 1500000;
+                case 37:
+                    return 2000000;
+                case 38:
+                    return 2500000;
+                case 39:
+                    return 1000000;
+                case 40:
+                    return 1000000;
+            }
+            return 0;
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Client.cs b/PokemonGo.RocketAPI/Client.cs
index 8060b4d..330c0ee 100644
--- a/PokemonGo.RocketAPI/Client.cs
+++ b/PokemonGo.RocketAPI/Client.cs
@@ -1,469 +1,469 @@
-#region
-
-using System;
-using System.IO;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-using Google.Protobuf;
-using PokemonGo.RocketAPI.Enums;
-using PokemonGo.RocketAPI.Exceptions;
-using PokemonGo.RocketAPI.Extensions;
-using PokemonGo.RocketAPI.GeneratedCode;
-using PokemonGo.RocketAPI.Helpers;
-using PokemonGo.RocketAPI.Login;
-using static PokemonGo.RocketAPI.GeneratedCode.Response.Types;
-using PokemonGo.RocketAPI.Logging;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI
-{
-    public class Client
-    {
-        private readonly HttpClient _httpClient;
-        private string _apiUrl;
-        private AuthType _authType = AuthType.Google;
-        private Request.Types.UnknownAuth _unknownAuth;
-        Random rand = null;
-
-        public Client(ISettings settings)
-        {
-            Settings = settings;
-
-            string path = Directory.GetCurrentDirectory() + "\\Configs\\";
-            if (!Directory.Exists(path))
-            {
-                DirectoryInfo di = Directory.CreateDirectory(path);
-            }
-            string filename = "LastCoords.ini";
-            if (File.Exists(path + filename) && File.ReadAllText(path + filename).Contains(":"))
-            {
-                var latlngFromFile = File.ReadAllText(path + filename);
-                var latlng = latlngFromFile.Split(':');
-                if (latlng[0].Length != 0 && latlng[1].Length != 0)
-                {
-                    try
-                    {
-                        double temp_lat = Convert.ToDouble(latlng[0]);
-                        double temp_long = Convert.ToDouble(latlng[1]);
-
-                        if (temp_lat >= -90 && temp_lat <= 90 && temp_long >= -180 && temp_long <= 180)
-                        {
-                            SetCoordinates(Convert.ToDouble(latlng[0]), Convert.ToDouble(latlng[1]),
-                            Settings.DefaultAltitude);
-                        }
-                        else
-                        {
-                            Logger.Write("Coordinates in \"\\Configs\\Coords.ini\" file is invalid, using the default coordinates", LogLevel.Error);
-                            SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
-                        }
-                    }
-                    catch (FormatException)
-                    {
-                        Logger.Write("Coordinates in \"\\Configs\\Coords.ini\" file is invalid, using the default coordinates", LogLevel.Error);
-                        SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
-                    }
-                }
-                else
-                {
-                    SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
-                }
-            }
-            else
-            {
-                Logger.Write("Missing \"\\Configs\\Coords.ini\", using default settings for coordinates and create a new one...");
-                SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
-            }
-
-            //Setup HttpClient and create default headers
-            var handler = new HttpClientHandler
-            {
-                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
-                AllowAutoRedirect = false
-            };
-            _httpClient = new HttpClient(new RetryHandler(handler));
-            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Niantic App");
-            //"Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G900F Build/LMY48G)");
-            _httpClient.DefaultRequestHeaders.ExpectContinue = false;
-            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Connection", "keep-alive");
-            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "*/*");
-            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type",
-                "application/x-www-form-urlencoded");
-        }
-
-        public ISettings Settings { get; }
-        public string AccessToken { get; set; }
-
-        public double CurrentLat { get; private set; }
-        public double CurrentLng { get; private set; }
-        public double CurrentAltitude { get; private set; }
-
-        public async Task<CatchPokemonResponse> CatchPokemon(ulong encounterId, string spawnPointGuid, double pokemonLat,
-    double pokemonLng, MiscEnums.Item pokeball)
-        {
-
-            var customRequest = new Request.Types.CatchPokemonRequest
-            {
-                EncounterId = encounterId,
-                Pokeball = (int)pokeball,
-                SpawnPointGuid = spawnPointGuid,
-                HitPokemon = 1,
-                NormalizedReticleSize = Utils.FloatAsUlong(1.950),
-                SpinModifier = Utils.FloatAsUlong(1),
-                NormalizedHitPosition = Utils.FloatAsUlong(1)
-            };
-
-            var catchPokemonRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.CATCH_POKEMON,
-                    Message = customRequest.ToByteString()
-                });
-            return
-                await
-                    _httpClient.PostProtoPayload<Request, CatchPokemonResponse>($"https://{_apiUrl}/rpc", catchPokemonRequest);
-        }
-
-        public async Task DoGoogleLogin(string filename)
-        {
-            _authType = AuthType.Google;
-
-            string googleRefreshToken = string.Empty;
-            string path = Directory.GetCurrentDirectory() + "\\Configs\\";
-            if (!Directory.Exists(path))
-            {
-                DirectoryInfo di = Directory.CreateDirectory(path);
-            }
-            if (File.Exists(path + filename))
-            {
-                googleRefreshToken = File.ReadAllText(path + filename);
-            }
-
-            GoogleLogin.TokenResponseModel tokenResponse;
-            if (googleRefreshToken != string.Empty)
-            {
-                tokenResponse = await GoogleLogin.GetAccessToken(googleRefreshToken);
-                AccessToken = tokenResponse?.id_token;
-            }
-
-            if (AccessToken == null)
-            {
-                var deviceCode = await GoogleLogin.GetDeviceCode();
-                tokenResponse = await GoogleLogin.GetAccessToken(deviceCode);
-                googleRefreshToken = tokenResponse?.refresh_token;
-                Logger.Write("Refreshtoken " + tokenResponse?.refresh_token + " saved", LogLevel.Info);
-                File.WriteAllText(path + filename, googleRefreshToken);
-                AccessToken = tokenResponse?.id_token;
-            }
-
-        }
-
-        public async Task DoPtcLogin(string username, string password)
-        {
-            AccessToken = await PtcLogin.GetAccessToken(username, password);
-            _authType = AuthType.Ptc;
-        }
-
-        public async Task<EncounterResponse> EncounterPokemon(ulong encounterId, string spawnPointGuid)
-        {
-            var customRequest = new Request.Types.EncounterRequest
-            {
-                EncounterId = encounterId,
-                SpawnpointId = spawnPointGuid,
-                PlayerLatDegrees = Utils.FloatAsUlong(CurrentLat),
-                PlayerLngDegrees = Utils.FloatAsUlong(CurrentLng)
-            };
-
-            var encounterResponse = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.ENCOUNTER,
-                    Message = customRequest.ToByteString()
-                });
-            return await _httpClient.PostProtoPayload<Request, EncounterResponse>($"https://{_apiUrl}/rpc", encounterResponse);
-        }
-
-        public async Task<EvolvePokemonOut> EvolvePokemon(ulong pokemonId)
-        {
-            var customRequest = new EvolvePokemon
-            {
-                PokemonId = pokemonId
-            };
-
-            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.EVOLVE_POKEMON,
-                    Message = customRequest.ToByteString()
-                });
-            return
-                await
-                    _httpClient.PostProtoPayload<Request, EvolvePokemonOut>($"https://{_apiUrl}/rpc", releasePokemonRequest);
-        }
-
-        public async Task<FortDetailsResponse> GetFort(string fortId, double fortLat, double fortLng)
-        {
-            var customRequest = new Request.Types.FortDetailsRequest
-            {
-                Id = ByteString.CopyFromUtf8(fortId),
-                Latitude = Utils.FloatAsUlong(fortLat),
-                Longitude = Utils.FloatAsUlong(fortLng)
-            };
-
-            var fortDetailRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.FORT_DETAILS,
-                    Message = customRequest.ToByteString()
-                });
-            return
-                await
-                    _httpClient.PostProtoPayload<Request, FortDetailsResponse>($"https://{_apiUrl}/rpc",
-                        fortDetailRequest);
-        }
-
-        public async Task<GetInventoryResponse> GetInventory()
-        {
-            var inventoryRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude, RequestType.GET_INVENTORY);
-            return await _httpClient.PostProtoPayload<Request, GetInventoryResponse>($"https://{_apiUrl}/rpc", inventoryRequest);
-        }
-
-        public async Task<DownloadItemTemplatesResponse> GetItemTemplates()
-        {
-            var settingsRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                RequestType.DOWNLOAD_ITEM_TEMPLATES);
-            return
-                await
-                    _httpClient.PostProtoPayload<Request, DownloadItemTemplatesResponse>($"https://{_apiUrl}/rpc",
-                        settingsRequest);
-        }
-
-        public async Task<GetMapObjectsResponse> GetMapObjects()
-        {
-            var customRequest = new Request.Types.MapObjectsRequest
-            {
-                CellIds =
-                    ByteString.CopyFrom(
-                        ProtoHelper.EncodeUlongList(S2Helper.GetNearbyCellIds(CurrentLng,
-                            CurrentLat))),
-                Latitude = Utils.FloatAsUlong(CurrentLat),
-                Longitude = Utils.FloatAsUlong(CurrentLng),
-                Unknown14 = ByteString.CopyFromUtf8("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
-            };
-
-            var mapRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.GET_MAP_OBJECTS,
-                    Message = customRequest.ToByteString()
-                },
-                new Request.Types.Requests { Type = (int)RequestType.GET_HATCHED_OBJECTS },
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.GET_INVENTORY,
-                    Message = new Request.Types.Time() {Time_ = DateTime.UtcNow.ToUnixTime()}.ToByteString()
-                },
-                new Request.Types.Requests() { Type = (int)RequestType.CHECK_AWARDED_BADGES },
-                new Request.Types.Requests()
-                {
-                    Type = (int)RequestType.DOWNLOAD_SETTINGS,
-                    Message =
-                        new Request.Types.SettingsGuid
-                        {
-                            Guid = ByteString.CopyFromUtf8("4a2e9bc330dae60e7b74fc85b98868ab4700802e")
-                        }.ToByteString()
-                });
-
-            return await _httpClient.PostProtoPayload<Request, GetMapObjectsResponse>($"https://{_apiUrl}/rpc", mapRequest);
-        }
-
-        public async Task<GetPlayerResponse> GetProfile()
-        {
-            var profileRequest = RequestBuilder.GetInitialRequest(AccessToken, _authType, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests { Type = (int)RequestType.GET_PLAYER });
-            return await _httpClient.PostProtoPayload<Request, GetPlayerResponse>($"https://{_apiUrl}/rpc", profileRequest);
-        }
-
-        public async Task<DownloadSettingsResponse> GetSettings()
-        {
-            var settingsRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                RequestType.DOWNLOAD_SETTINGS);
-            return await _httpClient.PostProtoPayload<Request, DownloadSettingsResponse>($"https://{_apiUrl}/rpc", settingsRequest);
-        }
-
-        public async Task<RecycleInventoryItemResponse> RecycleItem(ItemId itemId, int amount)
-        {
-            var customRequest = new RecycleInventoryItem
-            {
-                ItemId = (ItemId)Enum.Parse(typeof(ItemId), itemId.ToString()),
-                Count = amount
-            };
-
-            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.RECYCLE_INVENTORY_ITEM,
-                    Message = customRequest.ToByteString()
-                });
-            return await _httpClient.PostProtoPayload<Request, RecycleInventoryItemResponse>($"https://{_apiUrl}/rpc", releasePokemonRequest);
-        }
-
-        public void SaveLatLng(double lat, double lng)
-        {
-            var latlng = lat + ":" + lng;
-            File.WriteAllText(Directory.GetCurrentDirectory() + "\\Configs\\LastCoords.ini", latlng);
-        }
-
-        public async Task<FortSearchResponse> SearchFort(string fortId, double fortLat, double fortLng)
-        {
-            var customRequest = new Request.Types.FortSearchRequest
-            {
-                Id = ByteString.CopyFromUtf8(fortId),
-                FortLatDegrees = Utils.FloatAsUlong(fortLat),
-                FortLngDegrees = Utils.FloatAsUlong(fortLng),
-                PlayerLatDegrees = Utils.FloatAsUlong(CurrentLat),
-                PlayerLngDegrees = Utils.FloatAsUlong(CurrentLng)
-            };
-
-            var fortDetailRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.FORT_SEARCH,
-                    Message = customRequest.ToByteString()
-                });
-            return
-                await
-                    _httpClient.PostProtoPayload<Request, FortSearchResponse>($"https://{_apiUrl}/rpc",
-                        fortDetailRequest);
-        }
-
-        /// <summary>
-        /// For GUI clients only. GUI clients don't use the DoGoogleLogin, but call the GoogleLogin class directly
-        /// </summary>
-        /// <param name="type"></param>
-        public void SetAuthType(AuthType type)
-        {
-            _authType = type;
-        }
-
-        private void CalcNoisedCoordinates(double lat, double lng, out double latNoise, out double lngNoise)
-        {
-            double mean = 0.0;// just for fun
-            double stdDev = 2.09513120352; //-> so 50% of the noised coordinates will have a maximal distance of 4 m to orginal ones
-
-            if (rand == null)
-            {
-                rand = new Random();
-            }
-            double u1 = rand.NextDouble();
-            double u2 = rand.NextDouble();
-            double u3 = rand.NextDouble();
-            double u4 = rand.NextDouble();
-
-            double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2);
-            double randNormal = mean + stdDev * randStdNormal;
-            double randStdNormal2 = Math.Sqrt(-2.0 * Math.Log(u3)) * Math.Sin(2.0 * Math.PI * u4);
-            double randNormal2 = mean + stdDev * randStdNormal2;
-
-            latNoise = lat + randNormal / 100000.0;
-            lngNoise = lng + randNormal2 / 100000.0;
-        }
-
-        private void SetCoordinates(double lat, double lng, double altitude)
-        {
-            if (double.IsNaN(lat) || double.IsNaN(lng)) return;
-
-            double latNoised = 0.0;
-            double lngNoised = 0.0;
-            CalcNoisedCoordinates(lat, lng, out latNoised, out lngNoised);
-            CurrentLat = latNoised;
-            CurrentLng = lngNoised;
-            CurrentAltitude = altitude;
-            SaveLatLng(lat, lng);
-        }
-
-        public async Task SetServer()
-        {
-            var serverRequest = RequestBuilder.GetInitialRequest(AccessToken, _authType, CurrentLat, CurrentLng, CurrentAltitude,
-                RequestType.GET_PLAYER, RequestType.GET_HATCHED_OBJECTS, RequestType.GET_INVENTORY,
-                RequestType.CHECK_AWARDED_BADGES, RequestType.DOWNLOAD_SETTINGS);
-            var serverResponse = await _httpClient.PostProto(Resources.RpcUrl, serverRequest);
-
-            if (serverResponse.Auth == null)
-                throw new AccessTokenExpiredException();
-
-            _unknownAuth = new Request.Types.UnknownAuth
-            {
-                Unknown71 = serverResponse.Auth.Unknown71,
-                Timestamp = serverResponse.Auth.Timestamp,
-                Unknown73 = serverResponse.Auth.Unknown73
-            };
-
-            _apiUrl = serverResponse.ApiUrl;
-        }
-
-        public async Task RepeatAction(int repeat, Func<Task> action)
-        {
-            for (int i = 0; i < repeat; i++)
-                await action();
-        }
-
-        public async Task<TransferPokemonOut> TransferPokemon(ulong pokemonId)
-        {
-            var customRequest = new TransferPokemon
-            {
-                PokemonId = pokemonId
-            };
-
-            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.RELEASE_POKEMON,
-                    Message = customRequest.ToByteString()
-                });
-            return await _httpClient.PostProtoPayload<Request, TransferPokemonOut>($"https://{_apiUrl}/rpc", releasePokemonRequest);
-        }
-
-        public async Task<PlayerUpdateResponse> UpdatePlayerLocation(double lat, double lng, double alt)
-        {
-            SetCoordinates(lat, lng, alt);
-            var customRequest = new Request.Types.PlayerUpdateProto
-            {
-                Lat = Utils.FloatAsUlong(CurrentLat),
-                Lng = Utils.FloatAsUlong(CurrentLng)
-            };
-
-            var updateRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.PLAYER_UPDATE,
-                    Message = customRequest.ToByteString()
-                });
-            var updateResponse =
-                await
-                    _httpClient.PostProtoPayload<Request, PlayerUpdateResponse>($"https://{_apiUrl}/rpc", updateRequest);
-            return updateResponse;
-        }
-
-        public async Task<UseItemCaptureRequest> UseCaptureItem(ulong encounterId, ItemId itemId, string spawnPointGuid)
-        {
-            var customRequest = new UseItemCaptureRequest
-            {
-                EncounterId = encounterId,
-                ItemId = itemId,
-                SpawnPointGuid = spawnPointGuid
-            };
-
-            var useItemRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
-                new Request.Types.Requests
-                {
-                    Type = (int)RequestType.USE_ITEM_CAPTURE,
-                    Message = customRequest.ToByteString()
-                });
-            return await _httpClient.PostProtoPayload<Request, UseItemCaptureRequest>($"https://{_apiUrl}/rpc", useItemRequest);
-        }
-
-    }
-}
+#region
+
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using PokemonGo.RocketAPI.Enums;
+using PokemonGo.RocketAPI.Exceptions;
+using PokemonGo.RocketAPI.Extensions;
+using PokemonGo.RocketAPI.GeneratedCode;
+using PokemonGo.RocketAPI.Helpers;
+using PokemonGo.RocketAPI.Login;
+using static PokemonGo.RocketAPI.GeneratedCode.Response.Types;
+using PokemonGo.RocketAPI.Logging;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI
+{
+    public class Client
+    {
+        private readonly HttpClient _httpClient;
+        private string _apiUrl;
+        private AuthType _authType = AuthType.Google;
+        private Request.Types.UnknownAuth _unknownAuth;
+        Random rand = null;
+
+        public Client(ISettings settings)
+        {
+            Settings = settings;
+
+            string path = Directory.GetCurrentDirectory() + "\\Configs\\";
+            if (!Directory.Exists(path))
+            {
+                DirectoryInfo di = Directory.CreateDirectory(path);
+            }
+            string filename = "LastCoords.ini";
+            if (File.Exists(path + filename) && File.ReadAllText(path + filename).Contains(":"))
+            {
+                var latlngFromFile = File.ReadAllText(path + filename);
+                var latlng = latlngFromFile.Split(':');
+                if (latlng[0].Length != 0 && latlng[1].Length != 0)
+                {
+                    try
+                    {
+                        double temp_lat = Convert.ToDouble(latlng[0]);
+                        double temp_long = Convert.ToDouble(latlng[1]);
+
+                        if (temp_lat >= -90 && temp_lat <= 90 && temp_long >= -180 && temp_long <= 180)
+                        {
+                            SetCoordinates(Convert.ToDouble(latlng[0]), Convert.ToDouble(latlng[1]),
+                            Settings.DefaultAltitude);
+                        }
+                        else
+                        {
+                            Logger.Write("Coordinates in \"\\Configs\\Coords.ini\" file is invalid, using the default coordinates", LogLevel.Error);
+                            SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
+                        }
+                    }
+                    catch (FormatException)
+                    {
+                        Logger.Write("Coordinates in \"\\Configs\\Coords.ini\" file is invalid, using the default coordinates", LogLevel.Error);
+                        SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
+                    }
+                }
+                else
+                {
+                    SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
+                }
+            }
+            else
+            {
+                Logger.Write("Missing \"\\Configs\\Coords.ini\", using default settings for coordinates and create a new one...");
+                SetCoordinates(Settings.DefaultLatitude, Settings.DefaultLongitude, Settings.DefaultAltitude);
+            }
+
+            //Setup HttpClient and create default headers
+            var handler = new HttpClientHandler
+            {
+                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
+                AllowAutoRedirect = false
+            };
+            _httpClient = new HttpClient(new RetryHandler(handler));
+            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", "Niantic App");
+            //"Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G900F Build/LMY48G)");
+            _httpClient.DefaultRequestHeaders.ExpectContinue = false;
+            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Connection", "keep-alive");
+            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "*/*");
+            _httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type",
+                "application/x-www-form-urlencoded");
+        }
+
+        public ISettings Settings { get; }
+        public string AccessToken { get; set; }
+
+        public double CurrentLat { get; private set; }
+        public double CurrentLng { get; private set; }
+        public double CurrentAltitude { get; private set; }
+
+        public async Task<CatchPokemonResponse> CatchPokemon(ulong encounterId, string spawnPointGuid, double pokemonLat,
+    double pokemonLng, MiscEnums.Item pokeball)
+        {
+
+            var customRequest = new Request.Types.CatchPokemonRequest
+            {
+                EncounterId = encounterId,
+                Pokeball = (int)pokeball,
+                SpawnPointGuid = spawnPointGuid,
+                HitPokemon = 1,
+                NormalizedReticleSize = Utils.FloatAsUlong(1.950),
+                SpinModifier = Utils.FloatAsUlong(1),
+                NormalizedHitPosition = Utils.FloatAsUlong(1)
+            };
+
+            var catchPokemonRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.CATCH_POKEMON,
+                    Message = customRequest.ToByteString()
+                });
+            return
+                await
+                    _httpClient.PostProtoPayload<Request, CatchPokemonResponse>($"https://{_apiUrl}/rpc", catchPokemonRequest);
+        }
+
+        public async Task DoGoogleLogin(string filename)
+        {
+            _authType = AuthType.Google;
+
+            string googleRefreshToken = string.Empty;
+            string path = Directory.GetCurrentDirectory() + "\\Configs\\";
+            if (!Directory.Exists(path))
+            {
+                DirectoryInfo di = Directory.CreateDirectory(path);
+            }
+            if (File.Exists(path + filename))
+            {
+                googleRefreshToken = File.ReadAllText(path + filename);
+            }
+
+            GoogleLogin.TokenResponseModel tokenResponse;
+            if (googleRefreshToken != string.Empty)
+            {
+                tokenResponse = await GoogleLogin.GetAccessToken(googleRefreshToken);
+                AccessToken = tokenResponse?.id_token;
+            }
+
+            if (AccessToken == null)
+            {
+                var deviceCode = await GoogleLogin.GetDeviceCode();
+                tokenResponse = await GoogleLogin.GetAccessToken(deviceCode);
+                googleRefreshToken = tokenResponse?.refresh_token;
+                Logger.Write("Refreshtoken " + tokenResponse?.refresh_token + " saved", LogLevel.Info);
+                File.WriteAllText(path + filename, googleRefreshToken);
+                AccessToken = tokenResponse?.id_token;
+            }
+
+        }
+
+        public async Task DoPtcLogin(string username, string password)
+        {
+            AccessToken = await PtcLogin.GetAccessToken(username, password);
+            _authType = AuthType.Ptc;
+        }
+
+        public async Task<EncounterResponse> EncounterPokemon(ulong encounterId, string spawnPointGuid)
+        {
+            var customRequest = new Request.Types.EncounterRequest
+            {
+                EncounterId = encounterId,
+                SpawnpointId = spawnPointGuid,
+                PlayerLatDegrees = Utils.FloatAsUlong(CurrentLat),
+                PlayerLngDegrees = Utils.FloatAsUlong(CurrentLng)
+            };
+
+            var encounterResponse = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.ENCOUNTER,
+                    Message = customRequest.ToByteString()
+                });
+            return await _httpClient.PostProtoPayload<Request, EncounterResponse>($"https://{_apiUrl}/rpc", encounterResponse);
+        }
+
+        public async Task<EvolvePokemonOut> EvolvePokemon(ulong pokemonId)
+        {
+            var customRequest = new EvolvePokemon
+            {
+                PokemonId = pokemonId
+            };
+
+            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.EVOLVE_POKEMON,
+                    Message = customRequest.ToByteString()
+                });
+            return
+                await
+                    _httpClient.PostProtoPayload<Request, EvolvePokemonOut>($"https://{_apiUrl}/rpc", releasePokemonRequest);
+        }
+
+        public async Task<FortDetailsResponse> GetFort(string fortId, double fortLat, double fortLng)
+        {
+            var customRequest = new Request.Types.FortDetailsRequest
+            {
+                Id = ByteString.CopyFromUtf8(fortId),
+                Latitude = Utils.FloatAsUlong(fortLat),
+                Longitude = Utils.FloatAsUlong(fortLng)
+            };
+
+            var fortDetailRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.FORT_DETAILS,
+                    Message = customRequest.ToByteString()
+                });
+            return
+                await
+                    _httpClient.PostProtoPayload<Request, FortDetailsResponse>($"https://{_apiUrl}/rpc",
+                        fortDetailRequest);
+        }
+
+        public async Task<GetInventoryResponse> GetInventory()
+        {
+            var inventoryRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude, RequestType.GET_INVENTORY);
+            return await _httpClient.PostProtoPayload<Request, GetInventoryResponse>($"https://{_apiUrl}/rpc", inventoryRequest);
+        }
+
+        public async Task<DownloadItemTemplatesResponse> GetItemTemplates()
+        {
+            var settingsRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                RequestType.DOWNLOAD_ITEM_TEMPLATES);
+            return
+                await
+                    _httpClient.PostProtoPayload<Request, DownloadItemTemplatesResponse>($"https://{_apiUrl}/rpc",
+                        settingsRequest);
+        }
+
+        public async Task<GetMapObjectsResponse> GetMapObjects()
+        {
+            var customRequest = new Request.Types.MapObjectsRequest
+            {
+                CellIds =
+                    ByteString.CopyFrom(
+                        ProtoHelper.EncodeUlongList(S2Helper.GetNearbyCellIds(CurrentLng,
+                            CurrentLat))),
+                Latitude = Utils.FloatAsUlong(CurrentLat),
+                Longitude = Utils.FloatAsUlong(CurrentLng),
+                Unknown14 = ByteString.CopyFromUtf8("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
+            };
+
+            var mapRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.GET_MAP_OBJECTS,
+                    Message = customRequest.ToByteString()
+                },
+                new Request.Types.Requests { Type = (int)RequestType.GET_HATCHED_OBJECTS },
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.GET_INVENTORY,
+                    Message = new Request.Types.Time() {Time_ = DateTime.UtcNow.ToUnixTime()}.ToByteString()
+                },
+                new Request.Types.Requests() { Type = (int)RequestType.CHECK_AWARDED_BADGES },
+                new Request.Types.Requests()
+                {
+                    Type = (int)RequestType.DOWNLOAD_SETTINGS,
+                    Message =
+                        new Request.Types.SettingsGuid
+                        {
+                            Guid = ByteString.CopyFromUtf8("4a2e9bc330dae60e7b74fc85b98868ab4700802e")
+                        }.ToByteString()
+                });
+
+            return await _httpClient.PostProtoPayload<Request, GetMapObjectsResponse>($"https://{_apiUrl}/rpc", mapRequest);
+        }
+
+        public async Task<GetPlayerResponse> GetProfile()
+        {
+            var profileRequest = RequestBuilder.GetInitialRequest(AccessToken, _authType, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests { Type = (int)RequestType.GET_PLAYER });
+            return await _httpClient.PostProtoPayload<Request, GetPlayerResponse>($"https://{_apiUrl}/rpc", profileRequest);
+        }
+
+        public async Task<DownloadSettingsResponse> GetSettings()
+        {
+            var settingsRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                RequestType.DOWNLOAD_SETTINGS);
+            return await _httpClient.PostProtoPayload<Request, DownloadSettingsResponse>($"https://{_apiUrl}/rpc", settingsRequest);
+        }
+
+        public async Task<RecycleInventoryItemResponse> RecycleItem(ItemId itemId, int amount)
+        {
+            var customRequest = new RecycleInventoryItem
+            {
+                ItemId = (ItemId)Enum.Parse(typeof(ItemId), itemId.ToString()),
+                Count = amount
+            };
+
+            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.RECYCLE_INVENTORY_ITEM,
+                    Message = customRequest.ToByteString()
+                });
+            return await _httpClient.PostProtoPayload<Request, RecycleInventoryItemResponse>($"https://{_apiUrl}/rpc", releasePokemonRequest);
+        }
+
+        public void SaveLatLng(double lat, double lng)
+        {
+            var latlng = lat + ":" + lng;
+            File.WriteAllText(Directory.GetCurrentDirectory() + "\\Configs\\LastCoords.ini", latlng);
+        }
+
+        public async Task<FortSearchResponse> SearchFort(string fortId, double fortLat, double fortLng)
+        {
+            var customRequest = new Request.Types.FortSearchRequest
+            {
+                Id = ByteString.CopyFromUtf8(fortId),
+                FortLatDegrees = Utils.FloatAsUlong(fortLat),
+                FortLngDegrees = Utils.FloatAsUlong(fortLng),
+                PlayerLatDegrees = Utils.FloatAsUlong(CurrentLat),
+                PlayerLngDegrees = Utils.FloatAsUlong(CurrentLng)
+            };
+
+            var fortDetailRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.FORT_SEARCH,
+                    Message = customRequest.ToByteString()
+                });
+            return
+                await
+                    _httpClient.PostProtoPayload<Request, FortSearchResponse>($"https://{_apiUrl}/rpc",
+                        fortDetailRequest);
+        }
+
+        /// <summary>
+        /// For GUI clients only. GUI clients don't use the DoGoogleLogin, but call the GoogleLogin class directly
+        /// </summary>
+        /// <param name="type"></param>
+        public void SetAuthType(AuthType type)
+        {
+            _authType = type;
+        }
+
+        private void CalcNoisedCoordinates(double lat, double lng, out double latNoise, out double lngNoise)
+        {
+            double mean = 0.0;// just for fun
+            double stdDev = 2.09513120352; //-> so 50% of the noised coordinates will have a maximal distance of 4 m to orginal ones
+
+            if (rand == null)
+            {
+                rand = new Random();
+            }
+            double u1 = rand.NextDouble();
+            double u2 = rand.NextDouble();
+            double u3 = rand.NextDouble();
+            double u4 = rand.NextDouble();
+
+            double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2);
+            double randNormal = mean + stdDev * randStdNormal;
+            double randStdNormal2 = Math.Sqrt(-2.0 * Math.Log(u3)) * Math.Sin(2.0 * Math.PI * u4);
+            double randNormal2 = mean + stdDev * randStdNormal2;
+
+            latNoise = lat + randNormal / 100000.0;
+            lngNoise = lng + randNormal2 / 100000.0;
+        }
+
+        private void SetCoordinates(double lat, double lng, double altitude)
+        {
+            if (double.IsNaN(lat) || double.IsNaN(lng)) return;
+
+            double latNoised = 0.0;
+            double lngNoised = 0.0;
+            CalcNoisedCoordinates(lat, lng, out latNoised, out lngNoised);
+            CurrentLat = latNoised;
+            CurrentLng = lngNoised;
+            CurrentAltitude = altitude;
+            SaveLatLng(lat, lng);
+        }
+
+        public async Task SetServer()
+        {
+            var serverRequest = RequestBuilder.GetInitialRequest(AccessToken, _authType, CurrentLat, CurrentLng, CurrentAltitude,
+                RequestType.GET_PLAYER, RequestType.GET_HATCHED_OBJECTS, RequestType.GET_INVENTORY,
+                RequestType.CHECK_AWARDED_BADGES, RequestType.DOWNLOAD_SETTINGS);
+            var serverResponse = await _httpClient.PostProto(Resources.RpcUrl, serverRequest);
+
+            if (serverResponse.Auth == null)
+                throw new AccessTokenExpiredException();
+
+            _unknownAuth = new Request.Types.UnknownAuth
+            {
+                Unknown71 = serverResponse.Auth.Unknown71,
+                Timestamp = serverResponse.Auth.Timestamp,
+                Unknown73 = serverResponse.Auth.Unknown73
+            };
+
+            _apiUrl = serverResponse.ApiUrl;
+        }
+
+        public async Task RepeatAction(int repeat, Func<Task> action)
+        {
+            for (int i = 0; i < repeat; i++)
+                await action();
+        }
+
+        public async Task<TransferPokemonOut> TransferPokemon(ulong pokemonId)
+        {
+            var customRequest = new TransferPokemon
+            {
+                PokemonId = pokemonId
+            };
+
+            var releasePokemonRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.RELEASE_POKEMON,
+                    Message = customRequest.ToByteString()
+                });
+            return await _httpClient.PostProtoPayload<Request, TransferPokemonOut>($"https://{_apiUrl}/rpc", releasePokemonRequest);
+        }
+
+        public async Task<PlayerUpdateResponse> UpdatePlayerLocation(double lat, double lng, double alt)
+        {
+            SetCoordinates(lat, lng, alt);
+            var customRequest = new Request.Types.PlayerUpdateProto
+            {
+                Lat = Utils.FloatAsUlong(CurrentLat),
+                Lng = Utils.FloatAsUlong(CurrentLng)
+            };
+
+            var updateRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.PLAYER_UPDATE,
+                    Message = customRequest.ToByteString()
+                });
+            var updateResponse =
+                await
+                    _httpClient.PostProtoPayload<Request, PlayerUpdateResponse>($"https://{_apiUrl}/rpc", updateRequest);
+            return updateResponse;
+        }
+
+        public async Task<UseItemCaptureRequest> UseCaptureItem(ulong encounterId, ItemId itemId, string spawnPointGuid)
+        {
+            var customRequest = new UseItemCaptureRequest
+            {
+                EncounterId = encounterId,
+                ItemId = itemId,
+                SpawnPointGuid = spawnPointGuid
+            };
+
+            var useItemRequest = RequestBuilder.GetRequest(_unknownAuth, CurrentLat, CurrentLng, CurrentAltitude,
+                new Request.Types.Requests
+                {
+                    Type = (int)RequestType.USE_ITEM_CAPTURE,
+                    Message = customRequest.ToByteString()
+                });
+            return await _httpClient.PostProtoPayload<Request, UseItemCaptureRequest>($"https://{_apiUrl}/rpc", useItemRequest);
+        }
+
+    }
+}
diff --git a/PokemonGo.RocketAPI/Extensions/HttpClientExtensions.cs b/PokemonGo.RocketAPI/Extensions/HttpClientExtensions.cs
index d40e1a5..8d1eff6 100644
--- a/PokemonGo.RocketAPI/Extensions/HttpClientExtensions.cs
+++ b/PokemonGo.RocketAPI/Extensions/HttpClientExtensions.cs
@@ -5,10 +5,10 @@ using System.Threading.Tasks;
 using Google.Protobuf;
 using PokemonGo.RocketAPI.Exceptions;
 using PokemonGo.RocketAPI.GeneratedCode;
-using PokemonGo.RocketAPI.Logging;
-
+using PokemonGo.RocketAPI.Logging;
+
 #endregion
-
+
 namespace PokemonGo.RocketAPI.Extensions
 {
     public static class HttpClientExtensions
diff --git a/PokemonGo.RocketAPI/Helpers/Git.cs b/PokemonGo.RocketAPI/Helpers/Git.cs
index e42b1ab..0630382 100644
--- a/PokemonGo.RocketAPI/Helpers/Git.cs
+++ b/PokemonGo.RocketAPI/Helpers/Git.cs
@@ -1,56 +1,56 @@
-#region
-
-using PokemonGo.RocketAPI.Logging;
-using System;
-using System.Net;
-using System.Reflection;
-using System.Text.RegularExpressions;
-using System.Threading;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Helpers
-{
-    public static class Git
-    {
-        public static void CheckVersion()
-        {
-            try
-            {
-                var match =
-                    new Regex(
-                        @"\[assembly\: AssemblyVersion\(""(\d{1,})\.(\d{1,})\.(\d{1,})\.(\d{1,})""\)\]")
-                        .Match(DownloadServerVersion());
-
-                if (!match.Success) return;
-                var gitVersion =
-                    new Version(
-                        $"{match.Groups[1]}.{match.Groups[2]}.{match.Groups[3]}.{match.Groups[4]}");
-                if (gitVersion <= Assembly.GetExecutingAssembly().GetName().Version)
-                {
-                    Logger.Write(
-                        "Awesome! You have already got the newest version! " +
-                        Assembly.GetExecutingAssembly().GetName().Version, LogLevel.Info);
-                    return;
-                }
-
-                Logger.Write("There is a new Version available: https://github.com/Spegeli/Pokemon-Go-Rocket-API", LogLevel.Info);
-                Thread.Sleep(1000);
-            }
-            catch (Exception)
-            {
-                // ignored
-            }
-        }
-
-        private static string DownloadServerVersion()
-        {
-            //test
-            using (var wC = new WebClient())
-                return
-                    wC.DownloadString(
-                        "https://raw.githubusercontent.com/Spegeli/Pokemon-Go-Rocket-API/master/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs");
-        }
-    }
+#region
+
+using PokemonGo.RocketAPI.Logging;
+using System;
+using System.Net;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Threading;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI.Helpers
+{
+    public static class Git
+    {
+        public static void CheckVersion()
+        {
+            try
+            {
+                var match =
+                    new Regex(
+                        @"\[assembly\: AssemblyVersion\(""(\d{1,})\.(\d{1,})\.(\d{1,})\.(\d{1,})""\)\]")
+                        .Match(DownloadServerVersion());
+
+                if (!match.Success) return;
+                var gitVersion =
+                    new Version(
+                        $"{match.Groups[1]}.{match.Groups[2]}.{match.Groups[3]}.{match.Groups[4]}");
+                if (gitVersion <= Assembly.GetExecutingAssembly().GetName().Version)
+                {
+                    Logger.Write(
+                        "Awesome! You have already got the newest version! " +
+                        Assembly.GetExecutingAssembly().GetName().Version, LogLevel.Info);
+                    return;
+                }
+
+                Logger.Write("There is a new Version available: https://github.com/Spegeli/Pokemon-Go-Rocket-API", LogLevel.Info);
+                Thread.Sleep(1000);
+            }
+            catch (Exception)
+            {
+                // ignored
+            }
+        }
+
+        private static string DownloadServerVersion()
+        {
+            //test
+            using (var wC = new WebClient())
+                return
+                    wC.DownloadString(
+                        "https://raw.githubusercontent.com/Spegeli/Pokemon-Go-Rocket-API/master/PokemonGo.RocketAPI/Properties/AssemblyInfo.cs");
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Helpers/RandomHelper.cs b/PokemonGo.RocketAPI/Helpers/RandomHelper.cs
index 2705ea6..1639092 100644
--- a/PokemonGo.RocketAPI/Helpers/RandomHelper.cs
+++ b/PokemonGo.RocketAPI/Helpers/RandomHelper.cs
@@ -1,40 +1,40 @@
-#region
-
-using System;
-using System.Threading.Tasks;
-
-#endregion
-
-namespace PokemonGo.RocketAPI.Helpers
-{
-    public class RandomHelper
-    {
-        private static readonly Random _random = new Random();
-        private static readonly Random _rng = new Random();
-
-        public static long GetLongRandom(long min, long max)
-        {
-            var buf = new byte[8];
-            _random.NextBytes(buf);
-            var longRand = BitConverter.ToInt64(buf, 0);
-
-            return Math.Abs(longRand%(max - min)) + min;
-        }
-
-        public static async Task RandomDelay(int maxDelay = 5000)
-        {
-            await Task.Delay(_rng.Next((maxDelay > 500) ? 500 : 0, maxDelay));
-        }
-
-        public static async Task RandomDelay(int min, int max)
-        {
-            await Task.Delay(_rng.Next(min, max));
-        }
-
-        public static int RandomNumber(int min, int max)
-        {
-            Random random = new Random();
-            return random.Next(min, max);
-        }
-    }
+#region
+
+using System;
+using System.Threading.Tasks;
+
+#endregion
+
+namespace PokemonGo.RocketAPI.Helpers
+{
+    public class RandomHelper
+    {
+        private static readonly Random _random = new Random();
+        private static readonly Random _rng = new Random();
+
+        public static long GetLongRandom(long min, long max)
+        {
+            var buf = new byte[8];
+            _random.NextBytes(buf);
+            var longRand = BitConverter.ToInt64(buf, 0);
+
+            return Math.Abs(longRand%(max - min)) + min;
+        }
+
+        public static async Task RandomDelay(int maxDelay = 5000)
+        {
+            await Task.Delay(_rng.Next((maxDelay > 500) ? 500 : 0, maxDelay));
+        }
+
+        public static async Task RandomDelay(int min, int max)
+        {
+            await Task.Delay(_rng.Next(min, max));
+        }
+
+        public static int RandomNumber(int min, int max)
+        {
+            Random random = new Random();
+            return random.Next(min, max);
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Helpers/RetryHandler.cs b/PokemonGo.RocketAPI/Helpers/RetryHandler.cs
index 68608f7..3063811 100644
--- a/PokemonGo.RocketAPI/Helpers/RetryHandler.cs
+++ b/PokemonGo.RocketAPI/Helpers/RetryHandler.cs
@@ -1,48 +1,48 @@
-#region
-
-using PokemonGo.RocketAPI.Logging;
-using System;
-using System.Net;
-using System.Net.Http;
-using System.Threading;
-using System.Threading.Tasks;
-
-#endregion
-
-namespace PokemonGo.RocketAPI.Helpers
-{
-    internal class RetryHandler : DelegatingHandler
-    {
-        private const int MaxRetries = 25;
-
-        public RetryHandler(HttpMessageHandler innerHandler)
-            : base(innerHandler)
-        {
-        }
-
-        protected override async Task<HttpResponseMessage> SendAsync(
-            HttpRequestMessage request,
-            CancellationToken cancellationToken)
-        {
-            for (var i = 0; i <= MaxRetries; i++)
-            {
-                try
-                {
-                    var response = await base.SendAsync(request, cancellationToken);
-                    if (response.StatusCode == HttpStatusCode.BadGateway)
-                        throw new Exception(); //todo: proper implementation
-
-                    return response;
-                }
-                catch (Exception ex)
-                {
-                    Logger.Write($"[#{i} of {MaxRetries}] retry request {request.RequestUri} - Error: {ex}",
-                        LogLevel.Warning);
-                    if (i >= MaxRetries) throw;
-                    await Task.Delay(1000, cancellationToken);
-                }
-            }
-            return null;
-        }
-    }
+#region
+
+using PokemonGo.RocketAPI.Logging;
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+
+#endregion
+
+namespace PokemonGo.RocketAPI.Helpers
+{
+    internal class RetryHandler : DelegatingHandler
+    {
+        private const int MaxRetries = 25;
+
+        public RetryHandler(HttpMessageHandler innerHandler)
+            : base(innerHandler)
+        {
+        }
+
+        protected override async Task<HttpResponseMessage> SendAsync(
+            HttpRequestMessage request,
+            CancellationToken cancellationToken)
+        {
+            for (var i = 0; i <= MaxRetries; i++)
+            {
+                try
+                {
+                    var response = await base.SendAsync(request, cancellationToken);
+                    if (response.StatusCode == HttpStatusCode.BadGateway)
+                        throw new Exception(); //todo: proper implementation
+
+                    return response;
+                }
+                catch (Exception ex)
+                {
+                    Logger.Write($"[#{i} of {MaxRetries}] retry request {request.RequestUri} - Error: {ex}",
+                        LogLevel.Warning);
+                    if (i >= MaxRetries) throw;
+                    await Task.Delay(1000, cancellationToken);
+                }
+            }
+            return null;
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/ISettings.cs b/PokemonGo.RocketAPI/ISettings.cs
index c935e24..011ca9e 100644
--- a/PokemonGo.RocketAPI/ISettings.cs
+++ b/PokemonGo.RocketAPI/ISettings.cs
@@ -1,41 +1,41 @@
-#region
-
-using PokemonGo.RocketAPI.Enums;
-using System.Collections.Generic;
-using PokemonGo.RocketAPI.GeneratedCode;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI
-{
-    public interface ISettings
-    {
-        AuthType AuthType { get; }
-        double DefaultLatitude { get; }
-        double DefaultLongitude { get; }
-        double DefaultAltitude { get; }
-        string PtcPassword { get; }
-        string PtcUsername { get; }
-        float KeepMinIVPercentage { get; }
-        int KeepMinCP { get; }
-        double WalkingSpeedInKilometerPerHour { get; }
-        bool EvolveAllPokemonWithEnoughCandy { get; }
-        bool TransferDuplicatePokemon { get; }
-        bool UsePokemonToNotCatchFilter { get; }
-        int KeepMinDuplicatePokemon { get; }
-        bool PrioritizeIVOverCP { get; }
-        int MaxTravelDistanceInMeters { get; }
-
-        bool UseGPXPathing { get; }
-        string GPXFile { get; }
-
-        ICollection<KeyValuePair<ItemId, int>> ItemRecycleFilter { get; }
-
-        ICollection<PokemonId> PokemonsToEvolve { get; }
-
-        ICollection<PokemonId> PokemonsNotToTransfer { get; }
-
-        ICollection<PokemonId> PokemonsNotToCatch { get; }
-    }
+#region
+
+using PokemonGo.RocketAPI.Enums;
+using System.Collections.Generic;
+using PokemonGo.RocketAPI.GeneratedCode;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI
+{
+    public interface ISettings
+    {
+        AuthType AuthType { get; }
+        double DefaultLatitude { get; }
+        double DefaultLongitude { get; }
+        double DefaultAltitude { get; }
+        string PtcPassword { get; }
+        string PtcUsername { get; }
+        float KeepMinIVPercentage { get; }
+        int KeepMinCP { get; }
+        double WalkingSpeedInKilometerPerHour { get; }
+        bool EvolveAllPokemonWithEnoughCandy { get; }
+        bool TransferDuplicatePokemon { get; }
+        bool UsePokemonToNotCatchFilter { get; }
+        int KeepMinDuplicatePokemon { get; }
+        bool PrioritizeIVOverCP { get; }
+        int MaxTravelDistanceInMeters { get; }
+
+        bool UseGPXPathing { get; }
+        string GPXFile { get; }
+
+        ICollection<KeyValuePair<ItemId, int>> ItemRecycleFilter { get; }
+
+        ICollection<PokemonId> PokemonsToEvolve { get; }
+
+        ICollection<PokemonId> PokemonsNotToTransfer { get; }
+
+        ICollection<PokemonId> PokemonsNotToCatch { get; }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Logging/Logger.cs b/PokemonGo.RocketAPI/Logging/Logger.cs
index da5501a..0735538 100644
--- a/PokemonGo.RocketAPI/Logging/Logger.cs
+++ b/PokemonGo.RocketAPI/Logging/Logger.cs
@@ -1,128 +1,128 @@
-#region
-
-using System;
-using System.IO;
-
-#endregion
-
-
-namespace PokemonGo.RocketAPI.Logging
-{
-    /// <summary>
-    /// Generic logger which can be used across the projects.
-    /// Logger should be set to properly log.
-    /// </summary>
-    public class Logger
-    {
-        static string _currentFile = string.Empty;
-        static string path = Directory.GetCurrentDirectory() + "\\Logs\\";
-
-        //private static Logger _logger;
-
-        /// <summary>
-        /// Set the logger. All future requests to <see cref="Write(string, LogLevel)"/> will use that logger, any old will be unset.
-        /// </summary>
-        /// <param name="logger"></param>
-        public static void SetLogger()
-		{
-            if (!Directory.Exists(path))
-            {
-                DirectoryInfo di = Directory.CreateDirectory(path);
-            }
-            _currentFile = DateTime.Now.ToString("yyyy-MM-dd - HH.mm.ss");
-            Log($"Initializing Rocket logger @ {DateTime.Now}...");
-        }
-
-        /// <summary>
-        ///     Log a specific message to the logger setup by <see cref="SetLogger(ILogger)" /> .
-        /// </summary>
-        /// <param name="message">The message to log.</param>
-        /// <param name="level">Optional level to log. Default <see cref="LogLevel.Info" />.</param>
-        /// <param name="color">Optional. Default is automatic color.</param>
-        public static void Write(string message, LogLevel level = LogLevel.None, ConsoleColor color = ConsoleColor.White)
-        {
-            switch (level)
-            {
-                case LogLevel.Info:
-                    System.Console.ForegroundColor = ConsoleColor.DarkGreen;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (INFO) {message}");
-                    break;
-                case LogLevel.Warning:
-                    System.Console.ForegroundColor = ConsoleColor.DarkYellow;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (ATTENTION) {message}");
-                    break;
-                case LogLevel.Error:
-                    System.Console.ForegroundColor = ConsoleColor.Red;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (ERROR) {message}");
-                    break;
-                case LogLevel.Debug:
-                    System.Console.ForegroundColor = ConsoleColor.Gray;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (DEBUG) {message}");
-                    break;
-                case LogLevel.Navigation:
-                    System.Console.ForegroundColor = ConsoleColor.DarkCyan;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (NAVIGATION) {message}");
-                    break;
-                case LogLevel.Pokestop:
-                    System.Console.ForegroundColor = ConsoleColor.Cyan;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (POKESTOP) {message}");
-                    break;
-                case LogLevel.Pokemon:
-                    System.Console.ForegroundColor = ConsoleColor.Yellow;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (PKMN) {message}");
-                    break;
-                case LogLevel.Transfer:
-                    System.Console.ForegroundColor = ConsoleColor.White;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (TRANSFER) {message}");
-                    break;
-                case LogLevel.Evolve:
-                    System.Console.ForegroundColor = ConsoleColor.White;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (EVOLVE) {message}");
-                    break;
-                case LogLevel.Berry:
-                    System.Console.ForegroundColor = ConsoleColor.White;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (BERRY) {message}");
-                    break;
-                case LogLevel.Recycling:
-                    System.Console.ForegroundColor = ConsoleColor.DarkMagenta;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (RECYCLING) {message}");
-                    break;
-                case LogLevel.None:
-                    System.Console.ForegroundColor = color;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] {message}");
-                    break;
-                default:
-                    System.Console.ForegroundColor = ConsoleColor.White;
-                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] {message}");
-                    break;
-            }
-            Log(string.Concat($"[{DateTime.Now.ToString("HH:mm:ss")}] ", message));
-        }
-
-        private static void Log(string message)
-        {
-            // maybe do a new log rather than appending?
-            using (var log = File.AppendText(path + _currentFile + ".txt"))
-            {
-                log.WriteLine(message);
-                log.Flush();
-            }
-        }
-    }
-
-    public enum LogLevel
-    {
-        None = 0,
-        Info = 1,
-        Warning = 2,
-        Error = 3,
-        Debug = 4,
-        Navigation = 5,
-        Pokestop = 6,
-        Pokemon = 7,
-        Transfer = 8,
-        Evolve = 9,
-        Berry = 10,
-        Recycling = 11
-    }
+#region
+
+using System;
+using System.IO;
+
+#endregion
+
+
+namespace PokemonGo.RocketAPI.Logging
+{
+    /// <summary>
+    /// Generic logger which can be used across the projects.
+    /// Logger should be set to properly log.
+    /// </summary>
+    public class Logger
+    {
+        static string _currentFile = string.Empty;
+        static string path = Directory.GetCurrentDirectory() + "\\Logs\\";
+
+        //private static Logger _logger;
+
+        /// <summary>
+        /// Set the logger. All future requests to <see cref="Write(string, LogLevel)"/> will use that logger, any old will be unset.
+        /// </summary>
+        /// <param name="logger"></param>
+        public static void SetLogger()
+		{
+            if (!Directory.Exists(path))
+            {
+                DirectoryInfo di = Directory.CreateDirectory(path);
+            }
+            _currentFile = DateTime.Now.ToString("yyyy-MM-dd - HH.mm.ss");
+            Log($"Initializing Rocket logger @ {DateTime.Now}...");
+        }
+
+        /// <summary>
+        ///     Log a specific message to the logger setup by <see cref="SetLogger(ILogger)" /> .
+        /// </summary>
+        /// <param name="message">The message to log.</param>
+        /// <param name="level">Optional level to log. Default <see cref="LogLevel.Info" />.</param>
+        /// <param name="color">Optional. Default is automatic color.</param>
+        public static void Write(string message, LogLevel level = LogLevel.None, ConsoleColor color = ConsoleColor.White)
+        {
+            switch (level)
+            {
+                case LogLevel.Info:
+                    System.Console.ForegroundColor = ConsoleColor.DarkGreen;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (INFO) {message}");
+                    break;
+                case LogLevel.Warning:
+                    System.Console.ForegroundColor = ConsoleColor.DarkYellow;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (ATTENTION) {message}");
+                    break;
+                case LogLevel.Error:
+                    System.Console.ForegroundColor = ConsoleColor.Red;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (ERROR) {message}");
+                    break;
+                case LogLevel.Debug:
+                    System.Console.ForegroundColor = ConsoleColor.Gray;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (DEBUG) {message}");
+                    break;
+                case LogLevel.Navigation:
+                    System.Console.ForegroundColor = ConsoleColor.DarkCyan;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (NAVIGATION) {message}");
+                    break;
+                case LogLevel.Pokestop:
+                    System.Console.ForegroundColor = ConsoleColor.Cyan;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (POKESTOP) {message}");
+                    break;
+                case LogLevel.Pokemon:
+                    System.Console.ForegroundColor = ConsoleColor.Yellow;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (PKMN) {message}");
+                    break;
+                case LogLevel.Transfer:
+                    System.Console.ForegroundColor = ConsoleColor.White;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (TRANSFER) {message}");
+                    break;
+                case LogLevel.Evolve:
+                    System.Console.ForegroundColor = ConsoleColor.White;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (EVOLVE) {message}");
+                    break;
+                case LogLevel.Berry:
+                    System.Console.ForegroundColor = ConsoleColor.White;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (BERRY) {message}");
+                    break;
+                case LogLevel.Recycling:
+                    System.Console.ForegroundColor = ConsoleColor.DarkMagenta;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] (RECYCLING) {message}");
+                    break;
+                case LogLevel.None:
+                    System.Console.ForegroundColor = color;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] {message}");
+                    break;
+                default:
+                    System.Console.ForegroundColor = ConsoleColor.White;
+                    System.Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss")}] {message}");
+                    break;
+            }
+            Log(string.Concat($"[{DateTime.Now.ToString("HH:mm:ss")}] ", message));
+        }
+
+        private static void Log(string message)
+        {
+            // maybe do a new log rather than appending?
+            using (var log = File.AppendText(path + _currentFile + ".txt"))
+            {
+                log.WriteLine(message);
+                log.Flush();
+            }
+        }
+    }
+
+    public enum LogLevel
+    {
+        None = 0,
+        Info = 1,
+        Warning = 2,
+        Error = 3,
+        Debug = 4,
+        Navigation = 5,
+        Pokestop = 6,
+        Pokemon = 7,
+        Transfer = 8,
+        Evolve = 9,
+        Berry = 10,
+        Recycling = 11
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/Login/GoogleLogin.cs b/PokemonGo.RocketAPI/Login/GoogleLogin.cs
index 8e28e0d..7bc0473 100644
--- a/PokemonGo.RocketAPI/Login/GoogleLogin.cs
+++ b/PokemonGo.RocketAPI/Login/GoogleLogin.cs
@@ -1,113 +1,113 @@
-#region
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Windows.Forms;
-using PokemonGo.RocketAPI.Helpers;
-using PokemonGo.RocketAPI.Logging;
-
-#endregion
-
-namespace PokemonGo.RocketAPI.Login
-{
-    public static class GoogleLogin
-    {
-        private const string OauthTokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
-        private const string OauthEndpoint = "https://accounts.google.com/o/oauth2/device/code";
-        private const string ClientId = "848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com";
-        private const string ClientSecret = "NCjF1TLi2CcY6t5mt0ZveuL7";
-
-        /// <summary>
-        ///     Gets the access token from Google
-        /// </summary>
-        /// <param name="deviceCode"></param>
-        /// <returns>tokenResponse</returns>
-        public static async Task<TokenResponseModel> GetAccessToken(DeviceCodeModel deviceCode)
-        {
-            //Poll until user submitted code..
-            TokenResponseModel tokenResponse;
-            do
-            {
-                await Task.Delay(2000);
-                tokenResponse = await PollSubmittedToken(deviceCode.device_code);
-            } while (tokenResponse.access_token == null || tokenResponse.refresh_token == null);
-
-            return tokenResponse;
-        }
-
-        public static async Task<TokenResponseModel> GetAccessToken(string refreshToken)
-        {
-            return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
-                new KeyValuePair<string, string>("access_type", "offline"),
-                new KeyValuePair<string, string>("client_id", ClientId),
-                new KeyValuePair<string, string>("client_secret", ClientSecret),
-                new KeyValuePair<string, string>("refresh_token", refreshToken),
-                new KeyValuePair<string, string>("grant_type", "refresh_token"),
-                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
-        }
-
-        public static async Task<DeviceCodeModel> GetDeviceCode()
-        {
-            var deviceCode = await HttpClientHelper.PostFormEncodedAsync<DeviceCodeModel>(OauthEndpoint,
-                new KeyValuePair<string, string>("client_id", ClientId),
-                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
-
-            try
-            {
-                Logger.Write("Google Device Code copied to clipboard");
-                Thread.Sleep(2000);
-                Process.Start(@"http://www.google.com/device");
-                var thread = new Thread(() => Clipboard.SetText(deviceCode.user_code)); //Copy device code
-                thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
-                thread.Start();
-                thread.Join();
-            }
-            catch (Exception)
-            {
-                Logger.Write("Couldnt copy to clipboard, do it manually", LogLevel.Warning);
-                Logger.Write($"Goto: http://www.google.com/device & enter {deviceCode.user_code}", LogLevel.Warning);
-            }
-
-            return deviceCode;
-        }
-
-        private static async Task<TokenResponseModel> PollSubmittedToken(string deviceCode)
-        {
-            return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
-                new KeyValuePair<string, string>("client_id", ClientId),
-                new KeyValuePair<string, string>("client_secret", ClientSecret),
-                new KeyValuePair<string, string>("code", deviceCode),
-                new KeyValuePair<string, string>("grant_type", "http://oauth.net/grant_type/device/1.0"),
-                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
-        }
-
-        internal class ErrorResponseModel
-        {
-            public string error { get; set; }
-            public string error_description { get; set; }
-        }
-
-        public class TokenResponseModel
-        {
-            public string access_token { get; set; }
-            public string token_type { get; set; }
-            public int expires_in { get; set; }
-            public string refresh_token { get; set; }
-            public string id_token { get; set; }
-        }
-
-
-        public class DeviceCodeModel
-        {
-            public string verification_url { get; set; }
-            public int expires_in { get; set; }
-            public int interval { get; set; }
-            public string device_code { get; set; }
-            public string user_code { get; set; }
-        }
-
-    }
-}
+#region
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using PokemonGo.RocketAPI.Helpers;
+using PokemonGo.RocketAPI.Logging;
+
+#endregion
+
+namespace PokemonGo.RocketAPI.Login
+{
+    public static class GoogleLogin
+    {
+        private const string OauthTokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
+        private const string OauthEndpoint = "https://accounts.google.com/o/oauth2/device/code";
+        private const string ClientId = "848232511240-73ri3t7plvk96pj4f85uj8otdat2alem.apps.googleusercontent.com";
+        private const string ClientSecret = "NCjF1TLi2CcY6t5mt0ZveuL7";
+
+        /// <summary>
+        ///     Gets the access token from Google
+        /// </summary>
+        /// <param name="deviceCode"></param>
+        /// <returns>tokenResponse</returns>
+        public static async Task<TokenResponseModel> GetAccessToken(DeviceCodeModel deviceCode)
+        {
+            //Poll until user submitted code..
+            TokenResponseModel tokenResponse;
+            do
+            {
+                await Task.Delay(2000);
+                tokenResponse = await PollSubmittedToken(deviceCode.device_code);
+            } while (tokenResponse.access_token == null || tokenResponse.refresh_token == null);
+
+            return tokenResponse;
+        }
+
+        public static async Task<TokenResponseModel> GetAccessToken(string refreshToken)
+        {
+            return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
+                new KeyValuePair<string, string>("access_type", "offline"),
+                new KeyValuePair<string, string>("client_id", ClientId),
+                new KeyValuePair<string, string>("client_secret", ClientSecret),
+                new KeyValuePair<string, string>("refresh_token", refreshToken),
+                new KeyValuePair<string, string>("grant_type", "refresh_token"),
+                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
+        }
+
+        public static async Task<DeviceCodeModel> GetDeviceCode()
+        {
+            var deviceCode = await HttpClientHelper.PostFormEncodedAsync<DeviceCodeModel>(OauthEndpoint,
+                new KeyValuePair<string, string>("client_id", ClientId),
+                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
+
+            try
+            {
+                Logger.Write("Google Device Code copied to clipboard");
+                Thread.Sleep(2000);
+                Process.Start(@"http://www.google.com/device");
+                var thread = new Thread(() => Clipboard.SetText(deviceCode.user_code)); //Copy device code
+                thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
+                thread.Start();
+                thread.Join();
+            }
+            catch (Exception)
+            {
+                Logger.Write("Couldnt copy to clipboard, do it manually", LogLevel.Warning);
+                Logger.Write($"Goto: http://www.google.com/device & enter {deviceCode.user_code}", LogLevel.Warning);
+            }
+
+            return deviceCode;
+        }
+
+        private static async Task<TokenResponseModel> PollSubmittedToken(string deviceCode)
+        {
+            return await HttpClientHelper.PostFormEncodedAsync<TokenResponseModel>(OauthTokenEndpoint,
+                new KeyValuePair<string, string>("client_id", ClientId),
+                new KeyValuePair<string, string>("client_secret", ClientSecret),
+                new KeyValuePair<string, string>("code", deviceCode),
+                new KeyValuePair<string, string>("grant_type", "http://oauth.net/grant_type/device/1.0"),
+                new KeyValuePair<string, string>("scope", "openid email https://www.googleapis.com/auth/userinfo.email"));
+        }
+
+        internal class ErrorResponseModel
+        {
+            public string error { get; set; }
+            public string error_description { get; set; }
+        }
+
+        public class TokenResponseModel
+        {
+            public string access_token { get; set; }
+            public string token_type { get; set; }
+            public int expires_in { get; set; }
+            public string refresh_token { get; set; }
+            public string id_token { get; set; }
+        }
+
+
+        public class DeviceCodeModel
+        {
+            public string verification_url { get; set; }
+            public int expires_in { get; set; }
+            public int interval { get; set; }
+            public string device_code { get; set; }
+            public string user_code { get; set; }
+        }
+
+    }
+}
diff --git a/PokemonGo.RocketAPI/Login/PtcLogin.cs b/PokemonGo.RocketAPI/Login/PtcLogin.cs
index d1c7e25..58a2416 100644
--- a/PokemonGo.RocketAPI/Login/PtcLogin.cs
+++ b/PokemonGo.RocketAPI/Login/PtcLogin.cs
@@ -1,83 +1,83 @@
-#region
-
-using System.Collections.Generic;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-using System.Web;
-using PokemonGo.RocketAPI.Exceptions;
-using PokemonGo.RocketAPI.Helpers;
-
-#endregion
-
-namespace PokemonGo.RocketAPI.Login
-{
-    internal static class PtcLogin
-    {
-        public static async Task<string> GetAccessToken(string username, string password)
-        {
-            var handler = new HttpClientHandler
-            {
-                AutomaticDecompression = DecompressionMethods.GZip,
-                AllowAutoRedirect = false
-            };
-
-            using (var tempHttpClient = new HttpClient(handler))
-            {
-                //Get session cookie
-                var sessionResp = await tempHttpClient.GetAsync(Resources.PtcLoginUrl);
-                var data = await sessionResp.Content.ReadAsStringAsync();
-                if (data == null) throw new PtcOfflineException();
-
-                if (sessionResp.StatusCode == HttpStatusCode.InternalServerError)
-                    throw new PtcOfflineException();
-
-                var lt = JsonHelper.GetValue(data, "lt");
-                var executionId = JsonHelper.GetValue(data, "execution");
-
-                //Login
-                var loginResp = await tempHttpClient.PostAsync(Resources.PtcLoginUrl,
-                    new FormUrlEncodedContent(
-                        new[]
-                        {
-                            new KeyValuePair<string, string>("lt", lt),
-                            new KeyValuePair<string, string>("execution", executionId),
-                            new KeyValuePair<string, string>("_eventId", "submit"),
-                            new KeyValuePair<string, string>("username", username),
-                            new KeyValuePair<string, string>("password", password)
-                        }));
-
-                if (loginResp.Headers.Location == null)
-                {
-                    //This should be sufficient for catching AccountNotVerified exceptions
-                    if (loginResp.StatusCode == HttpStatusCode.OK && !loginResp.Headers.Contains("Set-Cookies"))
-                        throw new AccountNotVerifiedException();
-
-                    throw new PtcOfflineException();
-                }
-
-
-                var ticketId = HttpUtility.ParseQueryString(loginResp.Headers.Location.Query)["ticket"];
-                if (ticketId == null)
-                    throw new PtcOfflineException();
-
-                //Get tokenvar
-                var tokenResp = await tempHttpClient.PostAsync(Resources.PtcLoginOauth,
-                    new FormUrlEncodedContent(
-                        new[]
-                        {
-                            new KeyValuePair<string, string>("client_id", "mobile-app_pokemon-go"),
-                            new KeyValuePair<string, string>("redirect_uri",
-                                "https://www.nianticlabs.com/pokemongo/error"),
-                            new KeyValuePair<string, string>("client_secret",
-                                "w8ScCUXJQc6kXKw8FiOhd8Fixzht18Dq3PEVkUCP5ZPxtgyWsbTvWHFLm2wNY0JR"),
-                            new KeyValuePair<string, string>("grant_type", "refresh_token"),
-                            new KeyValuePair<string, string>("code", ticketId)
-                        }));
-
-                var tokenData = await tokenResp.Content.ReadAsStringAsync();
-                return HttpUtility.ParseQueryString(tokenData)["access_token"];
-            }
-        }
-    }
+#region
+
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using System.Web;
+using PokemonGo.RocketAPI.Exceptions;
+using PokemonGo.RocketAPI.Helpers;
+
+#endregion
+
+namespace PokemonGo.RocketAPI.Login
+{
+    internal static class PtcLogin
+    {
+        public static async Task<string> GetAccessToken(string username, string password)
+        {
+            var handler = new HttpClientHandler
+            {
+                AutomaticDecompression = DecompressionMethods.GZip,
+                AllowAutoRedirect = false
+            };
+
+            using (var tempHttpClient = new HttpClient(handler))
+            {
+                //Get session cookie
+                var sessionResp = await tempHttpClient.GetAsync(Resources.PtcLoginUrl);
+                var data = await sessionResp.Content.ReadAsStringAsync();
+                if (data == null) throw new PtcOfflineException();
+
+                if (sessionResp.StatusCode == HttpStatusCode.InternalServerError)
+                    throw new PtcOfflineException();
+
+                var lt = JsonHelper.GetValue(data, "lt");
+                var executionId = JsonHelper.GetValue(data, "execution");
+
+                //Login
+                var loginResp = await tempHttpClient.PostAsync(Resources.PtcLoginUrl,
+                    new FormUrlEncodedContent(
+                        new[]
+                        {
+                            new KeyValuePair<string, string>("lt", lt),
+                            new KeyValuePair<string, string>("execution", executionId),
+                            new KeyValuePair<string, string>("_eventId", "submit"),
+                            new KeyValuePair<string, string>("username", username),
+                            new KeyValuePair<string, string>("password", password)
+                        }));
+
+                if (loginResp.Headers.Location == null)
+                {
+                    //This should be sufficient for catching AccountNotVerified exceptions
+                    if (loginResp.StatusCode == HttpStatusCode.OK && !loginResp.Headers.Contains("Set-Cookies"))
+                        throw new AccountNotVerifiedException();
+
+                    throw new PtcOfflineException();
+                }
+
+
+                var ticketId = HttpUtility.ParseQueryString(loginResp.Headers.Location.Query)["ticket"];
+                if (ticketId == null)
+                    throw new PtcOfflineException();
+
+                //Get tokenvar
+                var tokenResp = await tempHttpClient.PostAsync(Resources.PtcLoginOauth,
+                    new FormUrlEncodedContent(
+                        new[]
+                        {
+                            new KeyValuePair<string, string>("client_id", "mobile-app_pokemon-go"),
+                            new KeyValuePair<string, string>("redirect_uri",
+                                "https://www.nianticlabs.com/pokemongo/error"),
+                            new KeyValuePair<string, string>("client_secret",
+                                "w8ScCUXJQc6kXKw8FiOhd8Fixzht18Dq3PEVkUCP5ZPxtgyWsbTvWHFLm2wNY0JR"),
+                            new KeyValuePair<string, string>("grant_type", "refresh_token"),
+                            new KeyValuePair<string, string>("code", ticketId)
+                        }));
+
+                var tokenData = await tokenResp.Content.ReadAsStringAsync();
+                return HttpUtility.ParseQueryString(tokenData)["access_token"];
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
index 61ddc2d..ca8e6f1 100644
--- a/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
+++ b/PokemonGo.RocketAPI/PokemonGo.RocketAPI.csproj
@@ -1,134 +1,134 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <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>{05D2DA44-1B8E-4CF7-94ED-4D52451CD095}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>PokemonGo.RocketAPI</RootNamespace>
-    <AssemblyName>Pokemon Go Rocket API</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <AssemblyInfoFilePath>Properties\AssemblyInfo.cs</AssemblyInfoFilePath>
-    <UpdateAssemblyVersion>True</UpdateAssemblyVersion>
-    <UpdateAssemblyFileVersion>False</UpdateAssemblyFileVersion>
-    <UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
-    <AssemblyVersionSettings>YearStamp.MonthStamp.DayStamp.Increment</AssemblyVersionSettings>
-    <PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
-    <AssemblyVersion>2016.7.24.286</AssemblyVersion>
-  </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>
-  </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="C5, Version=2.2.5073.27396, Culture=neutral, PublicKeyToken=282361b99ded7e8e, processorArchitecture=MSIL">
-      <HintPath>..\packages\C5.2.2.5073.27396\lib\portable-net40+sl50+wp80+win\C5.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\dotnet\Google.Protobuf.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <HintPath>..\packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <HintPath>..\packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="S2Geometry, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\S2Geometry.1.0.1\lib\portable-net45+wp8+win8\S2Geometry.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Configuration" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.VarintBitConverter, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\VarintBitConverter.1.0.0.0\lib\Net40\System.VarintBitConverter.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Web" />
-    <Reference Include="System.Windows.Forms" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Enums\AuthType.cs" />
-    <Compile Include="Enums\MiscEnums.cs" />
-    <Compile Include="Enums\RequestType.cs" />
-    <Compile Include="Exceptions\AccessTokenExpiredException.cs" />
-    <Compile Include="Exceptions\AccountNotVerifiedException.cs" />
-    <Compile Include="Exceptions\InvalidResponseException.cs" />
-    <Compile Include="Exceptions\PtcOfflineException.cs" />
-    <Compile Include="Extensions\DateTimeExtensions.cs" />
-    <Compile Include="GeneratedCode\AllEnum.cs" />
-    <Compile Include="GeneratedCode\Payloads.cs" />
-    <Compile Include="GeneratedCode\Request.cs" />
-    <Compile Include="GeneratedCode\Response.cs" />
-    <Compile Include="Helpers\Git.cs" />
-    <Compile Include="Helpers\HttpClientHelper.cs" />
-    <Compile Include="Helpers\JsonHelper.cs" />
-    <Compile Include="Helpers\ProtoHelper.cs" />
-    <Compile Include="Helpers\RetryHandler.cs" />
-    <Compile Include="Helpers\S2Helper.cs" />
-    <Compile Include="Helpers\Utils.cs" />
-    <Compile Include="ISettings.cs" />
-    <Compile Include="Logging\Logger.cs" />
-    <Compile Include="Login\GoogleLogin.cs" />
-    <Compile Include="Login\PtcLogin.cs" />
-    <None Include="app.config">
-      <SubType>Designer</SubType>
-    </None>
-    <Compile Include="Client.cs" />
-    <Compile Include="Extensions\HttpClientExtensions.cs" />
-    <Compile Include="Helpers\RandomHelper.cs" />
-    <Compile Include="Helpers\RequestBuilder.cs" />
-    <Compile Include="PokemonInfo.cs" />
-    <Compile Include="Resources.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-    <None Include="Proto\AllEnum.proto" />
-    <None Include="Proto\Payloads.proto" />
-    <None Include="Proto\Response.proto" />
-    <None Include="Proto\Request.proto" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <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>{05D2DA44-1B8E-4CF7-94ED-4D52451CD095}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>PokemonGo.RocketAPI</RootNamespace>
+    <AssemblyName>Pokemon Go Rocket API</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AssemblyInfoFilePath>Properties\AssemblyInfo.cs</AssemblyInfoFilePath>
+    <UpdateAssemblyVersion>True</UpdateAssemblyVersion>
+    <UpdateAssemblyFileVersion>False</UpdateAssemblyFileVersion>
+    <UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
+    <AssemblyVersionSettings>YearStamp.MonthStamp.DayStamp.Increment</AssemblyVersionSettings>
+    <PrimaryVersionType>AssemblyVersionAttribute</PrimaryVersionType>
+    <AssemblyVersion>2016.7.24.286</AssemblyVersion>
+  </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>
+  </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="C5, Version=2.2.5073.27396, Culture=neutral, PublicKeyToken=282361b99ded7e8e, processorArchitecture=MSIL">
+      <HintPath>..\packages\C5.2.2.5073.27396\lib\portable-net40+sl50+wp80+win\C5.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\dotnet\Google.Protobuf.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\EnterpriseLibrary.TransientFaultHandling.6.0.1304.0\lib\portable-net45+win+wp8\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data, Version=6.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\EnterpriseLibrary.TransientFaultHandling.Data.6.0.1304.1\lib\NET45\Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Data.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="S2Geometry, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\S2Geometry.1.0.1\lib\portable-net45+wp8+win8\S2Geometry.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.VarintBitConverter, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\VarintBitConverter.1.0.0.0\lib\Net40\System.VarintBitConverter.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.Web" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Enums\AuthType.cs" />
+    <Compile Include="Enums\MiscEnums.cs" />
+    <Compile Include="Enums\RequestType.cs" />
+    <Compile Include="Exceptions\AccessTokenExpiredException.cs" />
+    <Compile Include="Exceptions\AccountNotVerifiedException.cs" />
+    <Compile Include="Exceptions\InvalidResponseException.cs" />
+    <Compile Include="Exceptions\PtcOfflineException.cs" />
+    <Compile Include="Extensions\DateTimeExtensions.cs" />
+    <Compile Include="GeneratedCode\AllEnum.cs" />
+    <Compile Include="GeneratedCode\Payloads.cs" />
+    <Compile Include="GeneratedCode\Request.cs" />
+    <Compile Include="GeneratedCode\Response.cs" />
+    <Compile Include="Helpers\Git.cs" />
+    <Compile Include="Helpers\HttpClientHelper.cs" />
+    <Compile Include="Helpers\JsonHelper.cs" />
+    <Compile Include="Helpers\ProtoHelper.cs" />
+    <Compile Include="Helpers\RetryHandler.cs" />
+    <Compile Include="Helpers\S2Helper.cs" />
+    <Compile Include="Helpers\Utils.cs" />
+    <Compile Include="ISettings.cs" />
+    <Compile Include="Logging\Logger.cs" />
+    <Compile Include="Login\GoogleLogin.cs" />
+    <Compile Include="Login\PtcLogin.cs" />
+    <None Include="app.config">
+      <SubType>Designer</SubType>
+    </None>
+    <Compile Include="Client.cs" />
+    <Compile Include="Extensions\HttpClientExtensions.cs" />
+    <Compile Include="Helpers\RandomHelper.cs" />
+    <Compile Include="Helpers\RequestBuilder.cs" />
+    <Compile Include="PokemonInfo.cs" />
+    <Compile Include="Resources.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+    <None Include="Proto\AllEnum.proto" />
+    <None Include="Proto\Payloads.proto" />
+    <None Include="Proto\Response.proto" />
+    <None Include="Proto\Request.proto" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
   </Target>
   <Target Name="AfterBuild">
   </Target>
-  -->
+  -->
 </Project>
\ No newline at end of file
diff --git a/PokemonGo.RocketAPI/PokemonInfo.cs b/PokemonGo.RocketAPI/PokemonInfo.cs
index ed2d035..ad2eb19 100644
--- a/PokemonGo.RocketAPI/PokemonInfo.cs
+++ b/PokemonGo.RocketAPI/PokemonInfo.cs
@@ -1,321 +1,321 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using PokemonGo.RocketAPI.GeneratedCode;
-
-namespace PokemonGo.RocketAPI
-{
-    public struct BaseStats
-    {
-        public int BaseAttack, BaseDefense, BaseStamina;
-        public BaseStats(int baseStamina, int baseAttack, int baseDefense)
-        {
-            this.BaseAttack = baseAttack;
-            this.BaseDefense = baseDefense;
-            this.BaseStamina = baseStamina;
-        }
-        public override string ToString()
-        {
-            return (String.Format("({0} atk,{1} def,{2} sta)", BaseAttack, BaseDefense, BaseStamina));
-        }
-    }
-
-    public static class PokemonInfo
-    {
-        public static double CalculatePokemonPerfection(PokemonData poke)
-        {
-            if (poke.CpMultiplier + poke.AdditionalCpMultiplier == 0)
-                return (poke.IndividualAttack * 2 + poke.IndividualDefense + poke.IndividualStamina) / (4.0 * 15.0) * 100.0;
-
-            BaseStats baseStats = GetBaseStats(poke.PokemonId);
-            var max_cp = CalculateMaxCPMultiplier(poke);
-            var min_cp = CalculateMinCPMultiplier(poke);
-            var cur_cp = CalculateCPMultiplier(poke);
-
-            return ((cur_cp - min_cp) / (max_cp - min_cp)) * 100.0;
-        }
-
-        public static double CalculateMaxCPMultiplier(PokemonData poke)
-        {
-            BaseStats baseStats = GetBaseStats(poke.PokemonId);
-            return (baseStats.BaseAttack + 15) * Math.Sqrt(baseStats.BaseDefense + 15) * Math.Sqrt(baseStats.BaseStamina + 15);
-        }
-        public static double CalculateMinCPMultiplier(PokemonData poke)
-        {
-            BaseStats baseStats = GetBaseStats(poke.PokemonId);
-            return (baseStats.BaseAttack) * Math.Sqrt(baseStats.BaseDefense) * Math.Sqrt(baseStats.BaseStamina);
-        }
-        public static double CalculateCPMultiplier(PokemonData poke)
-        {
-            BaseStats baseStats = GetBaseStats(poke.PokemonId);
-            return (baseStats.BaseAttack + poke.IndividualAttack) * Math.Sqrt(baseStats.BaseDefense + poke.IndividualDefense) * Math.Sqrt(baseStats.BaseStamina + poke.IndividualStamina);
-        }
-
-        public static int CalculateMaxCP(PokemonData poke)
-        {
-            return Math.Max((int)Math.Floor(0.1 * CalculateMaxCPMultiplier(poke) * Math.Pow(poke.CpMultiplier + poke.AdditionalCpMultiplier, 2)), 10);
-        }
-        public static int CalculateMinCP(PokemonData poke)
-        {
-            return Math.Max((int)Math.Floor(0.1 * CalculateMinCPMultiplier(poke) * Math.Pow(poke.CpMultiplier + poke.AdditionalCpMultiplier, 2)), 10);
-        }
-        public static int CalculateCP(PokemonData poke)
-        {
-            return Math.Max((int)Math.Floor(0.1 * CalculateCPMultiplier(poke) * Math.Pow(poke.CpMultiplier + poke.AdditionalCpMultiplier, 2)), 10);
-        }
-
-        public static BaseStats GetBaseStats(PokemonId id)
-        {
-            switch ((int)id)
-            {
-                case 1: return new BaseStats(90, 126, 126);
-                case 2: return new BaseStats(120, 156, 158);
-                case 3: return new BaseStats(160, 198, 200);
-                case 4: return new BaseStats(78, 128, 108);
-                case 5: return new BaseStats(116, 160, 140);
-                case 6: return new BaseStats(156, 212, 182);
-                case 7: return new BaseStats(88, 112, 142);
-                case 8: return new BaseStats(118, 144, 176);
-                case 9: return new BaseStats(158, 186, 222);
-                case 10: return new BaseStats(90, 62, 66);
-                case 11: return new BaseStats(100, 56, 86);
-                case 12: return new BaseStats(120, 144, 144);
-                case 13: return new BaseStats(80, 68, 64);
-                case 14: return new BaseStats(90, 62, 82);
-                case 15: return new BaseStats(130, 144, 130);
-                case 16: return new BaseStats(80, 94, 90);
-                case 17: return new BaseStats(126, 126, 122);
-                case 18: return new BaseStats(166, 170, 166);
-                case 19: return new BaseStats(60, 92, 86);
-                case 20: return new BaseStats(110, 146, 150);
-                case 21: return new BaseStats(80, 102, 78);
-                case 22: return new BaseStats(130, 168, 146);
-                case 23: return new BaseStats(70, 112, 112);
-                case 24: return new BaseStats(120, 166, 166);
-                case 25: return new BaseStats(70, 124, 108);
-                case 26: return new BaseStats(120, 200, 154);
-                case 27: return new BaseStats(100, 90, 114);
-                case 28: return new BaseStats(150, 150, 172);
-                case 29: return new BaseStats(110, 100, 104);
-                case 30: return new BaseStats(140, 132, 136);
-                case 31: return new BaseStats(180, 184, 190);
-                case 32: return new BaseStats(92, 110, 94);
-                case 33: return new BaseStats(122, 142, 128);
-                case 34: return new BaseStats(162, 204, 170);
-                case 35: return new BaseStats(140, 116, 124);
-                case 36: return new BaseStats(190, 178, 178);
-                case 37: return new BaseStats(76, 106, 118);
-                case 38: return new BaseStats(146, 176, 194);
-                case 39: return new BaseStats(230, 98, 54);
-                case 40: return new BaseStats(280, 168, 108);
-                case 41: return new BaseStats(80, 88, 90);
-                case 42: return new BaseStats(150, 164, 164);
-                case 43: return new BaseStats(90, 134, 130);
-                case 44: return new BaseStats(120, 162, 158);
-                case 45: return new BaseStats(150, 202, 190);
-                case 46: return new BaseStats(70, 122, 120);
-                case 47: return new BaseStats(120, 162, 170);
-                case 48: return new BaseStats(120, 108, 118);
-                case 49: return new BaseStats(140, 172, 154);
-                case 50: return new BaseStats(20, 108, 86);
-                case 51: return new BaseStats(70, 148, 140);
-                case 52: return new BaseStats(80, 104, 94);
-                case 53: return new BaseStats(130, 156, 146);
-                case 54: return new BaseStats(100, 132, 112);
-                case 55: return new BaseStats(160, 194, 176);
-                case 56: return new BaseStats(80, 122, 96);
-                case 57: return new BaseStats(130, 178, 150);
-                case 58: return new BaseStats(110, 156, 110);
-                case 59: return new BaseStats(180, 230, 180);
-                case 60: return new BaseStats(80, 108, 98);
-                case 61: return new BaseStats(130, 132, 132);
-                case 62: return new BaseStats(180, 180, 202);
-                case 63: return new BaseStats(50, 110, 76);
-                case 64: return new BaseStats(80, 150, 112);
-                case 65: return new BaseStats(110, 186, 152);
-                case 66: return new BaseStats(140, 118, 96);
-                case 67: return new BaseStats(160, 154, 144);
-                case 68: return new BaseStats(180, 198, 180);
-                case 69: return new BaseStats(100, 158, 78);
-                case 70: return new BaseStats(130, 190, 110);
-                case 71: return new BaseStats(160, 222, 152);
-                case 72: return new BaseStats(80, 106, 136);
-                case 73: return new BaseStats(160, 170, 196);
-                case 74: return new BaseStats(80, 106, 118);
-                case 75: return new BaseStats(110, 142, 156);
-                case 76: return new BaseStats(160, 176, 198);
-                case 77: return new BaseStats(100, 168, 138);
-                case 78: return new BaseStats(130, 200, 170);
-                case 79: return new BaseStats(180, 110, 110);
-                case 80: return new BaseStats(190, 184, 198);
-                case 81: return new BaseStats(50, 128, 138);
-                case 82: return new BaseStats(100, 186, 180);
-                case 83: return new BaseStats(104, 138, 132);
-                case 84: return new BaseStats(70, 126, 96);
-                case 85: return new BaseStats(120, 182, 150);
-                case 86: return new BaseStats(130, 104, 138);
-                case 87: return new BaseStats(180, 156, 192);
-                case 88: return new BaseStats(160, 124, 110);
-                case 89: return new BaseStats(210, 180, 188);
-                case 90: return new BaseStats(60, 120, 112);
-                case 91: return new BaseStats(100, 196, 196);
-                case 92: return new BaseStats(60, 136, 82);
-                case 93: return new BaseStats(90, 172, 118);
-                case 94: return new BaseStats(120, 204, 156);
-                case 95: return new BaseStats(70, 90, 186);
-                case 96: return new BaseStats(120, 104, 140);
-                case 97: return new BaseStats(170, 162, 196);
-                case 98: return new BaseStats(60, 116, 110);
-                case 99: return new BaseStats(110, 178, 168);
-                case 100: return new BaseStats(80, 102, 124);
-                case 101: return new BaseStats(120, 150, 174);
-                case 102: return new BaseStats(120, 110, 132);
-                case 103: return new BaseStats(190, 232, 164);
-                case 104: return new BaseStats(100, 102, 150);
-                case 105: return new BaseStats(120, 140, 202);
-                case 106: return new BaseStats(100, 148, 172);
-                case 107: return new BaseStats(100, 138, 204);
-                case 108: return new BaseStats(180, 126, 160);
-                case 109: return new BaseStats(80, 136, 142);
-                case 110: return new BaseStats(130, 190, 198);
-                case 111: return new BaseStats(160, 110, 116);
-                case 112: return new BaseStats(210, 166, 160);
-                case 113: return new BaseStats(500, 40, 60);
-                case 114: return new BaseStats(130, 164, 152);
-                case 115: return new BaseStats(210, 142, 178);
-                case 116: return new BaseStats(60, 122, 100);
-                case 117: return new BaseStats(110, 176, 150);
-                case 118: return new BaseStats(90, 112, 126);
-                case 119: return new BaseStats(160, 172, 160);
-                case 120: return new BaseStats(60, 130, 128);
-                case 121: return new BaseStats(120, 194, 192);
-                case 122: return new BaseStats(80, 154, 196);
-                case 123: return new BaseStats(140, 176, 180);
-                case 124: return new BaseStats(130, 172, 134);
-                case 125: return new BaseStats(130, 198, 160);
-                case 126: return new BaseStats(130, 214, 158);
-                case 127: return new BaseStats(130, 184, 186);
-                case 128: return new BaseStats(150, 148, 184);
-                case 129: return new BaseStats(40, 42, 84);
-                case 130: return new BaseStats(190, 192, 196);
-                case 131: return new BaseStats(260, 186, 190);
-                case 132: return new BaseStats(96, 110, 110);
-                case 133: return new BaseStats(110, 114, 128);
-                case 134: return new BaseStats(260, 186, 168);
-                case 135: return new BaseStats(130, 192, 174);
-                case 136: return new BaseStats(130, 238, 178);
-                case 137: return new BaseStats(130, 156, 158);
-                case 138: return new BaseStats(70, 132, 160);
-                case 139: return new BaseStats(140, 180, 202);
-                case 140: return new BaseStats(60, 148, 142);
-                case 141: return new BaseStats(120, 190, 190);
-                case 142: return new BaseStats(160, 182, 162);
-                case 143: return new BaseStats(320, 180, 180);
-                case 144: return new BaseStats(180, 198, 242);
-                case 145: return new BaseStats(180, 232, 194);
-                case 146: return new BaseStats(180, 242, 194);
-                case 147: return new BaseStats(82, 128, 110);
-                case 148: return new BaseStats(122, 170, 152);
-                case 149: return new BaseStats(182, 250, 212);
-                case 150: return new BaseStats(212, 284, 202);
-                case 151: return new BaseStats(200, 220, 220);
-                default: return new BaseStats();
-            }
-        }
-
-        public static int GetPowerUpLevel(PokemonData poke)
-        {
-            return (int)(GetLevel(poke) * 2.0);
-        }
-        public static double GetLevel(PokemonData poke)
-        {
-
-            switch ((int)((poke.CpMultiplier + poke.AdditionalCpMultiplier) * 1000.0))
-            {
-                case 93: // 0.094 * 1000 = 93.99999678134
-                case 94: return 1;
-                case 135: return 1.5;
-                case 166: return 2;
-                case 192: return 2.5;
-                case 215: return 3;
-                case 236: return 3.5;
-                case 255: return 4;
-                case 273: return 4.5;
-                case 290: return 5;
-                case 306: return 5.5;
-                case 321: return 6;
-                case 335: return 6.5;
-                case 349: return 7;
-                case 362: return 7.5;
-                case 375: return 8;
-                case 387: return 8.5;
-                case 399: return 9;
-                case 411: return 9.5;
-                case 422: return 10;
-                case 432: return 15;
-                case 443: return 11;
-                case 453: return 11.5;
-                case 462: return 12;
-                case 472: return 12.5;
-                case 481: return 13;
-                case 490: return 13.5;
-                case 499: return 14;
-                case 508: return 14.5;
-                case 517: return 15;
-                case 525: return 15.5;
-                case 534: return 16;
-                case 542: return 16.5;
-                case 550: return 17;
-                case 558: return 17.5;
-                case 566: return 18;
-                case 574: return 18.5;
-                case 582: return 19;
-                case 589: return 19.5;
-                case 597: return 20;
-                case 604: return 25;
-                case 612: return 21;
-                case 619: return 21.5;
-                case 626: return 22;
-                case 633: return 22.5;
-                case 640: return 23;
-                case 647: return 23.5;
-                case 654: return 24;
-                case 661: return 24.5;
-                case 667: return 25;
-                case 674: return 25.5;
-                case 681: return 26;
-                case 687: return 26.5;
-                case 694: return 27;
-                case 700: return 27.5;
-                case 706: return 28;
-                case 713: return 28.5;
-                case 719: return 29;
-                case 725: return 29.5;
-                case 731: return 30;
-                case 734: return 35;
-                case 737: return 31;
-                case 740: return 31.5;
-                case 743: return 32;
-                case 746: return 32.5;
-                case 749: return 33;
-                case 752: return 33.5;
-                case 755: return 34;
-                case 758: return 34.5;
-                case 761: return 35;
-                case 764: return 35.5;
-                case 767: return 36;
-                case 770: return 36.5;
-                case 773: return 37;
-                case 776: return 37.5;
-                case 778: return 38;
-                case 781: return 38.5;
-                case 784: return 39;
-                case 787: return 39.5;
-                case 790: return 40;
-                default: return 0;
-            }
-        }
-    }
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using PokemonGo.RocketAPI.GeneratedCode;
+
+namespace PokemonGo.RocketAPI
+{
+    public struct BaseStats
+    {
+        public int BaseAttack, BaseDefense, BaseStamina;
+        public BaseStats(int baseStamina, int baseAttack, int baseDefense)
+        {
+            this.BaseAttack = baseAttack;
+            this.BaseDefense = baseDefense;
+            this.BaseStamina = baseStamina;
+        }
+        public override string ToString()
+        {
+            return (String.Format("({0} atk,{1} def,{2} sta)", BaseAttack, BaseDefense, BaseStamina));
+        }
+    }
+
+    public static class PokemonInfo
+    {
+        public static double CalculatePokemonPerfection(PokemonData poke)
+        {
+            if (poke.CpMultiplier + poke.AdditionalCpMultiplier == 0)
+                return (poke.IndividualAttack * 2 + poke.IndividualDefense + poke.IndividualStamina) / (4.0 * 15.0) * 100.0;
+
+            BaseStats baseStats = GetBaseStats(poke.PokemonId);
+            var max_cp = CalculateMaxCPMultiplier(poke);
+            var min_cp = CalculateMinCPMultiplier(poke);
+            var cur_cp = CalculateCPMultiplier(poke);
+
+            return ((cur_cp - min_cp) / (max_cp - min_cp)) * 100.0;
+        }
+
+        public static double CalculateMaxCPMultiplier(PokemonData poke)
+        {
+            BaseStats baseStats = GetBaseStats(poke.PokemonId);
+            return (baseStats.BaseAttack + 15) * Math.Sqrt(baseStats.BaseDefense + 15) * Math.Sqrt(baseStats.BaseStamina + 15);
+        }
+        public static double CalculateMinCPMultiplier(PokemonData poke)
+        {
+            BaseStats baseStats = GetBaseStats(poke.PokemonId);
+            return (baseStats.BaseAttack) * Math.Sqrt(baseStats.BaseDefense) * Math.Sqrt(baseStats.BaseStamina);
+        }
+        public static double CalculateCPMultiplier(PokemonData poke)
+        {
+            BaseStats baseStats = GetBaseStats(poke.PokemonId);
+            return (baseStats.BaseAttack + poke.IndividualAttack) * Math.Sqrt(baseStats.BaseDefense + poke.IndividualDefense) * Math.Sqrt(baseStats.BaseStamina + poke.IndividualStamina);
+        }
+
+        public static int CalculateMaxCP(PokemonData poke)
+        {
+            return Math.Max((int)Math.Floor(0.1 * CalculateMaxCPMultiplier(poke) * Math.Pow(poke.CpMultiplier + poke.AdditionalCpMultiplier, 2)), 10);
+        }
+        public static int CalculateMinCP(PokemonData poke)
+        {
+            return Math.Max((int)Math.Floor(0.1 * CalculateMinCPMultiplier(poke) * Math.Pow(poke.CpMultiplier + poke.AdditionalCpMultiplier, 2)), 10);
+        }
+        public static int CalculateCP(PokemonData poke)
+        {
+            return Math.Max((int)Math.Floor(0.1 * CalculateCPMultiplier(poke) * Math.Pow(poke.CpMultiplier + poke.AdditionalCpMultiplier, 2)), 10);
+        }
+
+        public static BaseStats GetBaseStats(PokemonId id)
+        {
+            switch ((int)id)
+            {
+                case 1: return new BaseStats(90, 126, 126);
+                case 2: return new BaseStats(120, 156, 158);
+                case 3: return new BaseStats(160, 198, 200);
+                case 4: return new BaseStats(78, 128, 108);
+                case 5: return new BaseStats(116, 160, 140);
+                case 6: return new BaseStats(156, 212, 182);
+                case 7: return new BaseStats(88, 112, 142);
+                case 8: return new BaseStats(118, 144, 176);
+                case 9: return new BaseStats(158, 186, 222);
+                case 10: return new BaseStats(90, 62, 66);
+                case 11: return new BaseStats(100, 56, 86);
+                case 12: return new BaseStats(120, 144, 144);
+                case 13: return new BaseStats(80, 68, 64);
+                case 14: return new BaseStats(90, 62, 82);
+                case 15: return new BaseStats(130, 144, 130);
+                case 16: return new BaseStats(80, 94, 90);
+                case 17: return new BaseStats(126, 126, 122);
+                case 18: return new BaseStats(166, 170, 166);
+                case 19: return new BaseStats(60, 92, 86);
+                case 20: return new BaseStats(110, 146, 150);
+                case 21: return new BaseStats(80, 102, 78);
+                case 22: return new BaseStats(130, 168, 146);
+                case 23: return new BaseStats(70, 112, 112);
+                case 24: return new BaseStats(120, 166, 166);
+                case 25: return new BaseStats(70, 124, 108);
+                case 26: return new BaseStats(120, 200, 154);
+                case 27: return new BaseStats(100, 90, 114);
+                case 28: return new BaseStats(150, 150, 172);
+                case 29: return new BaseStats(110, 100, 104);
+                case 30: return new BaseStats(140, 132, 136);
+                case 31: return new BaseStats(180, 184, 190);
+                case 32: return new BaseStats(92, 110, 94);
+                case 33: return new BaseStats(122, 142, 128);
+                case 34: return new BaseStats(162, 204, 170);
+                case 35: return new BaseStats(140, 116, 124);
+                case 36: return new BaseStats(190, 178, 178);
+                case 37: return new BaseStats(76, 106, 118);
+                case 38: return new BaseStats(146, 176, 194);
+                case 39: return new BaseStats(230, 98, 54);
+                case 40: return new BaseStats(280, 168, 108);
+                case 41: return new BaseStats(80, 88, 90);
+                case 42: return new BaseStats(150, 164, 164);
+                case 43: return new BaseStats(90, 134, 130);
+                case 44: return new BaseStats(120, 162, 158);
+                case 45: return new BaseStats(150, 202, 190);
+                case 46: return new BaseStats(70, 122, 120);
+                case 47: return new BaseStats(120, 162, 170);
+                case 48: return new BaseStats(120, 108, 118);
+                case 49: return new BaseStats(140, 172, 154);
+                case 50: return new BaseStats(20, 108, 86);
+                case 51: return new BaseStats(70, 148, 140);
+                case 52: return new BaseStats(80, 104, 94);
+                case 53: return new BaseStats(130, 156, 146);
+                case 54: return new BaseStats(100, 132, 112);
+                case 55: return new BaseStats(160, 194, 176);
+                case 56: return new BaseStats(80, 122, 96);
+                case 57: return new BaseStats(130, 178, 150);
+                case 58: return new BaseStats(110, 156, 110);
+                case 59: return new BaseStats(180, 230, 180);
+                case 60: return new BaseStats(80, 108, 98);
+                case 61: return new BaseStats(130, 132, 132);
+                case 62: return new BaseStats(180, 180, 202);
+                case 63: return new BaseStats(50, 110, 76);
+                case 64: return new BaseStats(80, 150, 112);
+                case 65: return new BaseStats(110, 186, 152);
+                case 66: return new BaseStats(140, 118, 96);
+                case 67: return new BaseStats(160, 154, 144);
+                case 68: return new BaseStats(180, 198, 180);
+                case 69: return new BaseStats(100, 158, 78);
+                case 70: return new BaseStats(130, 190, 110);
+                case 71: return new BaseStats(160, 222, 152);
+                case 72: return new BaseStats(80, 106, 136);
+                case 73: return new BaseStats(160, 170, 196);
+                case 74: return new BaseStats(80, 106, 118);
+                case 75: return new BaseStats(110, 142, 156);
+                case 76: return new BaseStats(160, 176, 198);
+                case 77: return new BaseStats(100, 168, 138);
+                case 78: return new BaseStats(130, 200, 170);
+                case 79: return new BaseStats(180, 110, 110);
+                case 80: return new BaseStats(190, 184, 198);
+                case 81: return new BaseStats(50, 128, 138);
+                case 82: return new BaseStats(100, 186, 180);
+                case 83: return new BaseStats(104, 138, 132);
+                case 84: return new BaseStats(70, 126, 96);
+                case 85: return new BaseStats(120, 182, 150);
+                case 86: return new BaseStats(130, 104, 138);
+                case 87: return new BaseStats(180, 156, 192);
+                case 88: return new BaseStats(160, 124, 110);
+                case 89: return new BaseStats(210, 180, 188);
+                case 90: return new BaseStats(60, 120, 112);
+                case 91: return new BaseStats(100, 196, 196);
+                case 92: return new BaseStats(60, 136, 82);
+                case 93: return new BaseStats(90, 172, 118);
+                case 94: return new BaseStats(120, 204, 156);
+                case 95: return new BaseStats(70, 90, 186);
+                case 96: return new BaseStats(120, 104, 140);
+                case 97: return new BaseStats(170, 162, 196);
+                case 98: return new BaseStats(60, 116, 110);
+                case 99: return new BaseStats(110, 178, 168);
+                case 100: return new BaseStats(80, 102, 124);
+                case 101: return new BaseStats(120, 150, 174);
+                case 102: return new BaseStats(120, 110, 132);
+                case 103: return new BaseStats(190, 232, 164);
+                case 104: return new BaseStats(100, 102, 150);
+                case 105: return new BaseStats(120, 140, 202);
+                case 106: return new BaseStats(100, 148, 172);
+                case 107: return new BaseStats(100, 138, 204);
+                case 108: return new BaseStats(180, 126, 160);
+                case 109: return new BaseStats(80, 136, 142);
+                case 110: return new BaseStats(130, 190, 198);
+                case 111: return new BaseStats(160, 110, 116);
+                case 112: return new BaseStats(210, 166, 160);
+                case 113: return new BaseStats(500, 40, 60);
+                case 114: return new BaseStats(130, 164, 152);
+                case 115: return new BaseStats(210, 142, 178);
+                case 116: return new BaseStats(60, 122, 100);
+                case 117: return new BaseStats(110, 176, 150);
+                case 118: return new BaseStats(90, 112, 126);
+                case 119: return new BaseStats(160, 172, 160);
+                case 120: return new BaseStats(60, 130, 128);
+                case 121: return new BaseStats(120, 194, 192);
+                case 122: return new BaseStats(80, 154, 196);
+                case 123: return new BaseStats(140, 176, 180);
+                case 124: return new BaseStats(130, 172, 134);
+                case 125: return new BaseStats(130, 198, 160);
+                case 126: return new BaseStats(130, 214, 158);
+                case 127: return new BaseStats(130, 184, 186);
+                case 128: return new BaseStats(150, 148, 184);
+                case 129: return new BaseStats(40, 42, 84);
+                case 130: return new BaseStats(190, 192, 196);
+                case 131: return new BaseStats(260, 186, 190);
+                case 132: return new BaseStats(96, 110, 110);
+                case 133: return new BaseStats(110, 114, 128);
+                case 134: return new BaseStats(260, 186, 168);
+                case 135: return new BaseStats(130, 192, 174);
+                case 136: return new BaseStats(130, 238, 178);
+                case 137: return new BaseStats(130, 156, 158);
+                case 138: return new BaseStats(70, 132, 160);
+                case 139: return new BaseStats(140, 180, 202);
+                case 140: return new BaseStats(60, 148, 142);
+                case 141: return new BaseStats(120, 190, 190);
+                case 142: return new BaseStats(160, 182, 162);
+                case 143: return new BaseStats(320, 180, 180);
+                case 144: return new BaseStats(180, 198, 242);
+                case 145: return new BaseStats(180, 232, 194);
+                case 146: return new BaseStats(180, 242, 194);
+                case 147: return new BaseStats(82, 128, 110);
+                case 148: return new BaseStats(122, 170, 152);
+                case 149: return new BaseStats(182, 250, 212);
+                case 150: return new BaseStats(212, 284, 202);
+                case 151: return new BaseStats(200, 220, 220);
+                default: return new BaseStats();
+            }
+        }
+
+        public static int GetPowerUpLevel(PokemonData poke)
+        {
+            return (int)(GetLevel(poke) * 2.0);
+        }
+        public static double GetLevel(PokemonData poke)
+        {
+
+            switch ((int)((poke.CpMultiplier + poke.AdditionalCpMultiplier) * 1000.0))
+            {
+                case 93: // 0.094 * 1000 = 93.99999678134
+                case 94: return 1;
+                case 135: return 1.5;
+                case 166: return 2;
+                case 192: return 2.5;
+                case 215: return 3;
+                case 236: return 3.5;
+                case 255: return 4;
+                case 273: return 4.5;
+                case 290: return 5;
+                case 306: return 5.5;
+                case 321: return 6;
+                case 335: return 6.5;
+                case 349: return 7;
+                case 362: return 7.5;
+                case 375: return 8;
+                case 387: return 8.5;
+                case 399: return 9;
+                case 411: return 9.5;
+                case 422: return 10;
+                case 432: return 15;
+                case 443: return 11;
+                case 453: return 11.5;
+                case 462: return 12;
+                case 472: return 12.5;
+                case 481: return 13;
+                case 490: return 13.5;
+                case 499: return 14;
+                case 508: return 14.5;
+                case 517: return 15;
+                case 525: return 15.5;
+                case 534: return 16;
+                case 542: return 16.5;
+                case 550: return 17;
+                case 558: return 17.5;
+                case 566: return 18;
+                case 574: return 18.5;
+                case 582: return 19;
+                case 589: return 19.5;
+                case 597: return 20;
+                case 604: return 25;
+                case 612: return 21;
+                case 619: return 21.5;
+                case 626: return 22;
+                case 633: return 22.5;
+                case 640: return 23;
+                case 647: return 23.5;
+                case 654: return 24;
+                case 661: return 24.5;
+                case 667: return 25;
+                case 674: return 25.5;
+                case 681: return 26;
+                case 687: return 26.5;
+                case 694: return 27;
+                case 700: return 27.5;
+                case 706: return 28;
+                case 713: return 28.5;
+                case 719: return 29;
+                case 725: return 29.5;
+                case 731: return 30;
+                case 734: return 35;
+                case 737: return 31;
+                case 740: return 31.5;
+                case 743: return 32;
+                case 746: return 32.5;
+                case 749: return 33;
+                case 752: return 33.5;
+                case 755: return 34;
+                case 758: return 34.5;
+                case 761: return 35;
+                case 764: return 35.5;
+                case 767: return 36;
+                case 770: return 36.5;
+                case 773: return 37;
+                case 776: return 37.5;
+                case 778: return 38;
+                case 781: return 38.5;
+                case 784: return 39;
+                case 787: return 39.5;
+                case 790: return 40;
+                default: return 0;
+            }
+        }
+    }
 }
\ No newline at end of file
You may download the files in Public Git.