package com.mapswithme.maps.location;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.mapswithme.maps.MwmApplication;
import com.mapswithme.util.LocationUtils;

import java.util.ArrayList;
import java.util.List;

class AndroidNativeProvider extends BaseLocationProvider
{
  private final static String[] TRUSTED_PROVIDERS = { LocationManager.NETWORK_PROVIDER,
                                                      LocationManager.GPS_PROVIDER };
  @NonNull
  private final LocationManager mLocationManager;
  private boolean mIsActive;
  @NonNull
  private final List<LocationListener> mListeners = new ArrayList<>();

  AndroidNativeProvider(@NonNull LocationFixChecker locationFixChecker)
  {
    super(locationFixChecker);
    mLocationManager = (LocationManager) MwmApplication.get().getSystemService(Context.LOCATION_SERVICE);
  }

  @Override
  protected boolean start()
  {
    if (mIsActive)
      return true;

    List<String> providers = getAvailableProviders(mLocationManager);
    if (providers.isEmpty())
      return false;

    mIsActive = true;
    for (String provider : providers)
    {
      sLogger.d("Request location updates from the provider: " + provider);
      LocationListener listener = new BaseLocationListener(getLocationFixChecker());
      mLocationManager.requestLocationUpdates(provider, LocationHelper.INSTANCE.getInterval(), 0, listener);
      mListeners.add(listener);
    }

    LocationHelper.INSTANCE.startSensors();

    Location location = findBestNotExpiredLocation(mLocationManager, providers,
                                                   LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_SHORT);
    if (!getLocationFixChecker().isLocationBetterThanLast(location))
    {
      location = LocationHelper.INSTANCE.getSavedLocation();
      if (location == null || LocationUtils.isExpired(location, LocationHelper.INSTANCE.getSavedLocationTime(),
                                                      LocationUtils.LOCATION_EXPIRATION_TIME_MILLIS_SHORT))
      {
        return true;
      }
    }

    if (location != null)
      onLocationChanged(location);

    return true;
  }

  private void onLocationChanged(@NonNull Location location)
  {
    for (LocationListener listener : mListeners)
      listener.onLocationChanged(location);
  }

  @Override
  protected void stop()
  {
    for (LocationListener listener : mListeners)
      mLocationManager.removeUpdates(listener);
    mListeners.clear();
    mIsActive = false;
  }

  @Nullable
  static Location findBestNotExpiredLocation(long expirationMillis)
  {
    final LocationManager manager = (LocationManager) MwmApplication.get().getSystemService(Context.LOCATION_SERVICE);
    return findBestNotExpiredLocation(manager,
                                      getAvailableProviders(manager),
                                      expirationMillis);
  }

  @Nullable
  private static Location findBestNotExpiredLocation(LocationManager manager, List<String> providers, long expirationMillis)
  {
    Location res = null;
    for (final String pr : providers)
    {
      final Location last = manager.getLastKnownLocation(pr);
      if (last == null || LocationUtils.isExpired(last, last.getTime(), expirationMillis))
        continue;

      if (res == null || res.getAccuracy() > last.getAccuracy())
        res = last;
    }
    return res;
  }

  @NonNull
  private static List<String> getAvailableProviders(@NonNull LocationManager locationManager)
  {
    final List<String> res = new ArrayList<>();
    for (String provider : TRUSTED_PROVIDERS)
    {
      if (locationManager.isProviderEnabled(provider))
        res.add(provider);
    }
    return res;
  }
}

@@ -405,16 +405,47 @@
 il.List;
+%0Aimport java.util.ListIterator;
 %0A%0Aclass 
@@ -2415,37 +2415,45 @@
 cation)%0A  %7B%0A    
-for (
+ListIterator%3C
 LocationListener
@@ -2448,35 +2448,36 @@
 tionListener
- listener :
+%3E iterator =
  mListeners)
@@ -2479,24 +2479,77 @@
 ners
-)%0A      listener
+.listIterator();%0A    while (iterator.hasNext())%0A      iterator.next()
 .onL
@@ -2623,21 +2623,29 @@
   %7B%0A    
-for (
+ListIterator%3C
 Location
@@ -2656,19 +2656,20 @@
 ener
- listener :
+%3E iterator =
  mLi
@@ -2675,16 +2675,62 @@
 isteners
+.listIterator();%0A    while (iterator.hasNext()
 )%0A      
@@ -2760,27 +2760,35 @@
 Updates(
-listener
+iterator.next()
 );%0A
+%0A
     mLis

Use ListIterator instead foreach loop