private void updateLocationLoaders() {
    if (NavigineApp.Navigation == null) return;

    long timeNow = DateTimeUtils.currentTimeMillis();
    mUpdateLocationLoadersTime = timeNow;

    synchronized (mLoaderMap) {
      Iterator<Map.Entry<String, LoaderState>> iter = mLoaderMap.entrySet().iterator();
      while (iter.hasNext()) {
        Map.Entry<String, LoaderState> entry = iter.next();

        LoaderState loader = entry.getValue();
        if (loader.state < 100) {
          loader.timeLabel = timeNow;
          if (loader.type == DOWNLOAD) loader.state = LocationLoader.checkLocationLoader(loader.id);
          if (loader.type == UPLOAD) loader.state = LocationLoader.checkLocationUploader(loader.id);
        } else if (loader.state == 100) {
          String archivePath = NavigineApp.Navigation.getArchivePath();
          String locationFile =
              LocationLoader.getLocationFile(NavigineApp.AppContext, loader.location);
          if (archivePath != null && archivePath.equals(locationFile)) {
            Log.d(TAG, "Reloading archive " + archivePath);
            if (NavigineApp.Navigation.loadArchive(archivePath)) {
              SharedPreferences.Editor editor = NavigineApp.Settings.edit();
              editor.putString("map_file", archivePath);
              editor.commit();
            }
          }
          if (loader.type == DOWNLOAD) LocationLoader.stopLocationLoader(loader.id);
          if (loader.type == UPLOAD) LocationLoader.stopLocationUploader(loader.id);
          iter.remove();
        } else {
          // Load failed
          if (Math.abs(timeNow - loader.timeLabel) > 5000) {
            if (loader.type == DOWNLOAD) LocationLoader.stopLocationLoader(loader.id);
            if (loader.type == UPLOAD) LocationLoader.stopLocationUploader(loader.id);
            iter.remove();
          }
        }
      }
    }
    updateLocalVersions();
    mAdapter.updateList();
  }
  public void run() {
    setAllColors(Color.GREEN);
    setTurnRadarRight(Double.POSITIVE_INFINITY);

    double robotX, robotY;
    double robotHeading, angleToGoal, angleToObs;
    double adjustment;
    double obsAngle, obsAdjustment;
    double angleDiff;
    double speedToGoal, speedFromObs;

    Enemy temp;
    obstacles = new HashMap<String, Enemy>(10);

    while (true) {
      if (foundGoal) {
        robotX = getX();
        robotY = getY();
        goalX = obstacles.get(GOAL_NAME).x;
        goalY = obstacles.get(GOAL_NAME).y;

        // Adjust robocode's returned heading so that 0 aligns with the positive x-axis instead of
        // the positive y-axis.
        // Also make it so that positive angle indicates a counter clockwise rotation instead of the
        // clockwise style
        // returned by robocode.
        robotHeading = 360 - (getHeading() - 90);
        angleToGoal = Math.toDegrees(Math.atan2(goalY - robotY, goalX - robotX));
        if (angleToGoal < 0) {
          angleToGoal += 360;
        }

        adjustment = angleToGoal - robotHeading;
        adjustment = normalizeAngle(adjustment);
        speedToGoal = calcRobotSpeedLinear(robotX, robotY, goalX, goalY);

        // Calculate how the robot's heading and speed should be affected by objects that it has
        // located
        // as it explores the world.
        Iterator it = obstacles.entrySet().iterator();
        while (it.hasNext()) {
          System.out.println("Iterating through objects.");

          Map.Entry pairs = (Map.Entry) it.next();

          // If the current item in the Iterator isn't the goal.
          if (!pairs.getKey().equals(GOAL_NAME)) {
            temp = (Enemy) pairs.getValue();
            speedFromObs = calcObjRepulseSpeed(robotX, robotY, temp.x, temp.y);

            // If the robot is in range of the object to be affected by it's repulsion.
            if (speedFromObs != 0) {
              obsAngle = Math.toDegrees(Math.atan2(robotY - temp.y, robotX - temp.x));
              if (obsAngle < 0) obsAngle += 360;

              angleDiff = obsAngle - angleToGoal;
              angleDiff = normalizeAngle(angleDiff);
              adjustment += (angleDiff * (speedFromObs / speedToGoal));
              speedToGoal -= speedFromObs;
            }
          }

          // Was getting a null pointer exception when using this. The internet lied about its
          // usefulness.
          // it.remove(); // avoids a ConcurrentModificationException
        }

        adjustment = normalizeAngle(adjustment);
        setTurnLeft(adjustment);
        // ahead(speedToGoal);
        setAhead(speedToGoal);
      }

      execute();
    }
  }