Merge remote-tracking branch 'refs/remotes/TheUnnameOrganization/Beta-Build' into Beta-Build

Gh0st [2016-08-23 15:33:46]
Merge remote-tracking branch 'refs/remotes/TheUnnameOrganization/Beta-Build' into Beta-Build
Filename
PokemonGo.RocketBot.Logic/Common/Translations.cs
PokemonGo.RocketBot.Logic/Navigation.cs
PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj
PokemonGo.RocketBot.Logic/Settings.cs
PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
PokemonGo.RocketBot.Logic/Tasks/LevelUpSpecificPokemonTask.cs
PokemonGo.RocketBot.Logic/Tasks/RecycleSpecificItemTask.cs
PokemonGo.RocketBot.Logic/Tasks/RenameSpecificPokemonTask.cs
PokemonGo.RocketBot.Logic/Tasks/TransferPokemonTask.cs
PokemonGo.RocketBot.Logic/Tasks/UseIncenseTask.cs
PokemonGo.RocketBot.Logic/Tasks/UseLuckyEggTask.cs
PokemonGo.RocketBot.Window/ConsoleLogger.cs
PokemonGo.RocketBot.Window/Forms/MainForm.cs
PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs
PokemonGo.RocketBot.Window/Forms/SettingForm.Designer.cs
PokemonGo.RocketBot.Window/Forms/SettingForm.cs
PokemonGo.RocketBot.Window/Helpers/MachineIdHelper.cs
PokemonGo.RocketBot.Window/Helpers/ResourceHelper.cs
PokemonGo.RocketBot.Window/Images/Miscs/question.png
PokemonGo.RocketBot.Window/Models/LoggingStrings.cs
PokemonGo.RocketBot.Window/PokemonGo.RocketBot.Window.csproj
PokemonGo.RocketBot.Window/Properties/Resources.Designer.cs
PokemonGo.RocketBot.Window/Properties/Resources.resx
PokemonGo.RocketBot.Window/WebSocketHandler/ActionCommands/TransferPokemonHandler.cs
diff --git a/PokemonGo.RocketBot.Logic/Common/Translations.cs b/PokemonGo.RocketBot.Logic/Common/Translations.cs
index d4d1fc8..6aab17d 100644
--- a/PokemonGo.RocketBot.Logic/Common/Translations.cs
+++ b/PokemonGo.RocketBot.Logic/Common/Translations.cs
@@ -78,6 +78,7 @@ namespace PokemonGo.RocketBot.Logic.Common
         LogEntryPkmn,
         LogEntryTransfered,
         LogEntryEvolved,
+        LogEntryLevelUp,
         LogEntryBerry,
         LogEntryEgg,
         LogEntryDebug,
@@ -640,6 +641,7 @@ namespace PokemonGo.RocketBot.Logic.Common
             new KeyValuePair<TranslationString, string>(TranslationString.LogEntryPkmn, "PKMN"),
             new KeyValuePair<TranslationString, string>(TranslationString.LogEntryTransfered, "TRANSFERRED"),
             new KeyValuePair<TranslationString, string>(TranslationString.LogEntryEvolved, "EVOLVED"),
+            new KeyValuePair<TranslationString, string>(TranslationString.LogEntryLevelUp, "LEVELUP"),
             new KeyValuePair<TranslationString, string>(TranslationString.LogEntryBerry, "BERRY"),
             new KeyValuePair<TranslationString, string>(TranslationString.LogEntryEgg, "EGG"),
             new KeyValuePair<TranslationString, string>(TranslationString.LogEntryDebug, "DEBUG"),
diff --git a/PokemonGo.RocketBot.Logic/Navigation.cs b/PokemonGo.RocketBot.Logic/Navigation.cs
index 1e7e1e5..f02e2a1 100644
--- a/PokemonGo.RocketBot.Logic/Navigation.cs
+++ b/PokemonGo.RocketBot.Logic/Navigation.cs
@@ -26,7 +26,7 @@ namespace PokemonGo.RocketBot.Logic

     public class Navigation
     {
-        private const double SpeedDownTo = 10/3.6;
+        private const double SpeedDownTo = 10 / 3.6;
         private readonly Client _client;
         private readonly Random _randWalking = new Random();
         private double _currentWalkingSpeed;
@@ -42,7 +42,7 @@ namespace PokemonGo.RocketBot.Logic
         {
             if (_lastMajorVariantWalkingSpeed == DateTime.MinValue && _nextMajorVariantWalkingSpeed == DateTime.MinValue)
             {
-                var minutes = _randWalking.NextDouble()*(2 - 6) + 2;
+                var minutes = _randWalking.NextDouble() * (2 - 6) + 2;
                 _lastMajorVariantWalkingSpeed = DateTime.Now;
                 _nextMajorVariantWalkingSpeed = _lastMajorVariantWalkingSpeed.AddMinutes(minutes);
                 _currentWalkingSpeed = session.LogicSettings.WalkingSpeedInKilometerPerHour;
@@ -55,9 +55,9 @@ namespace PokemonGo.RocketBot.Logic
                                 session.LogicSettings.WalkingSpeedVariant;
                 var randomMax = session.LogicSettings.WalkingSpeedInKilometerPerHour +
                                 session.LogicSettings.WalkingSpeedVariant;
-                _currentWalkingSpeed = _randWalking.NextDouble()*(randomMax - randomMin) + randomMin;
+                _currentWalkingSpeed = _randWalking.NextDouble() * (randomMax - randomMin) + randomMin;

-                var minutes = _randWalking.NextDouble()*(2 - 6) + 2;
+                var minutes = _randWalking.NextDouble() * (2 - 6) + 2;
                 _lastMajorVariantWalkingSpeed = DateTime.Now;
                 _nextMajorVariantWalkingSpeed = _lastMajorVariantWalkingSpeed.AddMinutes(minutes);

@@ -68,7 +68,7 @@ namespace PokemonGo.RocketBot.Logic
                 });
             }

-            return _currentWalkingSpeed/3.6;
+            return _currentWalkingSpeed / 3.6;
         }

         private double MinorWalkingSpeedVariant(ISession session)
@@ -82,7 +82,7 @@ namespace PokemonGo.RocketBot.Logic
                     var randomMax = session.LogicSettings.WalkingSpeedInKilometerPerHour +
                                     session.LogicSettings.WalkingSpeedVariant + 0.5;

-                    _currentWalkingSpeed += _randWalking.NextDouble()*(0.01 - 0.09) + 0.01;
+                    _currentWalkingSpeed += _randWalking.NextDouble() * (0.01 - 0.09) + 0.01;
                     if (_currentWalkingSpeed > randomMax)
                         _currentWalkingSpeed = randomMax;
                 }
@@ -91,7 +91,7 @@ namespace PokemonGo.RocketBot.Logic
                     var randomMin = session.LogicSettings.WalkingSpeedInKilometerPerHour -
                                     session.LogicSettings.WalkingSpeedVariant - 0.5;

-                    _currentWalkingSpeed -= _randWalking.NextDouble()*(0.01 - 0.09) + 0.01;
+                    _currentWalkingSpeed -= _randWalking.NextDouble() * (0.01 - 0.09) + 0.01;
                     if (_currentWalkingSpeed < randomMin)
                         _currentWalkingSpeed = randomMin;
                 }
@@ -106,7 +106,7 @@ namespace PokemonGo.RocketBot.Logic
                 }
             }

-            return _currentWalkingSpeed/3.6;
+            return _currentWalkingSpeed / 3.6;
         }

         private List<List<double>> Route(ISession session, GeoCoordinate start, GeoCoordinate dest)
@@ -181,8 +181,8 @@ namespace PokemonGo.RocketBot.Logic
                 else
                 {
                     lng += (sum & 1) == 1 ? ~(sum >> 1) : sum >> 1;
-                    coordinates.Add(lng/precision);
-                    coordinates.Add(lat/precision);
+                    coordinates.Add(lng / precision);
+                    coordinates.Add(lat / precision);
                     result.Add(coordinates);
                 }

@@ -195,10 +195,10 @@ namespace PokemonGo.RocketBot.Logic
         public async Task<PlayerUpdateResponse> Move(GeoCoordinate targetLocation,
             Func<Task<bool>> functionExecutedWhileWalking,
             ISession session,
-            CancellationToken cancellationToken)
+            CancellationToken cancellationToken, bool forceDisableHumanWalking = false)
         {
             cancellationToken.ThrowIfCancellationRequested();
-            if (!session.LogicSettings.DisableHumanWalking)
+            if (!session.LogicSettings.DisableHumanWalking && !forceDisableHumanWalking)
             {
                 PlayerUpdateResponse result = null;
                 var points = new List<GeoCoordinate>();
@@ -218,7 +218,7 @@ namespace PokemonGo.RocketBot.Logic
                 {
                     var speedInMetersPerSecond = session.LogicSettings.UseWalkingSpeedVariant
                         ? MajorWalkingSpeedVariant(session)
-                        : session.LogicSettings.WalkingSpeedInKilometerPerHour/3.6;
+                        : session.LogicSettings.WalkingSpeedInKilometerPerHour / 3.6;
                     var sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude);

                     var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, points.ToArray()[i]);
@@ -259,7 +259,7 @@ namespace PokemonGo.RocketBot.Logic
                             speedInMetersPerSecond = MinorWalkingSpeedVariant(session);

                         nextWaypointDistance = Math.Min(currentDistanceToTarget,
-                            millisecondsUntilGetUpdatePlayerLocationResponse/1000*speedInMetersPerSecond);
+                            millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
                         nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, points.ToArray()[i]);
                         waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance,
                             nextWaypointBearing);
@@ -289,7 +289,7 @@ namespace PokemonGo.RocketBot.Logic

                 var nextWaypointDistance = session.LogicSettings.UseWalkingSpeedVariant
                     ? MajorWalkingSpeedVariant(session)
-                    : session.LogicSettings.WalkingSpeedInKilometerPerHour/3.6;
+                    : session.LogicSettings.WalkingSpeedInKilometerPerHour / 3.6;
                 ;
                 ;
                 var waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
@@ -307,14 +307,15 @@ namespace PokemonGo.RocketBot.Logic
                 {
                     var speedInMetersPerSecond = session.LogicSettings.UseWalkingSpeedVariant
                         ? MajorWalkingSpeedVariant(session)
-                        : session.LogicSettings.WalkingSpeedInKilometerPerHour/3.6;
+                        : session.LogicSettings.WalkingSpeedInKilometerPerHour / 3.6;
                     cancellationToken.ThrowIfCancellationRequested();

                     var millisecondsUntilGetUpdatePlayerLocationResponse =
                         (DateTime.Now - requestSendDateTime).TotalMilliseconds;

                     sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude);
-                    var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
+                    var currentDistanceToTarget = LocationUtils.CalculateDistanceInMeters(sourceLocation,
+                        targetLocation);

                     if (currentDistanceToTarget < 40)
                     {
@@ -326,9 +327,10 @@ namespace PokemonGo.RocketBot.Logic
                     }

                     nextWaypointDistance = Math.Min(currentDistanceToTarget,
-                        millisecondsUntilGetUpdatePlayerLocationResponse/1000*speedInMetersPerSecond);
+                        millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
                     nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
-                    waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);
+                    waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance,
+                        nextWaypointBearing);

                     requestSendDateTime = DateTime.Now;
                     result =
@@ -360,7 +362,7 @@ namespace PokemonGo.RocketBot.Logic
                 Convert.ToDouble(trk.Lon, CultureInfo.InvariantCulture));
             var speedInMetersPerSecond = session.LogicSettings.UseWalkingSpeedVariant
                 ? MajorWalkingSpeedVariant(session)
-                : session.LogicSettings.WalkingSpeedInKilometerPerHour/3.6;
+                : session.LogicSettings.WalkingSpeedInKilometerPerHour / 3.6;
             var sourceLocation = new GeoCoordinate(_client.CurrentLatitude, _client.CurrentLongitude);
             LocationUtils.CalculateDistanceInMeters(sourceLocation, targetLocation);
             var nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
@@ -397,7 +399,7 @@ namespace PokemonGo.RocketBot.Logic
                     speedInMetersPerSecond = MinorWalkingSpeedVariant(session);

                 nextWaypointDistance = Math.Min(currentDistanceToTarget,
-                    millisecondsUntilGetUpdatePlayerLocationResponse/1000*speedInMetersPerSecond);
+                    millisecondsUntilGetUpdatePlayerLocationResponse / 1000 * speedInMetersPerSecond);
                 nextWaypointBearing = LocationUtils.DegreeBearing(sourceLocation, targetLocation);
                 waypoint = LocationUtils.CreateWaypoint(sourceLocation, nextWaypointDistance, nextWaypointBearing);

diff --git a/PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj b/PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj
index 43977d9..49b07a8 100644
--- a/PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj
+++ b/PokemonGo.RocketBot.Logic/PokemonGo.RocketBot.Logic.csproj
@@ -158,6 +158,7 @@
     <Compile Include="Tasks\GetPokeDexCount.cs" />
     <Compile Include="Tasks\InventoryListTask.cs" />
     <Compile Include="Tasks\LevelUpPokemonTask.cs" />
+    <Compile Include="Tasks\LevelUpSpecificPokemonTask.cs" />
     <Compile Include="Tasks\PokemonListTask.cs" />
     <Compile Include="Tasks\Farm.cs" />
     <Compile Include="Settings.cs" />
@@ -183,17 +184,21 @@
     <Compile Include="Tasks\FarmPokestopsTask.cs" />
     <Compile Include="Tasks\Login.cs" />
     <Compile Include="Tasks\RecycleItemsTask.cs" />
+    <Compile Include="Tasks\RecycleSpecificItemTask.cs" />
     <Compile Include="Tasks\RenamePokemonTask.cs" />
+    <Compile Include="Tasks\RenameSpecificPokemonTask.cs" />
     <Compile Include="Tasks\SnipePokemonTask.cs" />
     <Compile Include="Tasks\TransferDuplicatePokemonTask.cs" />
     <Compile Include="Event\UseLuckyEggEvent.cs" />
     <Compile Include="State\VersionCheckState.cs" />
     <Compile Include="Event\WarnEvent.cs" />
-    <Compile Include="Tasks\TransferPokemonTask.cs" />
+    <Compile Include="Tasks\TransferSpecificPokemonTask.cs" />
     <Compile Include="Tasks\TransferWeakPokemonTask.cs" />
     <Compile Include="Tasks\UseIncenseConstantlyTask.cs" />
+    <Compile Include="Tasks\UseIncenseTask.cs" />
     <Compile Include="Tasks\UseIncubatorsTask.cs" />
     <Compile Include="Tasks\UseLuckyEggConstantlyTask.cs" />
+    <Compile Include="Tasks\UseLuckyEggTask.cs" />
     <Compile Include="Tasks\UseNearbyPokestopsTask.cs" />
     <Compile Include="Utils\DelayingUtils.cs" />
     <Compile Include="Utils\DeviceInfoHelper.cs" />
diff --git a/PokemonGo.RocketBot.Logic/Settings.cs b/PokemonGo.RocketBot.Logic/Settings.cs
index 392bbd6..cd553d9 100644
--- a/PokemonGo.RocketBot.Logic/Settings.cs
+++ b/PokemonGo.RocketBot.Logic/Settings.cs
@@ -125,7 +125,7 @@ namespace PokemonGo.RocketBot.Logic
                 }
                 if (string.IsNullOrEmpty(DeviceId) || DeviceId == "8525f5d8201f78b5")
                     DeviceId = RandomString(16, "0123456789abcdef");
-                        // changed to random hex as full alphabet letters could have been flagged
+                // changed to random hex as full alphabet letters could have been flagged

                 // Jurann: Note that some device IDs I saw when adding devices had smaller numbers, only 12 or 14 chars instead of 16 - probably not important but noted here anyway

diff --git a/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs b/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
index cd8db01..a8ac497 100644
--- a/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
+++ b/PokemonGo.RocketBot.Logic/Tasks/FarmPokestopsTask.cs
@@ -83,8 +83,9 @@ namespace PokemonGo.RocketBot.Logic.Tasks

                 session.EventDispatcher.Send(new FortTargetEvent {Name = fortInfo.Name, Distance = distance});

-                await session.Navigation.Move(new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude,
-                    LocationUtils.getElevation(pokeStop.Latitude, pokeStop.Longitude)),
+                var targetLocation = new GeoCoordinate(pokeStop.Latitude, pokeStop.Longitude,
+                    LocationUtils.getElevation(pokeStop.Latitude, pokeStop.Longitude));
+                await session.Navigation.Move(targetLocation,
                     async () =>
                     {
                         // Catch normal map Pokemon
@@ -96,6 +97,12 @@ namespace PokemonGo.RocketBot.Logic.Tasks
                     session,
                     cancellationToken);

+                //Check if pokestop is in range, if not, move to pokestop without google routing
+                if (
+                    LocationUtils.CalculateDistanceInMeters(targetLocation,
+                        new GeoCoordinate(session.Client.CurrentLatitude, session.Client.CurrentLongitude)) >= 30)
+                    await session.Navigation.Move(targetLocation, null, session, cancellationToken, true);
+
                 //Catch Lure Pokemon
                 if (pokeStop.LureInfo != null)
                 {
diff --git a/PokemonGo.RocketBot.Logic/Tasks/LevelUpSpecificPokemonTask.cs b/PokemonGo.RocketBot.Logic/Tasks/LevelUpSpecificPokemonTask.cs
new file mode 100644
index 0000000..f895871
--- /dev/null
+++ b/PokemonGo.RocketBot.Logic/Tasks/LevelUpSpecificPokemonTask.cs
@@ -0,0 +1,29 @@
+using System.Threading.Tasks;
+using PokemonGo.RocketBot.Logic.Logging;
+using PokemonGo.RocketBot.Logic.State;
+using PokemonGo.RocketBot.Logic.Utils;
+using POGOProtos.Networking.Responses;
+
+namespace PokemonGo.RocketBot.Logic.Tasks
+{
+    public class LevelUpSpecificPokemonTask
+    {
+        public static async Task Execute(ISession session, ulong pokemonId)
+        {
+            var upgradeResult = await session.Inventory.UpgradePokemon(pokemonId);
+            if (upgradeResult.Result == UpgradePokemonResponse.Types.Result.Success)
+            {
+                Logger.Write("Pokemon Upgraded: " +
+                             session.Translation.GetPokemonTranslation(
+                                 upgradeResult.UpgradedPokemon.PokemonId) + ": " +
+                             upgradeResult.UpgradedPokemon.Cp, LogLevel.LevelUp);
+            }
+            else
+            {
+                Logger.Write("Pokemon Upgrade Failed.", LogLevel.Warning);
+            }
+
+            DelayingUtils.Delay(session.LogicSettings.DelayBetweenPlayerActions, 0);
+        }
+    }
+}
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Logic/Tasks/RecycleSpecificItemTask.cs b/PokemonGo.RocketBot.Logic/Tasks/RecycleSpecificItemTask.cs
new file mode 100644
index 0000000..d81a36f
--- /dev/null
+++ b/PokemonGo.RocketBot.Logic/Tasks/RecycleSpecificItemTask.cs
@@ -0,0 +1,28 @@
+using System.Threading.Tasks;
+using PokemonGo.RocketBot.Logic.Logging;
+using PokemonGo.RocketBot.Logic.State;
+using POGOProtos.Inventory.Item;
+using POGOProtos.Networking.Responses;
+
+namespace PokemonGo.RocketBot.Logic.Tasks
+{
+    public class RecycleSpecificItemTask
+    {
+        public static async Task Execute(Session session, ItemId itemId, int count)
+        {
+            var response = await session.Client.Inventory.RecycleItem(itemId, count);
+            if (response.Result == RecycleInventoryItemResponse.Types.Result.Success)
+            {
+                Logger.Write(
+                    $"Recycled {count}x {itemId.ToString().Substring(4)}",
+                    LogLevel.Recycling);
+            }
+            else
+            {
+                Logger.Write(
+                    $"Unable to recycle {count}x {itemId.ToString().Substring(4)}",
+                    LogLevel.Error);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Logic/Tasks/RenameSpecificPokemonTask.cs b/PokemonGo.RocketBot.Logic/Tasks/RenameSpecificPokemonTask.cs
new file mode 100644
index 0000000..2dfa195
--- /dev/null
+++ b/PokemonGo.RocketBot.Logic/Tasks/RenameSpecificPokemonTask.cs
@@ -0,0 +1,29 @@
+using System.Threading.Tasks;
+using PokemonGo.RocketBot.Logic.Logging;
+using PokemonGo.RocketBot.Logic.State;
+using PokemonGo.RocketBot.Logic.Utils;
+using POGOProtos.Data;
+using POGOProtos.Networking.Responses;
+
+namespace PokemonGo.RocketBot.Logic.Tasks
+{
+    public class RenameSpecificPokemonTask
+    {
+        public static async Task Execute(Session session, PokemonData pokemon, string newNickname)
+        {
+            //var pkm = pokemon;
+            var response = await session.Client.Inventory.NicknamePokemon(pokemon.Id, newNickname);
+            Logger.Write(response.Result == NicknamePokemonResponse.Types.Result.Success
+                ? $"Successfully renamed {pokemon.PokemonId} to \"{newNickname}\""
+                : $"Failed renaming {pokemon.PokemonId} to \"{newNickname}\"");
+            DelayingUtils.Delay(session.LogicSettings.DelayBetweenPlayerActions, 0);
+            //session.EventDispatcher.Send(new NoticeEvent
+            //{
+            //    Message =
+            //        session.Translation.GetTranslation(TranslationString.PokemonRename,
+            //            session.Translation.GetPokemonTranslation(pokemon.PokemonId),
+            //            pokemon.PokemonId, pkm.Nickname, newNickname)
+            //});
+        }
+    }
+}
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Logic/Tasks/TransferPokemonTask.cs b/PokemonGo.RocketBot.Logic/Tasks/TransferSpecificPokemonTask.cs
similarity index 97%
rename from PokemonGo.RocketBot.Logic/Tasks/TransferPokemonTask.cs
rename to PokemonGo.RocketBot.Logic/Tasks/TransferSpecificPokemonTask.cs
index 0a3e8b0..0480845 100644
--- a/PokemonGo.RocketBot.Logic/Tasks/TransferPokemonTask.cs
+++ b/PokemonGo.RocketBot.Logic/Tasks/TransferSpecificPokemonTask.cs
@@ -11,7 +11,7 @@ using PokemonGo.RocketBot.Logic.Utils;

 namespace PokemonGo.RocketBot.Logic.Tasks
 {
-    public class TransferPokemonTask
+    public class TransferSpecificPokemonTask
     {
         public static async Task Execute(ISession session, ulong pokemonId)
         {
diff --git a/PokemonGo.RocketBot.Logic/Tasks/UseIncenseTask.cs b/PokemonGo.RocketBot.Logic/Tasks/UseIncenseTask.cs
new file mode 100644
index 0000000..6f46467
--- /dev/null
+++ b/PokemonGo.RocketBot.Logic/Tasks/UseIncenseTask.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Threading.Tasks;
+using PokemonGo.RocketBot.Logic.Logging;
+using PokemonGo.RocketBot.Logic.State;
+using POGOProtos.Inventory.Item;
+using POGOProtos.Networking.Responses;
+
+namespace PokemonGo.RocketBot.Logic.Tasks
+{
+    public class UseIncenseTask
+    {
+        public static async Task Execute(Session session)
+        {
+            var response = await session.Client.Inventory.UseIncense(ItemId.ItemIncenseOrdinary);
+            switch (response.Result)
+            {
+                case UseIncenseResponse.Types.Result.Success:
+                    Logger.Write($"Incense valid until: {DateTime.Now.AddMinutes(30)}");
+                    break;
+                case UseIncenseResponse.Types.Result.IncenseAlreadyActive:
+                    Logger.Write($"An incense is already active!", LogLevel.Warning);
+                    break;
+                case UseIncenseResponse.Types.Result.LocationUnset:
+                    Logger.Write($"Bot must be running first!", LogLevel.Error);
+                    break;
+                case UseIncenseResponse.Types.Result.Unknown:
+                    break;
+                case UseIncenseResponse.Types.Result.NoneInInventory:
+                    break;
+                default:
+                    Logger.Write($"Failed using an incense!", LogLevel.Error);
+                    break;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Logic/Tasks/UseLuckyEggTask.cs b/PokemonGo.RocketBot.Logic/Tasks/UseLuckyEggTask.cs
new file mode 100644
index 0000000..257182c
--- /dev/null
+++ b/PokemonGo.RocketBot.Logic/Tasks/UseLuckyEggTask.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Threading.Tasks;
+using PokemonGo.RocketBot.Logic.Logging;
+using PokemonGo.RocketBot.Logic.State;
+using POGOProtos.Networking.Responses;
+
+namespace PokemonGo.RocketBot.Logic.Tasks
+{
+    public class UseLuckyEggTask
+    {
+        public static async Task Execute(Session session)
+        {
+            var response = await session.Client.Inventory.UseItemXpBoost();
+            switch (response.Result)
+            {
+                case UseItemXpBoostResponse.Types.Result.Success:
+                    Logger.Write($"Using a Lucky Egg");
+                    Logger.Write($"Lucky Egg valid until: {DateTime.Now.AddMinutes(30)}");
+                    break;
+                case UseItemXpBoostResponse.Types.Result.ErrorXpBoostAlreadyActive:
+                    Logger.Write($"A Lucky Egg is already active!", LogLevel.Warning);
+                    break;
+                case UseItemXpBoostResponse.Types.Result.ErrorLocationUnset:
+                    Logger.Write($"Bot must be running first!", LogLevel.Error);
+                    break;
+                case UseItemXpBoostResponse.Types.Result.Unset:
+                    break;
+                case UseItemXpBoostResponse.Types.Result.ErrorInvalidItemType:
+                    break;
+                case UseItemXpBoostResponse.Types.Result.ErrorNoItemsRemaining:
+                    break;
+                default:
+                    Logger.Write($"Failed using a Lucky Egg!", LogLevel.Error);
+                    break;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Window/ConsoleLogger.cs b/PokemonGo.RocketBot.Window/ConsoleLogger.cs
index bbc62e3..c478151 100644
--- a/PokemonGo.RocketBot.Window/ConsoleLogger.cs
+++ b/PokemonGo.RocketBot.Window/ConsoleLogger.cs
@@ -96,6 +96,10 @@ namespace PokemonGo.RocketBot.Window
                     MainForm.ColoredConsoleWrite(Color.Yellow,
                         $"[{DateTime.Now.ToString("HH:mm:ss")}] ({LoggingStrings.Evolved}) {message}");
                     break;
+                case LogLevel.LevelUp:
+                    MainForm.ColoredConsoleWrite(Color.Yellow,
+                        $"[{DateTime.Now.ToString("HH:mm:ss")}] ({LoggingStrings.LevelUp}) {message}");
+                    break;
                 case LogLevel.Berry:
                     MainForm.ColoredConsoleWrite(Color.DarkGoldenrod,
                         $"[{DateTime.Now.ToString("HH:mm:ss")}] ({LoggingStrings.Berry}) {message}");
diff --git a/PokemonGo.RocketBot.Window/Forms/MainForm.cs b/PokemonGo.RocketBot.Window/Forms/MainForm.cs
index 948aa8b..9af0793 100644
--- a/PokemonGo.RocketBot.Window/Forms/MainForm.cs
+++ b/PokemonGo.RocketBot.Window/Forms/MainForm.cs
@@ -36,7 +36,6 @@ using POGOProtos.Inventory;
 using POGOProtos.Inventory.Item;
 using POGOProtos.Map.Fort;
 using POGOProtos.Map.Pokemon;
-using POGOProtos.Networking.Responses;
 using Segment;
 using Segment.Model;
 using Logger = PokemonGo.RocketBot.Logic.Logging.Logger;
@@ -210,31 +209,31 @@ namespace PokemonGo.RocketBot.Window.Forms
             Logger.SetLoggerContext(_session);

             _session.Navigation.UpdatePositionEvent +=
-                (lat, lng) => _session.EventDispatcher.Send(new UpdatePositionEvent { Latitude = lat, Longitude = lng });
+                (lat, lng) => _session.EventDispatcher.Send(new UpdatePositionEvent {Latitude = lat, Longitude = lng});
             _session.Navigation.UpdatePositionEvent += Navigation_UpdatePositionEvent;

             RouteOptimizeUtil.RouteOptimizeEvent +=
                 optimizedroute =>
-                    _session.EventDispatcher.Send(new OptimizeRouteEvent { OptimizedRoute = optimizedroute });
+                    _session.EventDispatcher.Send(new OptimizeRouteEvent {OptimizedRoute = optimizedroute});
             RouteOptimizeUtil.RouteOptimizeEvent += InitializePokestopsAndRoute;

             Navigation.GetHumanizeRouteEvent +=
                 (route, destination) =>
-                    _session.EventDispatcher.Send(new GetHumanizeRouteEvent { Route = route, Destination = destination });
+                    _session.EventDispatcher.Send(new GetHumanizeRouteEvent {Route = route, Destination = destination});
             Navigation.GetHumanizeRouteEvent += UpdateMap;

             FarmPokestopsTask.LootPokestopEvent +=
-                pokestop => _session.EventDispatcher.Send(new LootPokestopEvent { Pokestop = pokestop });
+                pokestop => _session.EventDispatcher.Send(new LootPokestopEvent {Pokestop = pokestop});
             FarmPokestopsTask.LootPokestopEvent += UpdateMap;

             CatchNearbyPokemonsTask.PokemonEncounterEvent +=
                 mappokemons =>
-                    _session.EventDispatcher.Send(new PokemonsEncounterEvent { EncounterPokemons = mappokemons });
+                    _session.EventDispatcher.Send(new PokemonsEncounterEvent {EncounterPokemons = mappokemons});
             CatchNearbyPokemonsTask.PokemonEncounterEvent += UpdateMap;

             CatchIncensePokemonsTask.PokemonEncounterEvent +=
                 mappokemons =>
-                    _session.EventDispatcher.Send(new PokemonsEncounterEvent { EncounterPokemons = mappokemons });
+                    _session.EventDispatcher.Send(new PokemonsEncounterEvent {EncounterPokemons = mappokemons});
             CatchIncensePokemonsTask.PokemonEncounterEvent += UpdateMap;
         }

@@ -263,8 +262,8 @@ namespace PokemonGo.RocketBot.Window.Forms
                 _playerLocations.Clear();
                 var routePoint =
                     (from pokeStop in pokeStops
-                     where pokeStop != null
-                     select new PointLatLng(pokeStop.Latitude, pokeStop.Longitude)).ToList();
+                        where pokeStop != null
+                        select new PointLatLng(pokeStop.Latitude, pokeStop.Longitude)).ToList();

                 _routePoints = routePoint;
                 togglePrecalRoute.Enabled = true;
@@ -285,107 +284,6 @@ namespace PokemonGo.RocketBot.Window.Forms
             }, null);
         }

-        private void UpdateMap()
-        {
-            SynchronizationContext.Post(o =>
-            {
-                var route = new GMapRoute(_playerLocations, "step")
-                {
-                    Stroke = new Pen(Color.FromArgb(175, 175, 175), 2) { DashStyle = DashStyle.Dot }
-                };
-                _playerOverlay.Routes.Clear();
-                _playerOverlay.Routes.Add(route);
-            }, null);
-        }
-
-        private void UpdateMap(List<GeoCoordinate> route, GeoCoordinate destination)
-        {
-            var routePointLatLngs = new List<PointLatLng>();
-            foreach (var item in route)
-            {
-                routePointLatLngs.Add(new PointLatLng(item.Latitude, item.Longitude));
-            }
-            var routes = new GMapRoute(routePointLatLngs, routePointLatLngs.ToString())
-            {
-                Stroke = new Pen(Color.FromArgb(128, 0, 179, 253), 4) { DashStyle = DashStyle.Dash }
-            };
-            _playerRouteOverlay.Routes.Add(routes);
-            /* Logger.Write("new call");
-             List<PointLatLng> routePointLatLngs = new List<PointLatLng>();
-             Logger.Write("new route size: " +route.Count);
-             PointLatLng destinationPointLatLng = new PointLatLng(destination.Latitude, destination.Longitude);
-             foreach (var item in route)
-             {
-                 routePointLatLngs.Add(new PointLatLng(item.Latitude, item.Longitude));
-             }
-
-             List<PointLatLng> routePointsDistinct = new List<PointLatLng>(_routePoints.Distinct());
-
-             int listPosition;
-             for (listPosition = 0; listPosition < routePointsDistinct.Count; listPosition++)
-             {
-                 Logger.Write("listPosition: " + listPosition);
-                 var item = routePointsDistinct[listPosition];
-                 if (item == destinationPointLatLng)
-                     break;
-             }
-
-             if (listPosition == 0)
-                 return;
-
-             //routePointsDistinct.Remove(destinationPointLatLng);
-             routePointsDistinct.InsertRange(listPosition, routePointLatLngs);
-             //routePointsDistinct.Remove(routePointsDistinct[listPosition - 1]);
-
-
-             _pokestopsOverlay.Routes.Clear();
-             var routes = new GMapRoute(routePointsDistinct, "Walking Path")
-             {
-                 Stroke = new Pen(Color.FromArgb(128, 0, 179, 253), 4)
-             };
-             _pokestopsOverlay.Routes.Add(routes);*/
-        }
-
-        private void UpdateMap(FortData pokestop)
-        {
-            SynchronizationContext.Post(o =>
-            {
-                var pokeStopLoc = new PointLatLng(pokestop.Latitude, pokestop.Longitude);
-
-                lock (_pokestopsOverlay.Markers)
-                {
-                    for (var i = 0; i < _pokestopsOverlay.Markers.Count; i++)
-                    {
-                        var marker = _pokestopsOverlay.Markers[i];
-                        if (marker.Position == pokeStopLoc)
-                            _pokestopsOverlay.Markers.Remove(marker);
-                    }
-                }
-
-                GMapMarker pokestopMarker = new GMapMarkerPokestops(pokeStopLoc,
-                    ResourceHelper.GetImage("Pokestop_looted"));
-                //pokestopMarker.ToolTipMode = MarkerTooltipMode.OnMouseOver;
-                //pokestopMarker.ToolTip = new GMapBaloonToolTip(pokestopMarker);
-                _pokestopsOverlay.Markers.Add(pokestopMarker);
-            }, null);
-        }
-
-        private void UpdateMap(List<MapPokemon> encounterPokemons)
-        {
-            SynchronizationContext.Post(o =>
-            {
-                _pokemonsOverlay.Markers.Clear();
-
-                foreach (var pokemon in encounterPokemons)
-                {
-                    var pkmImage = ResourceHelper.GetImage("Pokemon_" + pokemon.PokemonId.GetHashCode(), 50, 50);
-                    var pointLatLng = new PointLatLng(pokemon.Latitude, pokemon.Longitude);
-                    GMapMarker pkmMarker = new GMapMarkerTrainer(pointLatLng, pkmImage);
-                    _pokemonsOverlay.Markers.Add(pkmMarker);
-                }
-            }, null);
-        }
-
         private void Navigation_UpdatePositionEvent(double lat, double lng)
         {
             var latlng = new PointLatLng(lat, lng);
@@ -459,14 +357,6 @@ namespace PokemonGo.RocketBot.Window.Forms
                         "https://raw.githubusercontent.com/TheUnnameOrganization/RocketBot/Beta-Build/src/RocketBotGUI/Properties/AssemblyInfo.cs");
         }

-        private void olvPokemonList_SelectedIndexChanged(object sender, EventArgs e)
-        {
-        }
-
-        private void gMapControl1_Load(object sender, EventArgs e)
-        {
-        }
-
         private void showMoreCheckBox_CheckedChanged(object sender, EventArgs e)
         {
             if (showMoreCheckBox.Checked)
@@ -511,6 +401,111 @@ namespace PokemonGo.RocketBot.Window.Forms
             }
         }

+        #region UPDATEMAP
+
+        private void UpdateMap()
+        {
+            SynchronizationContext.Post(o =>
+            {
+                var route = new GMapRoute(_playerLocations, "step")
+                {
+                    Stroke = new Pen(Color.FromArgb(175, 175, 175), 2) {DashStyle = DashStyle.Dot}
+                };
+                _playerOverlay.Routes.Clear();
+                _playerOverlay.Routes.Add(route);
+            }, null);
+        }
+
+        private void UpdateMap(List<GeoCoordinate> route, GeoCoordinate destination)
+        {
+            var routePointLatLngs = new List<PointLatLng>();
+            foreach (var item in route)
+            {
+                routePointLatLngs.Add(new PointLatLng(item.Latitude, item.Longitude));
+            }
+            var routes = new GMapRoute(routePointLatLngs, routePointLatLngs.ToString())
+            {
+                Stroke = new Pen(Color.FromArgb(128, 0, 179, 253), 4) {DashStyle = DashStyle.Dash}
+            };
+            _playerRouteOverlay.Routes.Add(routes);
+            /* Logger.Write("new call");
+             List<PointLatLng> routePointLatLngs = new List<PointLatLng>();
+             Logger.Write("new route size: " +route.Count);
+             PointLatLng destinationPointLatLng = new PointLatLng(destination.Latitude, destination.Longitude);
+             foreach (var item in route)
+             {
+                 routePointLatLngs.Add(new PointLatLng(item.Latitude, item.Longitude));
+             }
+
+             List<PointLatLng> routePointsDistinct = new List<PointLatLng>(_routePoints.Distinct());
+
+             int listPosition;
+             for (listPosition = 0; listPosition < routePointsDistinct.Count; listPosition++)
+             {
+                 Logger.Write("listPosition: " + listPosition);
+                 var item = routePointsDistinct[listPosition];
+                 if (item == destinationPointLatLng)
+                     break;
+             }
+
+             if (listPosition == 0)
+                 return;
+
+             //routePointsDistinct.Remove(destinationPointLatLng);
+             routePointsDistinct.InsertRange(listPosition, routePointLatLngs);
+             //routePointsDistinct.Remove(routePointsDistinct[listPosition - 1]);
+
+
+             _pokestopsOverlay.Routes.Clear();
+             var routes = new GMapRoute(routePointsDistinct, "Walking Path")
+             {
+                 Stroke = new Pen(Color.FromArgb(128, 0, 179, 253), 4)
+             };
+             _pokestopsOverlay.Routes.Add(routes);*/
+        }
+
+        private void UpdateMap(FortData pokestop)
+        {
+            SynchronizationContext.Post(o =>
+            {
+                var pokeStopLoc = new PointLatLng(pokestop.Latitude, pokestop.Longitude);
+
+                lock (_pokestopsOverlay.Markers)
+                {
+                    for (var i = 0; i < _pokestopsOverlay.Markers.Count; i++)
+                    {
+                        var marker = _pokestopsOverlay.Markers[i];
+                        if (marker.Position == pokeStopLoc)
+                            _pokestopsOverlay.Markers.Remove(marker);
+                    }
+                }
+
+                GMapMarker pokestopMarker = new GMapMarkerPokestops(pokeStopLoc,
+                    ResourceHelper.GetImage("Pokestop_looted"));
+                //pokestopMarker.ToolTipMode = MarkerTooltipMode.OnMouseOver;
+                //pokestopMarker.ToolTip = new GMapBaloonToolTip(pokestopMarker);
+                _pokestopsOverlay.Markers.Add(pokestopMarker);
+            }, null);
+        }
+
+        private void UpdateMap(List<MapPokemon> encounterPokemons)
+        {
+            SynchronizationContext.Post(o =>
+            {
+                _pokemonsOverlay.Markers.Clear();
+
+                foreach (var pokemon in encounterPokemons)
+                {
+                    var pkmImage = ResourceHelper.GetImage("Pokemon_" + pokemon.PokemonId.GetHashCode(), 50, 50);
+                    var pointLatLng = new PointLatLng(pokemon.Latitude, pokemon.Longitude);
+                    GMapMarker pkmMarker = new GMapMarkerTrainer(pointLatLng, pkmImage);
+                    _pokemonsOverlay.Markers.Add(pkmMarker);
+                }
+            }, null);
+        }
+
+        #endregion
+
         #region INTERFACE

         public static void ColoredConsoleWrite(Color color, string text)
@@ -594,7 +589,7 @@ namespace PokemonGo.RocketBot.Window.Forms
         {
             //olvPokemonList.ButtonClick += PokemonListButton_Click;

-            pkmnName.ImageGetter = delegate (object rowObject)
+            pkmnName.ImageGetter = delegate(object rowObject)
             {
                 var pokemon = rowObject as PokemonObject;

@@ -602,13 +597,13 @@ namespace PokemonGo.RocketBot.Window.Forms
                 var key = pokemon.PokemonId.ToString();
                 if (!olvPokemonList.SmallImageList.Images.ContainsKey(key))
                 {
-                    var img = GetPokemonImage((int)pokemon.PokemonId);
+                    var img = ResourceHelper.GetPokemonImage((int) pokemon.PokemonId);
                     olvPokemonList.SmallImageList.Images.Add(key, img);
                 }
                 return key;
             };

-            olvPokemonList.FormatRow += delegate (object sender, FormatRowEventArgs e)
+            olvPokemonList.FormatRow += delegate(object sender, FormatRowEventArgs e)
             {
                 var pok = e.Model as PokemonObject;
                 if (olvPokemonList.Objects
@@ -628,7 +623,7 @@ namespace PokemonGo.RocketBot.Window.Forms
                 }
             };

-            cmsPokemonList.Opening += delegate (object sender, CancelEventArgs e)
+            cmsPokemonList.Opening += delegate(object sender, CancelEventArgs e)
             {
                 e.Cancel = false;
                 cmsPokemonList.Items.Clear();
@@ -651,7 +646,7 @@ namespace PokemonGo.RocketBot.Window.Forms
                 item.Click += delegate { TransferPokemon(pokemons); };
                 cmsPokemonList.Items.Add(item);

-                item = new ToolStripMenuItem { Text = @"Rename" };
+                item = new ToolStripMenuItem {Text = @"Rename"};
                 item.Click += delegate
                 {
                     using (var form = count == 1 ? new NicknamePokemonForm(pokemonObject) : new NicknamePokemonForm())
@@ -666,30 +661,30 @@ namespace PokemonGo.RocketBot.Window.Forms

                 if (canAllEvolve)
                 {
-                    item = new ToolStripMenuItem { Text = $"Evolve {count} pokemon" };
+                    item = new ToolStripMenuItem {Text = $"Evolve {count} pokemon"};
                     item.Click += delegate { EvolvePokemon(pokemons); };
                     cmsPokemonList.Items.Add(item);
                 }

                 if (count != 1) return;
-                item = new ToolStripMenuItem { Text = @"PowerUp" };
+                item = new ToolStripMenuItem {Text = @"PowerUp"};
                 item.Click += delegate { PowerUpPokemon(pokemons); };
                 cmsPokemonList.Items.Add(item);
                 cmsPokemonList.Items.Add(separator);

-                item = new ToolStripMenuItem { Text = @"Transfer Clean Up (Keep highest IV)" };
+                item = new ToolStripMenuItem {Text = @"Transfer Clean Up (Keep highest IV)"};
                 item.Click += delegate { CleanUpTransferPokemon(pokemonObject, "IV"); };
                 cmsPokemonList.Items.Add(item);

-                item = new ToolStripMenuItem { Text = @"Transfer Clean Up (Keep highest CP)" };
+                item = new ToolStripMenuItem {Text = @"Transfer Clean Up (Keep highest CP)"};
                 item.Click += delegate { CleanUpTransferPokemon(pokemonObject, "CP"); };
                 cmsPokemonList.Items.Add(item);

-                item = new ToolStripMenuItem { Text = @"Evolve Clean Up (Highest IV)" };
+                item = new ToolStripMenuItem {Text = @"Evolve Clean Up (Highest IV)"};
                 item.Click += delegate { CleanUpEvolvePokemon(pokemonObject, "IV"); };
                 cmsPokemonList.Items.Add(item);

-                item = new ToolStripMenuItem { Text = @"Evolve Clean Up (Highest CP)" };
+                item = new ToolStripMenuItem {Text = @"Evolve Clean Up (Highest CP)"};
                 item.Click += delegate { CleanUpEvolvePokemon(pokemonObject, "CP"); };
                 cmsPokemonList.Items.Add(item);

@@ -706,17 +701,17 @@ namespace PokemonGo.RocketBot.Window.Forms
                 if (cName.Equals("Transfer"))
                 {
                     // ReSharper disable once PossibleNullReferenceException
-                    TransferPokemon(new List<PokemonData> { pokemon.PokemonData });
+                    TransferPokemon(new List<PokemonData> {pokemon.PokemonData});
                 }
                 else if (cName.Equals("Power Up"))
                 {
                     // ReSharper disable once PossibleNullReferenceException
-                    PowerUpPokemon(new List<PokemonData> { pokemon.PokemonData });
+                    PowerUpPokemon(new List<PokemonData> {pokemon.PokemonData});
                 }
                 else if (cName.Equals("Evolve"))
                 {
                     // ReSharper disable once PossibleNullReferenceException
-                    EvolvePokemon(new List<PokemonData> { pokemon.PokemonData });
+                    EvolvePokemon(new List<PokemonData> {pokemon.PokemonData});
                 }
             }
             catch (Exception ex)
@@ -731,17 +726,7 @@ namespace PokemonGo.RocketBot.Window.Forms
             SetState(false);
             foreach (var pokemon in pokemons)
             {
-                var transferPokemonResponse = await _session.Client.Inventory.TransferPokemon(pokemon.Id);
-                if (transferPokemonResponse.Result == ReleasePokemonResponse.Types.Result.Success)
-                {
-                    Logger.Write(
-                        $"{pokemon.PokemonId} was transferred. {transferPokemonResponse.CandyAwarded} candy awarded",
-                        LogLevel.Transfer);
-                }
-                else
-                {
-                    Logger.Write($"{pokemon.PokemonId} could not be transferred", LogLevel.Error);
-                }
+                await TransferSpecificPokemonTask.Execute(_session, pokemon.Id);
             }
             await ReloadPokemonList();
         }
@@ -751,15 +736,7 @@ namespace PokemonGo.RocketBot.Window.Forms
             SetState(false);
             foreach (var pokemon in pokemons)
             {
-                var evolvePokemonResponse = await _session.Client.Inventory.UpgradePokemon(pokemon.Id);
-                if (evolvePokemonResponse.Result == UpgradePokemonResponse.Types.Result.Success)
-                {
-                    Logger.Write($"{pokemon.PokemonId} successfully upgraded.");
-                }
-                else
-                {
-                    Logger.Write($"{pokemon.PokemonId} could not be upgraded");
-                }
+                await LevelUpSpecificPokemonTask.Execute(_session, pokemon.Id);
             }
             await ReloadPokemonList();
         }
@@ -769,16 +746,7 @@ namespace PokemonGo.RocketBot.Window.Forms
             SetState(false);
             foreach (var pokemon in pokemons)
             {
-                var evolvePokemonResponse = await _session.Client.Inventory.EvolvePokemon(pokemon.Id);
-                if (evolvePokemonResponse.Result == EvolvePokemonResponse.Types.Result.Success)
-                {
-                    Logger.Write(
-                        $"{pokemon.PokemonId} successfully evolved into {evolvePokemonResponse.EvolvedPokemonData.PokemonId}\n{evolvePokemonResponse.ExperienceAwarded} experience awarded\n{evolvePokemonResponse.CandyAwarded} candy awarded");
-                }
-                else
-                {
-                    Logger.Write($"{pokemon.PokemonId} could not be evolved");
-                }
+                await EvolveSpecificPokemonTask.Execute(_session, pokemon.Id);
             }
             await ReloadPokemonList();
         }
@@ -886,25 +854,11 @@ namespace PokemonGo.RocketBot.Window.Forms
                     }
                     continue;
                 }
-                var response = await _session.Client.Inventory.NicknamePokemon(pokemon.Id, newName.ToString());
-                if (response.Result == NicknamePokemonResponse.Types.Result.Success)
-                {
-                    Logger.Write($"Successfully renamed {pokemon.PokemonId} to \"{newName}\"");
-                }
-                else
-                {
-                    Logger.Write($"Failed renaming {pokemon.PokemonId} to \"{newName}\"");
-                }
-                await Task.Delay(1500);
+                await RenameSpecificPokemonTask.Execute(_session, pokemon, nickname);
             }
             await ReloadPokemonList();
         }

-        private Image GetPokemonImage(int pokemonId)
-        {
-            return ResourceHelper.GetImage("Pokemon_" + pokemonId);
-        }
-
         private async Task ReloadPokemonList()
         {
             SetState(false);
@@ -939,7 +893,7 @@ namespace PokemonGo.RocketBot.Window.Forms
                 foreach (var pokemon in pokemons)
                 {
                     var pokemonObject = new PokemonObject(pokemon);
-                    var family = _families.First(i => (int)i.FamilyId <= (int)pokemon.PokemonId);
+                    var family = _families.First(i => (int) i.FamilyId <= (int) pokemon.PokemonId);
                     pokemonObject.Candy = family.Candy_;
                     pokemonObjects.Add(pokemonObject);
                 }
@@ -999,7 +953,7 @@ namespace PokemonGo.RocketBot.Window.Forms

         private async void ItemBox_ItemClick(object sender, EventArgs e)
         {
-            var item = (ItemData)sender;
+            var item = (ItemData) sender;

             using (var form = new ItemForm(item))
             {
@@ -1009,142 +963,32 @@ namespace PokemonGo.RocketBot.Window.Forms
                 switch (item.ItemId)
                 {
                     case ItemId.ItemLuckyEgg:
+                    {
+                        if (_session.Client == null)
                         {
-                            if (_session.Client == null)
-                            {
-                                Logger.Write($"Bot must be running first!", LogLevel.Warning);
-                                SetState(true);
-                                return;
-                            }
-                            var response = await _session.Client.Inventory.UseItemXpBoost();
-                            switch (response.Result)
-                            {
-                                case UseItemXpBoostResponse.Types.Result.Success:
-                                    Logger.Write($"Using a Lucky Egg");
-                                    Logger.Write($"Lucky Egg valid until: {DateTime.Now.AddMinutes(30)}");
-                                    break;
-                                case UseItemXpBoostResponse.Types.Result.ErrorXpBoostAlreadyActive:
-                                    Logger.Write($"A Lucky Egg is already active!", LogLevel.Warning);
-                                    break;
-                                case UseItemXpBoostResponse.Types.Result.ErrorLocationUnset:
-                                    Logger.Write($"Bot must be running first!", LogLevel.Error);
-                                    break;
-                                case UseItemXpBoostResponse.Types.Result.Unset:
-                                    break;
-                                case UseItemXpBoostResponse.Types.Result.ErrorInvalidItemType:
-                                    break;
-                                case UseItemXpBoostResponse.Types.Result.ErrorNoItemsRemaining:
-                                    break;
-                                default:
-                                    Logger.Write($"Failed using a Lucky Egg!", LogLevel.Error);
-                                    break;
-                            }
+                            Logger.Write($"Bot must be running first!", LogLevel.Warning);
+                            SetState(true);
+                            return;
                         }
+                        await UseLuckyEggTask.Execute(_session);
+                    }
                         break;
                     case ItemId.ItemIncenseOrdinary:
+                    {
+                        if (_session.Client == null)
                         {
-                            if (_session.Client == null)
-                            {
-                                Logger.Write($"Bot must be running first!", LogLevel.Error);
-                                SetState(true);
-                                return;
-                            }
-                            var response = await _session.Client.Inventory.UseIncense(ItemId.ItemIncenseOrdinary);
-                            switch (response.Result)
-                            {
-                                case UseIncenseResponse.Types.Result.Success:
-                                    Logger.Write($"Incense valid until: {DateTime.Now.AddMinutes(30)}");
-                                    break;
-                                case UseIncenseResponse.Types.Result.IncenseAlreadyActive:
-                                    Logger.Write($"An incense is already active!", LogLevel.Warning);
-                                    break;
-                                case UseIncenseResponse.Types.Result.LocationUnset:
-                                    Logger.Write($"Bot must be running first!", LogLevel.Error);
-                                    break;
-                                case UseIncenseResponse.Types.Result.Unknown:
-                                    break;
-                                case UseIncenseResponse.Types.Result.NoneInInventory:
-                                    break;
-                                default:
-                                    Logger.Write($"Failed using an incense!", LogLevel.Error);
-                                    break;
-                            }
+                            Logger.Write($"Bot must be running first!", LogLevel.Error);
+                            SetState(true);
+                            return;
                         }
-                        break;
-                    case ItemId.ItemUnknown:
-                        break;
-                    case ItemId.ItemPokeBall:
-                        break;
-                    case ItemId.ItemGreatBall:
-                        break;
-                    case ItemId.ItemUltraBall:
-                        break;
-                    case ItemId.ItemMasterBall:
-                        break;
-                    case ItemId.ItemPotion:
-                        break;
-                    case ItemId.ItemSuperPotion:
-                        break;
-                    case ItemId.ItemHyperPotion:
-                        break;
-                    case ItemId.ItemMaxPotion:
-                        break;
-                    case ItemId.ItemRevive:
-                        break;
-                    case ItemId.ItemMaxRevive:
-                        break;
-                    case ItemId.ItemIncenseSpicy:
-                        break;
-                    case ItemId.ItemIncenseCool:
-                        break;
-                    case ItemId.ItemIncenseFloral:
-                        break;
-                    case ItemId.ItemTroyDisk:
-                        break;
-                    case ItemId.ItemXAttack:
-                        break;
-                    case ItemId.ItemXDefense:
-                        break;
-                    case ItemId.ItemXMiracle:
-                        break;
-                    case ItemId.ItemRazzBerry:
-                        break;
-                    case ItemId.ItemBlukBerry:
-                        break;
-                    case ItemId.ItemNanabBerry:
-                        break;
-                    case ItemId.ItemWeparBerry:
-                        break;
-                    case ItemId.ItemPinapBerry:
-                        break;
-                    case ItemId.ItemSpecialCamera:
-                        break;
-                    case ItemId.ItemIncubatorBasicUnlimited:
-                        break;
-                    case ItemId.ItemIncubatorBasic:
-                        break;
-                    case ItemId.ItemPokemonStorageUpgrade:
-                        break;
-                    case ItemId.ItemItemStorageUpgrade:
+                        await UseIncenseTask.Execute(_session);
+                    }
                         break;
                     default:
-                        {
-                            var response =
-                                await
-                                    _session.Client.Inventory.RecycleItem(item.ItemId, decimal.ToInt32(form.numCount.Value));
-                            if (response.Result == RecycleInventoryItemResponse.Types.Result.Success)
-                            {
-                                Logger.Write(
-                                    $"Recycled {decimal.ToInt32(form.numCount.Value)}x {item.ItemId.ToString().Substring(4)}",
-                                    LogLevel.Recycling);
-                            }
-                            else
-                            {
-                                Logger.Write(
-                                    $"Unable to recycle {decimal.ToInt32(form.numCount.Value)}x {item.ItemId.ToString().Substring(4)}",
-                                    LogLevel.Error);
-                            }
-                        }
+                    {
+                        await
+                            RecycleSpecificItemTask.Execute(_session, item.ItemId, decimal.ToInt32(form.numCount.Value));
+                    }
                         break;
                 }
                 await ReloadPokemonList();
diff --git a/PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs b/PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs
index d01589c..da0c4bc 100644
--- a/PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs
+++ b/PokemonGo.RocketBot.Window/Forms/MainForm.designer.cs
@@ -180,7 +180,6 @@ namespace PokemonGo.RocketBot.Window.Forms
             this.gMapControl1.Size = new System.Drawing.Size(605, 219);
             this.gMapControl1.TabIndex = 23;
             this.gMapControl1.Zoom = 0D;
-            this.gMapControl1.Load += new System.EventHandler(this.gMapControl1_Load);
             //
             // olvPokemonList
             //
@@ -237,7 +236,6 @@ namespace PokemonGo.RocketBot.Window.Forms
             this.olvPokemonList.UseCompatibleStateImageBehavior = false;
             this.olvPokemonList.View = System.Windows.Forms.View.Details;
             this.olvPokemonList.ButtonClick += new System.EventHandler<BrightIdeasSoftware.CellClickEventArgs>(this.olvPokemonList_ButtonClick);
-            this.olvPokemonList.SelectedIndexChanged += new System.EventHandler(this.olvPokemonList_SelectedIndexChanged);
             //
             // pkmnName
             //
diff --git a/PokemonGo.RocketBot.Window/Forms/SettingForm.Designer.cs b/PokemonGo.RocketBot.Window/Forms/SettingForm.Designer.cs
index 1330d94..8766141 100644
--- a/PokemonGo.RocketBot.Window/Forms/SettingForm.Designer.cs
+++ b/PokemonGo.RocketBot.Window/Forms/SettingForm.Designer.cs
@@ -636,7 +636,6 @@
             this.tbLatitude.Name = "tbLatitude";
             this.tbLatitude.Size = new System.Drawing.Size(184, 23);
             this.tbLatitude.TabIndex = 13;
-            this.tbLatitude.TextChanged += new System.EventHandler(this.tbLatitude_TextChanged);
             this.tbLatitude.Leave += new System.EventHandler(this.latitudeText_Leave);
             //
             // tbLongitude
@@ -687,7 +686,6 @@
             this.latLabel.Size = new System.Drawing.Size(53, 15);
             this.latLabel.TabIndex = 4;
             this.latLabel.Text = "Latitude:";
-            this.latLabel.Click += new System.EventHandler(this.latLabel_Click);
             //
             // UserLabel
             //
diff --git a/PokemonGo.RocketBot.Window/Forms/SettingForm.cs b/PokemonGo.RocketBot.Window/Forms/SettingForm.cs
index d8843b0..f27137d 100644
--- a/PokemonGo.RocketBot.Window/Forms/SettingForm.cs
+++ b/PokemonGo.RocketBot.Window/Forms/SettingForm.cs
@@ -1,9 +1,11 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Drawing;
 using System.Globalization;
 using System.IO;
 using System.Linq;
+using System.Runtime.InteropServices;
 using System.Windows.Forms;
 using GMap.NET;
 using GMap.NET.MapProviders;
@@ -11,7 +13,6 @@ using PokemonGo.RocketAPI.Enums;
 using PokemonGo.RocketBot.Logic;
 using PokemonGo.RocketBot.Window.Helpers;
 using POGOProtos.Enums;
-using System.Reflection;

 namespace PokemonGo.RocketBot.Window.Forms
 {
@@ -286,6 +287,31 @@ namespace PokemonGo.RocketBot.Window.Forms
             #endregion
         }

+        #region Help button for API key
+
+        protected override void OnLoad(EventArgs e)
+        {
+            var btn = new Button {Size = new Size(25, GoogleApiBox.ClientSize.Height + 2)};
+            btn.Location = new Point(GoogleApiBox.ClientSize.Width - btn.Width, -1);
+            btn.Cursor = Cursors.Default;
+            btn.Image = ResourceHelper.GetImage("question");
+            btn.Click += googleapihep_click;
+            GoogleApiBox.Controls.Add(btn);
+            // Send EM_SETMARGINS to prevent text from disappearing underneath the button
+            SendMessage(GoogleApiBox.Handle, 0xd3, (IntPtr) 2, (IntPtr) (btn.Width << 16));
+            base.OnLoad(e);
+        }
+
+        private void googleapihep_click(object sender, EventArgs e)
+        {
+            Process.Start("https://developers.google.com/maps/documentation/directions/get-api-key");
+        }
+
+        [DllImport("user32.dll")]
+        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
+
+        #endregion
+
         #region private methods

         private static int ConvertStringToInt(string input)
@@ -319,7 +345,7 @@ namespace PokemonGo.RocketBot.Window.Forms
         /// </summary>
         private void GetLanguageList()
         {
-            var languages = new List<string> { "en" };
+            var languages = new List<string> {"en"};
             var langFiles = Directory.GetFiles(LanguagePath, "*.json", SearchOption.TopDirectoryOnly);
             languages.AddRange(langFiles.Select(
                 langFileName => Path.GetFileNameWithoutExtension(langFileName)?.Replace("translation.", ""))
@@ -336,7 +362,7 @@ namespace PokemonGo.RocketBot.Window.Forms
             tbLatitude.Text = gMapCtrl.Position.Lat.ToString(CultureInfo.InvariantCulture);
             tbLongitude.Text = gMapCtrl.Position.Lng.ToString(CultureInfo.InvariantCulture);
             //update trackbar
-            trackBar.Value = (int)Math.Round(gMapCtrl.Zoom);
+            trackBar.Value = (int) Math.Round(gMapCtrl.Zoom);
         }

         /// <summary>
@@ -422,188 +448,201 @@ namespace PokemonGo.RocketBot.Window.Forms

         private void saveBtn_Click(object sender, EventArgs e)
         {
-            #region Auth Settings
-
-            _setting.Auth.AuthType = authTypeCb.Text == @"Google" ? AuthType.Google : AuthType.Ptc;
-            if (_setting.Auth.AuthType == AuthType.Google)
+            if (UserLoginBox.Text.Length == 0 || UserPasswordBox.Text.Length == 0 || GoogleApiBox.Text.Length == 0)
             {
-                _setting.Auth.GoogleUsername = UserLoginBox.Text;
-                _setting.Auth.GooglePassword = UserPasswordBox.Text;
-                _setting.Auth.PtcUsername = "";
-                _setting.Auth.PtcPassword = "";
+                MessageBox.Show(
+                    @"You haven't complete entering your basic information yet." + Environment.NewLine +
+                    @"Either Username, Password or Google API key is empty. Please complete them before saving.",
+                    @"Incomplete information", MessageBoxButtons.OK, MessageBoxIcon.Warning);
             }
             else
             {
-                _setting.Auth.GoogleUsername = "";
-                _setting.Auth.GooglePassword = "";
-                _setting.Auth.PtcUsername = UserLoginBox.Text;
-                _setting.Auth.PtcPassword = UserPasswordBox.Text;
-            }
-
-            _setting.Auth.GoogleApiKey = GoogleApiBox.Text;
-
-            _setting.Auth.UseProxy = useProxyCb.Checked;
-            _setting.Auth.UseProxyHost = proxyHostTb.Text;
-            _setting.Auth.UseProxyPort = proxyPortTb.Text;
-            _setting.Auth.UseProxyAuthentication = useProxyAuthCb.Checked;
-            _setting.Auth.UseProxyUsername = proxyUserTb.Text;
-            _setting.Auth.UseProxyPassword = proxyPwTb.Text;
-
-            _setting.Auth.DevicePackageName = "custom";
-            _setting.Auth.DeviceId = DeviceIdTb.Text;
-            _setting.Auth.AndroidBoardName = AndroidBoardNameTb.Text;
-            _setting.Auth.AndroidBootloader = AndroidBootloaderTb.Text;
-            _setting.Auth.DeviceBrand = DeviceBrandTb.Text;
-            _setting.Auth.DeviceModel = DeviceModelTb.Text;
-            _setting.Auth.DeviceModelIdentifier = DeviceModelIdentifierTb.Text;
-            _setting.Auth.DeviceModelBoot = DeviceModelBootTb.Text;
-            _setting.Auth.HardwareManufacturer = HardwareManufacturerTb.Text;
-            _setting.Auth.HardwareModel = HardwareModelTb.Text;
-            _setting.Auth.FirmwareBrand = FirmwareBrandTb.Text;
-            _setting.Auth.FirmwareTags = FirmwareTagsTb.Text;
-            _setting.Auth.FirmwareType = FirmwareTypeTb.Text;
-            _setting.Auth.FirmwareFingerprint = FirmwareFingerprintTb.Text;
-
-            _setting.Auth.Save(AuthFilePath);
-
-            #endregion
-
-            #region Bot Settings
-
-            _setting.TranslationLanguageCode = cbLanguage.Text;
+                #region Auth Settings
+
+                _setting.Auth.AuthType = authTypeCb.Text == @"Google" ? AuthType.Google : AuthType.Ptc;
+                if (_setting.Auth.AuthType == AuthType.Google)
+                {
+                    _setting.Auth.GoogleUsername = UserLoginBox.Text;
+                    _setting.Auth.GooglePassword = UserPasswordBox.Text;
+                    _setting.Auth.PtcUsername = "";
+                    _setting.Auth.PtcPassword = "";
+                }
+                else
+                {
+                    _setting.Auth.GoogleUsername = "";
+                    _setting.Auth.GooglePassword = "";
+                    _setting.Auth.PtcUsername = UserLoginBox.Text;
+                    _setting.Auth.PtcPassword = UserPasswordBox.Text;
+                }
+
+                _setting.Auth.GoogleApiKey = GoogleApiBox.Text;
+
+                _setting.Auth.UseProxy = useProxyCb.Checked;
+                _setting.Auth.UseProxyHost = proxyHostTb.Text;
+                _setting.Auth.UseProxyPort = proxyPortTb.Text;
+                _setting.Auth.UseProxyAuthentication = useProxyAuthCb.Checked;
+                _setting.Auth.UseProxyUsername = proxyUserTb.Text;
+                _setting.Auth.UseProxyPassword = proxyPwTb.Text;
+
+                _setting.Auth.DevicePackageName = "custom";
+                _setting.Auth.DeviceId = DeviceIdTb.Text;
+                _setting.Auth.AndroidBoardName = AndroidBoardNameTb.Text;
+                _setting.Auth.AndroidBootloader = AndroidBootloaderTb.Text;
+                _setting.Auth.DeviceBrand = DeviceBrandTb.Text;
+                _setting.Auth.DeviceModel = DeviceModelTb.Text;
+                _setting.Auth.DeviceModelIdentifier = DeviceModelIdentifierTb.Text;
+                _setting.Auth.DeviceModelBoot = DeviceModelBootTb.Text;
+                _setting.Auth.HardwareManufacturer = HardwareManufacturerTb.Text;
+                _setting.Auth.HardwareModel = HardwareModelTb.Text;
+                _setting.Auth.FirmwareBrand = FirmwareBrandTb.Text;
+                _setting.Auth.FirmwareTags = FirmwareTagsTb.Text;
+                _setting.Auth.FirmwareType = FirmwareTypeTb.Text;
+                _setting.Auth.FirmwareFingerprint = FirmwareFingerprintTb.Text;
+
+                _setting.Auth.Save(AuthFilePath);
+
+                #endregion
+
+                #region Bot Settings
+
+                _setting.TranslationLanguageCode = cbLanguage.Text;
+
+                #region Location
+
+                _setting.DefaultLatitude = ConvertStringToDouble(tbLatitude.Text);
+                _setting.DefaultLongitude = ConvertStringToDouble(tbLongitude.Text);
+                _setting.WalkingSpeedInKilometerPerHour = ConvertStringToInt(tbWalkingSpeed.Text);
+
+                #endregion
+
+                #region Pokemon
+
+                #region Catch
+
+                _setting.CatchPokemon = cbCatchPoke.Checked;
+                _setting.UseEggIncubators = cbUseEggIncubators.Checked;
+                _setting.MaxBerriesToUsePerPokemon = ConvertStringToInt(tBMaxBerriesToUsePerPokemon.Text);
+                _setting.MaxPokeballsPerPokemon = ConvertStringToInt(tbMaxPokeballsPerPokemon.Text);
+                _setting.PokemonsToIgnore = ConvertClbToList(clbIgnore);
+                _setting.AutoFavoritePokemon = cbAutoFavoritePokemon.Checked;
+                _setting.FavoriteMinIvPercentage = ConvertStringToFloat(tbFavoriteMinIvPercentage.Text);
+
+                _setting.UseBerriesMinCp = ConvertStringToInt(tbUseBerriesMinCp.Text);
+                _setting.UseBerriesMinIv = ConvertStringToFloat(tbUseBerriesMinIv.Text);
+                _setting.UseBerriesBelowCatchProbability = ConvertStringToDouble(tbUseBerriesBelowCatchProbability.Text);
+                _setting.UseBerriesOperator = cbUseBerriesOperator.SelectedIndex == 0 ? "and" : "or";
+
+                _setting.UseGreatBallAboveCp = ConvertStringToInt(tbUseGreatBallAboveCp.Text);
+                _setting.UseUltraBallAboveCp = ConvertStringToInt(tbUseUltraBallAboveCp.Text);
+                _setting.UseMasterBallAboveCp = ConvertStringToInt(tbUseMasterBallAboveCp.Text);
+                _setting.UseGreatBallAboveIv = ConvertStringToDouble(tbUseGreatBallAboveIv.Text);
+                _setting.UseUltraBallAboveIv = ConvertStringToDouble(tbUseUltraBallAboveIv.Text);
+                _setting.UseGreatBallBelowCatchProbability =
+                    ConvertStringToDouble(tbUseGreatBallBelowCatchProbability.Text);
+                _setting.UseUltraBallBelowCatchProbability =
+                    ConvertStringToDouble(tbUseUltraBallBelowCatchProbability.Text);
+                _setting.UseMasterBallBelowCatchProbability =
+                    ConvertStringToDouble(tbUseMasterBallBelowCatchProbability.Text);
+
+                #endregion
+
+                #region Transfer
+
+                _setting.PrioritizeIvOverCp = cbPrioritizeIvOverCp.Checked;
+                _setting.KeepMinCp = ConvertStringToInt(tbKeepMinCp.Text);
+                _setting.KeepMinIvPercentage = ConvertStringToFloat(tbKeepMinIV.Text);
+                _setting.KeepMinLvl = ConvertStringToInt(tbKeepMinLvl.Text);
+                _setting.KeepMinOperator = cbKeepMinOperator.SelectedIndex == 0 ? "and" : "or";
+                _setting.TransferWeakPokemon = cbTransferWeakPokemon.Checked;
+                _setting.TransferDuplicatePokemon = cbTransferDuplicatePokemon.Checked;
+                _setting.TransferDuplicatePokemonOnCapture = cbTransferDuplicatePokemonOnCapture.Checked;
+
+                _setting.KeepMinDuplicatePokemon = ConvertStringToInt(tbKeepMinDuplicatePokemon.Text);
+                _setting.UseKeepMinLvl = cbUseKeepMinLvl.Checked;
+                _setting.PokemonsNotToTransfer = ConvertClbToList(clbTransfer);
+
+                #endregion
+
+                #region PowerUp
+
+                _setting.UseLevelUpList = true;
+
+                _setting.AutomaticallyLevelUpPokemon = cbAutoPowerUp.Checked;
+                _setting.OnlyUpgradeFavorites = cbPowerUpFav.Checked;
+                _setting.LevelUpByCPorIv = cbPowerUpType.SelectedIndex == 0 ? "iv" : "cp";
+                _setting.UpgradePokemonMinimumStatsOperator = cbPowerUpCondiction.SelectedIndex == 0 ? "and" : "or";
+                _setting.GetMinStarDustForLevelUp = ConvertStringToInt(cbPowerUpMinStarDust.Text);
+                _setting.UpgradePokemonIvMinimum = ConvertStringToFloat(tbPowerUpMinIV.Text);
+                _setting.UpgradePokemonCpMinimum = ConvertStringToFloat(tbPowerUpMinCP.Text);
+                _setting.PokemonsToLevelUp = ConvertClbToList(clbPowerUp);
+
+                #endregion
+
+                #region Evo
+
+                _setting.EvolveAllPokemonAboveIv = cbEvoAllAboveIV.Checked;
+                _setting.EvolveAboveIvValue = ConvertStringToFloat(tbEvoAboveIV.Text);
+                _setting.EvolveAllPokemonWithEnoughCandy = cbEvolveAllPokemonWithEnoughCandy.Checked;
+                _setting.KeepPokemonsThatCanEvolve = cbKeepPokemonsThatCanEvolve.Checked;
+                _setting.UseLuckyEggsWhileEvolving = cbUseLuckyEggsWhileEvolving.Checked;
+                _setting.EvolveKeptPokemonsAtStorageUsagePercentage =
+                    ConvertStringToDouble(tbEvolveKeptPokemonsAtStorageUsagePercentage.Text);
+                _setting.UseLuckyEggsMinPokemonAmount = ConvertStringToInt(tbUseLuckyEggsMinPokemonAmount.Text);
+                _setting.PokemonsToEvolve = ConvertClbToList(clbEvolve);
+
+                #endregion

-            #region Location
+                #endregion

-            _setting.DefaultLatitude = ConvertStringToDouble(tbLatitude.Text);
-            _setting.DefaultLongitude = ConvertStringToDouble(tbLongitude.Text);
-            _setting.WalkingSpeedInKilometerPerHour = ConvertStringToInt(tbWalkingSpeed.Text);
-
-            #endregion
-
-            #region Pokemon
-
-            #region Catch
-
-            _setting.CatchPokemon = cbCatchPoke.Checked;
-            _setting.UseEggIncubators = cbUseEggIncubators.Checked;
-            _setting.MaxBerriesToUsePerPokemon = ConvertStringToInt(tBMaxBerriesToUsePerPokemon.Text);
-            _setting.MaxPokeballsPerPokemon = ConvertStringToInt(tbMaxPokeballsPerPokemon.Text);
-            _setting.PokemonsToIgnore = ConvertClbToList(clbIgnore);
-            _setting.AutoFavoritePokemon = cbAutoFavoritePokemon.Checked;
-            _setting.FavoriteMinIvPercentage = ConvertStringToFloat(tbFavoriteMinIvPercentage.Text);
-
-            _setting.UseBerriesMinCp = ConvertStringToInt(tbUseBerriesMinCp.Text);
-            _setting.UseBerriesMinIv = ConvertStringToFloat(tbUseBerriesMinIv.Text);
-            _setting.UseBerriesBelowCatchProbability = ConvertStringToDouble(tbUseBerriesBelowCatchProbability.Text);
-            _setting.UseBerriesOperator = cbUseBerriesOperator.SelectedIndex == 0 ? "and" : "or";
-
-            _setting.UseGreatBallAboveCp = ConvertStringToInt(tbUseGreatBallAboveCp.Text);
-            _setting.UseUltraBallAboveCp = ConvertStringToInt(tbUseUltraBallAboveCp.Text);
-            _setting.UseMasterBallAboveCp = ConvertStringToInt(tbUseMasterBallAboveCp.Text);
-            _setting.UseGreatBallAboveIv = ConvertStringToDouble(tbUseGreatBallAboveIv.Text);
-            _setting.UseUltraBallAboveIv = ConvertStringToDouble(tbUseUltraBallAboveIv.Text);
-            _setting.UseGreatBallBelowCatchProbability = ConvertStringToDouble(tbUseGreatBallBelowCatchProbability.Text);
-            _setting.UseUltraBallBelowCatchProbability = ConvertStringToDouble(tbUseUltraBallBelowCatchProbability.Text);
-            _setting.UseMasterBallBelowCatchProbability =
-                ConvertStringToDouble(tbUseMasterBallBelowCatchProbability.Text);
-
-            #endregion
-
-            #region Transfer
-
-            _setting.PrioritizeIvOverCp = cbPrioritizeIvOverCp.Checked;
-            _setting.KeepMinCp = ConvertStringToInt(tbKeepMinCp.Text);
-            _setting.KeepMinIvPercentage = ConvertStringToFloat(tbKeepMinIV.Text);
-            _setting.KeepMinLvl = ConvertStringToInt(tbKeepMinLvl.Text);
-            _setting.KeepMinOperator = cbKeepMinOperator.SelectedIndex == 0 ? "and" : "or";
-            _setting.TransferWeakPokemon = cbTransferWeakPokemon.Checked;
-            _setting.TransferDuplicatePokemon = cbTransferDuplicatePokemon.Checked;
-            _setting.TransferDuplicatePokemonOnCapture = cbTransferDuplicatePokemonOnCapture.Checked;
-
-            _setting.KeepMinDuplicatePokemon = ConvertStringToInt(tbKeepMinDuplicatePokemon.Text);
-            _setting.UseKeepMinLvl = cbUseKeepMinLvl.Checked;
-            _setting.PokemonsNotToTransfer = ConvertClbToList(clbTransfer);
-
-            #endregion
-
-            #region PowerUp
-
-            _setting.UseLevelUpList = true;
+                #region Item

-            _setting.AutomaticallyLevelUpPokemon = cbAutoPowerUp.Checked;
-            _setting.OnlyUpgradeFavorites = cbPowerUpFav.Checked;
-            _setting.LevelUpByCPorIv = cbPowerUpType.SelectedIndex == 0 ? "iv" : "cp";
-            _setting.UpgradePokemonMinimumStatsOperator = cbPowerUpCondiction.SelectedIndex == 0 ? "and" : "or";
-            _setting.GetMinStarDustForLevelUp = ConvertStringToInt(cbPowerUpMinStarDust.Text);
-            _setting.UpgradePokemonIvMinimum = ConvertStringToFloat(tbPowerUpMinIV.Text);
-            _setting.UpgradePokemonCpMinimum = ConvertStringToFloat(tbPowerUpMinCP.Text);
-            _setting.PokemonsToLevelUp = ConvertClbToList(clbPowerUp);
+                _setting.UseLuckyEggConstantly = cbUseLuckyEggConstantly.Checked;
+                _setting.UseIncenseConstantly = cbUseIncenseConstantly.Checked;
+                _setting.TotalAmountOfPokeballsToKeep = ConvertStringToInt(tbTotalAmountOfPokeballsToKeep.Text);
+                _setting.TotalAmountOfPotionsToKeep = ConvertStringToInt(tbTotalAmountOfPotionsToKeep.Text);
+                _setting.TotalAmountOfRevivesToKeep = ConvertStringToInt(tbTotalAmountOfRevivesToKeep.Text);
+                _setting.TotalAmountOfBerriesToKeep = ConvertStringToInt(tbTotalAmountOfBerriesToKeep.Text);
+                _setting.VerboseRecycling = cbVerboseRecycling.Checked;
+                _setting.RecycleInventoryAtUsagePercentage =
+                    ConvertStringToDouble(tbRecycleInventoryAtUsagePercentage.Text);
+
+                #endregion
+
+                #region Advanced Settings
+
+                _setting.DisableHumanWalking = cbDisableHumanWalking.Checked;
+                _setting.UseWalkingSpeedVariant = cbUseWalkingSpeedVariant.Checked;
+                _setting.WalkingSpeedVariant = ConvertStringToDouble(tbWalkingSpeedVariantInKilometerPerHour.Text);
+                _setting.ShowVariantWalking = cbShowWalkingSpeed.Checked;
+                _setting.MaxSpawnLocationOffset = ConvertStringToInt(tbMaxSpawnLocationOffset.Text);
+                _setting.MaxTravelDistanceInMeters = ConvertStringToInt(tbMaxTravelDistanceInMeters.Text);
+
+                _setting.DelayBetweenPlayerActions = ConvertStringToInt(tbDelayBetweenPlayerActions.Text);
+                _setting.DelayBetweenPokemonCatch = ConvertStringToInt(tbDelayBetweenPokemonCatch.Text);
+                _setting.DelayBetweenRecycleActions = cbDelayBetweenRecycleActions.Checked;
+
+                _setting.RandomizeRecycle = cbRandomizeRecycle.Checked;
+                _setting.RandomRecycleValue = ConvertStringToInt(tbRandomRecycleValue.Text);
+
+                _setting.EnableHumanizedThrows = cbEnableHumanizedThrows.Checked;
+                _setting.NiceThrowChance = ConvertStringToInt(tbNiceThrowChance.Text);
+                _setting.GreatThrowChance = ConvertStringToInt(tbGreatThrowChance.Text);
+                _setting.ExcellentThrowChance = ConvertStringToInt(tbExcellentThrowChance.Text);
+                _setting.CurveThrowChance = ConvertStringToInt(tbCurveThrowChance.Text);
+                _setting.ForceGreatThrowOverIv = ConvertStringToDouble(tbForceGreatThrowOverIv.Text);
+                _setting.ForceExcellentThrowOverIv = ConvertStringToDouble(tbForceExcellentThrowOverIv.Text);
+                _setting.ForceGreatThrowOverCp = ConvertStringToInt(tbForceGreatThrowOverCp.Text);
+                _setting.ForceExcellentThrowOverCp = ConvertStringToInt(tbForceExcellentThrowOverCp.Text);
+
+                #endregion
+
+                _setting.Save(ConfigFilePath);
+
+                #endregion

-            #endregion
-
-            #region Evo
-
-            _setting.EvolveAllPokemonAboveIv = cbEvoAllAboveIV.Checked;
-            _setting.EvolveAboveIvValue = ConvertStringToFloat(tbEvoAboveIV.Text);
-            _setting.EvolveAllPokemonWithEnoughCandy = cbEvolveAllPokemonWithEnoughCandy.Checked;
-            _setting.KeepPokemonsThatCanEvolve = cbKeepPokemonsThatCanEvolve.Checked;
-            _setting.UseLuckyEggsWhileEvolving = cbUseLuckyEggsWhileEvolving.Checked;
-            _setting.EvolveKeptPokemonsAtStorageUsagePercentage =
-                ConvertStringToDouble(tbEvolveKeptPokemonsAtStorageUsagePercentage.Text);
-            _setting.UseLuckyEggsMinPokemonAmount = ConvertStringToInt(tbUseLuckyEggsMinPokemonAmount.Text);
-            _setting.PokemonsToEvolve = ConvertClbToList(clbEvolve);
-
-            #endregion
-
-            #endregion
-
-            #region Item
-
-            _setting.UseLuckyEggConstantly = cbUseLuckyEggConstantly.Checked;
-            _setting.UseIncenseConstantly = cbUseIncenseConstantly.Checked;
-            _setting.TotalAmountOfPokeballsToKeep = ConvertStringToInt(tbTotalAmountOfPokeballsToKeep.Text);
-            _setting.TotalAmountOfPotionsToKeep = ConvertStringToInt(tbTotalAmountOfPotionsToKeep.Text);
-            _setting.TotalAmountOfRevivesToKeep = ConvertStringToInt(tbTotalAmountOfRevivesToKeep.Text);
-            _setting.TotalAmountOfBerriesToKeep = ConvertStringToInt(tbTotalAmountOfBerriesToKeep.Text);
-            _setting.VerboseRecycling = cbVerboseRecycling.Checked;
-            _setting.RecycleInventoryAtUsagePercentage = ConvertStringToDouble(tbRecycleInventoryAtUsagePercentage.Text);
-
-            #endregion
-
-            #region Advanced Settings
-
-            _setting.DisableHumanWalking = cbDisableHumanWalking.Checked;
-            _setting.UseWalkingSpeedVariant = cbUseWalkingSpeedVariant.Checked;
-            _setting.WalkingSpeedVariant = ConvertStringToDouble(tbWalkingSpeedVariantInKilometerPerHour.Text);
-            _setting.ShowVariantWalking = cbShowWalkingSpeed.Checked;
-            _setting.MaxSpawnLocationOffset = ConvertStringToInt(tbMaxSpawnLocationOffset.Text);
-            _setting.MaxTravelDistanceInMeters = ConvertStringToInt(tbMaxTravelDistanceInMeters.Text);
-
-            _setting.DelayBetweenPlayerActions = ConvertStringToInt(tbDelayBetweenPlayerActions.Text);
-            _setting.DelayBetweenPokemonCatch = ConvertStringToInt(tbDelayBetweenPokemonCatch.Text);
-            _setting.DelayBetweenRecycleActions = cbDelayBetweenRecycleActions.Checked;
-
-            _setting.RandomizeRecycle = cbRandomizeRecycle.Checked;
-            _setting.RandomRecycleValue = ConvertStringToInt(tbRandomRecycleValue.Text);
-
-            _setting.EnableHumanizedThrows = cbEnableHumanizedThrows.Checked;
-            _setting.NiceThrowChance = ConvertStringToInt(tbNiceThrowChance.Text);
-            _setting.GreatThrowChance = ConvertStringToInt(tbGreatThrowChance.Text);
-            _setting.ExcellentThrowChance = ConvertStringToInt(tbExcellentThrowChance.Text);
-            _setting.CurveThrowChance = ConvertStringToInt(tbCurveThrowChance.Text);
-            _setting.ForceGreatThrowOverIv = ConvertStringToDouble(tbForceGreatThrowOverIv.Text);
-            _setting.ForceExcellentThrowOverIv = ConvertStringToDouble(tbForceExcellentThrowOverIv.Text);
-            _setting.ForceGreatThrowOverCp = ConvertStringToInt(tbForceGreatThrowOverCp.Text);
-            _setting.ForceExcellentThrowOverCp = ConvertStringToInt(tbForceExcellentThrowOverCp.Text);
-
-            #endregion
-
-            _setting.Save(ConfigFilePath);
-
-            #endregion
-
-            Application.Restart();
-            Close();
+                Application.Restart();
+                Close();
+            }
         }

         private void cancelBtn_Click(object sender, EventArgs e)
@@ -668,7 +707,7 @@ namespace PokemonGo.RocketBot.Window.Forms

         private void AdressBox_KeyPress(object sender, KeyPressEventArgs e)
         {
-            if (e.KeyChar != (char)Keys.Enter)
+            if (e.KeyChar != (char) Keys.Enter)
             {
                 return;
             }
@@ -763,15 +802,5 @@ namespace PokemonGo.RocketBot.Window.Forms
         }

         #endregion
-
-        private void latLabel_Click(object sender, EventArgs e)
-        {
-
-        }
-
-        private void tbLatitude_TextChanged(object sender, EventArgs e)
-        {
-
-        }
     }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Window/Helpers/MachineIdHelper.cs b/PokemonGo.RocketBot.Window/Helpers/MachineIdHelper.cs
index 88bc2a3..36eaeaa 100644
--- a/PokemonGo.RocketBot.Window/Helpers/MachineIdHelper.cs
+++ b/PokemonGo.RocketBot.Window/Helpers/MachineIdHelper.cs
@@ -1,4 +1,5 @@
-using System.Management;
+using System;
+using System.Management;

 namespace PokemonGo.RocketBot.Window.Helpers
 {
@@ -12,7 +13,7 @@ namespace PokemonGo.RocketBot.Window.Helpers

             foreach (var o in moc)
             {
-                var mo = (ManagementObject) o;
+                var mo = (ManagementObject)o;
                 cpuInfo = mo.Properties["processorID"].Value.ToString();
                 break;
             }
@@ -30,7 +31,16 @@ namespace PokemonGo.RocketBot.Window.Helpers

         public static string GetMachineId()
         {
-            return GetCpuId() + GetHardDriveId();
+            string id;
+            try
+            {
+                id = GetCpuId() + GetHardDriveId();
+            }
+            catch (Exception)
+            {
+                id = "BF00LIKELYVIRTUALMACHINE";
+            }
+            return id;
         }
     }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Window/Helpers/ResourceHelper.cs b/PokemonGo.RocketBot.Window/Helpers/ResourceHelper.cs
index 9ea7874..4bcc81c 100644
--- a/PokemonGo.RocketBot.Window/Helpers/ResourceHelper.cs
+++ b/PokemonGo.RocketBot.Window/Helpers/ResourceHelper.cs
@@ -27,5 +27,10 @@ namespace PokemonGo.RocketBot.Window.Helpers

             return newImage;
         }
+
+        public static Image GetPokemonImage(int pokemonId)
+        {
+            return GetImage("Pokemon_" + pokemonId);
+        }
     }
 }
\ No newline at end of file
diff --git a/PokemonGo.RocketBot.Window/Images/Miscs/question.png b/PokemonGo.RocketBot.Window/Images/Miscs/question.png
new file mode 100644
index 0000000..0c854e9
Binary files /dev/null and b/PokemonGo.RocketBot.Window/Images/Miscs/question.png differ
diff --git a/PokemonGo.RocketBot.Window/Models/LoggingStrings.cs b/PokemonGo.RocketBot.Window/Models/LoggingStrings.cs
index 38e166d..f6b9744 100644
--- a/PokemonGo.RocketBot.Window/Models/LoggingStrings.cs
+++ b/PokemonGo.RocketBot.Window/Models/LoggingStrings.cs
@@ -17,6 +17,8 @@ namespace PokemonGo.RocketBot.Window.Models

         internal static string Evolved;

+        internal static string LevelUp;
+
         internal static string Farming;

         internal static string Info;
@@ -63,6 +65,10 @@ namespace PokemonGo.RocketBot.Window.Models
                 session?.Translation.GetTranslation(
                     TranslationString.LogEntryEvolved) ?? "EVOLVED";

+            LevelUp =
+                session?.Translation.GetTranslation(
+                    TranslationString.LogEntryLevelUp) ?? "LEVELUP";
+
             Farming =
                 session?.Translation.GetTranslation(
                     TranslationString.LogEntryFarming) ?? "FARMING";
diff --git a/PokemonGo.RocketBot.Window/PokemonGo.RocketBot.Window.csproj b/PokemonGo.RocketBot.Window/PokemonGo.RocketBot.Window.csproj
index 4ce519b..f5dbe64 100644
--- a/PokemonGo.RocketBot.Window/PokemonGo.RocketBot.Window.csproj
+++ b/PokemonGo.RocketBot.Window/PokemonGo.RocketBot.Window.csproj
@@ -103,10 +103,42 @@
       <HintPath>..\packages\GMap.NET.WindowsForms.1.7.1\lib\net40\GMap.NET.WindowsForms.dll</HintPath>
       <Private>True</Private>
     </Reference>
+    <Reference Include="Google.Apis, Version=1.16.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Google.Apis.Auth, Version=1.16.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.16.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Google.Apis.Core, Version=1.16.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Google.Apis.PlatformServices, Version=1.16.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.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\lib\net45\Google.Protobuf.dll</HintPath>
       <Private>True</Private>
     </Reference>
+    <Reference Include="MetroFramework, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a, processorArchitecture=MSIL">
+      <HintPath>..\packages\MetroModernUI.1.4.0.0\lib\net\MetroFramework.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="MetroFramework.Design, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a, processorArchitecture=MSIL">
+      <HintPath>..\packages\MetroModernUI.1.4.0.0\lib\net\MetroFramework.Design.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="MetroFramework.Fonts, Version=1.4.0.0, Culture=neutral, PublicKeyToken=5f91a84759bf584a, processorArchitecture=MSIL">
+      <HintPath>..\packages\MetroModernUI.1.4.0.0\lib\net\MetroFramework.Fonts.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <HintPath>$(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
       <Private>True</Private>
@@ -302,6 +334,7 @@
     <None Include="cert.pfx">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
+    <None Include="Images\Miscs\question.png" />
     <Content Include="Resources\device info.csv">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
diff --git a/PokemonGo.RocketBot.Window/Properties/Resources.Designer.cs b/PokemonGo.RocketBot.Window/Properties/Resources.Designer.cs
index 2a9c7d7..fe5a228 100644
--- a/PokemonGo.RocketBot.Window/Properties/Resources.Designer.cs
+++ b/PokemonGo.RocketBot.Window/Properties/Resources.Designer.cs
@@ -1830,6 +1830,16 @@ namespace PokemonGo.RocketBot.Window.Properties {
             }
         }

+        /// <summary>
+        ///   查找 System.Drawing.Bitmap 类型的本地化资源。
+        /// </summary>
+        internal static System.Drawing.Bitmap question {
+            get {
+                object obj = ResourceManager.GetObject("question", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+
         /// <summary>
         ///   查找 System.Drawing.Bitmap 类型的本地化资源。
         /// </summary>
diff --git a/PokemonGo.RocketBot.Window/Properties/Resources.resx b/PokemonGo.RocketBot.Window/Properties/Resources.resx
index 7ebfacf..4636423 100644
--- a/PokemonGo.RocketBot.Window/Properties/Resources.resx
+++ b/PokemonGo.RocketBot.Window/Properties/Resources.resx
@@ -1990,6 +1990,9 @@
   <data name="Pokestop_looted" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Images\Markers\Pokestop_looted.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
+  <data name="question" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>..\Images\Miscs\question.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
   <data name="Trainer_Front" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>..\Images\Markers\Trainer_Front.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>
diff --git a/PokemonGo.RocketBot.Window/WebSocketHandler/ActionCommands/TransferPokemonHandler.cs b/PokemonGo.RocketBot.Window/WebSocketHandler/ActionCommands/TransferPokemonHandler.cs
index 70ded15..9a5d172 100644
--- a/PokemonGo.RocketBot.Window/WebSocketHandler/ActionCommands/TransferPokemonHandler.cs
+++ b/PokemonGo.RocketBot.Window/WebSocketHandler/ActionCommands/TransferPokemonHandler.cs
@@ -16,7 +16,7 @@ namespace PokemonGo.RocketBot.Window.WebSocketHandler.ActionCommands

         public async Task Handle(ISession session, WebSocketSession webSocketSession, dynamic message)
         {
-            await TransferPokemonTask.Execute(session, (ulong) message.PokemonId);
+            await TransferSpecificPokemonTask.Execute(session, (ulong) message.PokemonId);
         }
     }
 }
\ No newline at end of file
You may download the files in Public Git.