// Path: library/src/main/java/fr/prcaen/externalresources/converter/Converter.java
// public interface Converter {
//   Resources fromReader(Reader reader) throws IOException;
// }
// 
// Path: library/src/main/java/fr/prcaen/externalresources/exception/ExternalResourceException.java
// public class ExternalResourceException extends RuntimeException {
// 
//   public ExternalResourceException(String detailMessage) {
//     super(detailMessage);
//   }
// 
//   public ExternalResourceException(String message, Throwable cause) {
//     super(message, cause);
//   }
// 
//   public ExternalResourceException(Throwable cause) {
//     super(cause);
//   }
// }
// 
// Path: library/src/main/java/fr/prcaen/externalresources/exception/ResponseException.java
// public final class ResponseException extends ExternalResourceException {
// 
//   private final boolean localCacheOnly;
//   private final int responseCode;
// 
//   public ResponseException(String message, @Cache.Policy int networkPolicy, int responseCode) {
//     super(message);
// 
//     this.localCacheOnly = networkPolicy == Cache.POLICY_OFFLINE;
//     this.responseCode = responseCode;
//   }
// 
//   public boolean isLocalCacheOnly() {
//     return localCacheOnly;
//   }
// 
//   public int getResponseCode() {
//     return responseCode;
//   }
// }
// 
// Path: library/src/main/java/fr/prcaen/externalresources/model/Resources.java
// @SuppressWarnings("unused") public final class Resources {
//   protected final ConcurrentHashMap<String, Resource> members;
// 
//   public Resources() {
//     this.members = new ConcurrentHashMap<>();
//   }
// 
//   public Resources(@NonNull ConcurrentHashMap<String, Resource> members) {
//     this.members = members;
//   }
// 
//   public static Resources from(Reader reader, Converter converter) throws IOException {
//     return converter.fromReader(reader);
//   }
// 
//   public static Resources from(String string, Converter converter) throws IOException {
//     return from(new StringReader(string), converter);
//   }
// 
//   public static Resources fromJson(Reader reader) throws IOException {
//     return from(reader, new JsonConverter());
//   }
// 
//   public static Resources fromJson(String string) throws IOException {
//     return from(string, new JsonConverter());
//   }
// 
//   public static Resources fromJson(InputStream reader) throws IOException {
//     return fromJson(new InputStreamReader(reader));
//   }
// 
//   public static Resources fromXml(Reader reader) throws IOException {
//     return from(reader, new XmlConverter());
//   }
// 
//   public static Resources fromXml(String string) throws IOException {
//     return from(string, new XmlConverter());
//   }
// 
//   public static Resources fromXml(InputStream reader) throws IOException {
//     return fromXml(new InputStreamReader(reader));
//   }
// 
//   public Resource add(String key, Resource value) {
//     return members.put(key, value);
//   }
// 
//   @NonNull protected Set<Entry<String, Resource>> entrySet() {
//     return members.entrySet();
//   }
// 
//   public boolean has(String key) {
//     return members.containsKey(key);
//   }
// 
//   public Resource get(String key) {
//     return members.get(key);
//   }
// 
//   public Resources merge(Resources resources) {
//     members.putAll(resources.members);
// 
//     return this;
//   }
// }
// 
// Path: library/src/main/java/fr/prcaen/externalresources/url/Url.java
// public interface Url {
// 
//   void fontScale(float fontScale);
// 
//   void hardKeyboardHidden(int hardKeyboardHidden);
// 
//   void keyboard(int keyboard);
// 
//   void keyboardHidden(int keyboardHidden);
// 
//   void locale(Locale locale);
// 
//   void mcc(int mcc);
// 
//   void mnc(int mnc);
// 
//   void navigation(int navigation);
// 
//   void navigationHidden(int navigationHidden);
// 
//   void orientation(int orientation);
// 
//   void screenLayout(int screenLayout);
// 
//   void touchscreen(int touchscreen);
// 
//   void uiMode(int uiMode);
// 
//   void densityDpi(int densityDpi);
// 
//   void screenWidthDp(int screenWidthDp);
// 
//   void screenHeightDp(int screenHeightDp);
// 
//   void smallestScreenWidthDp(int smallestScreenWidthDp);
// 
//   String build();
// }


import android.content.Context;
import android.content.res.Configuration;
import android.support.annotation.NonNull;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import fr.prcaen.externalresources.converter.Converter;
import fr.prcaen.externalresources.exception.ExternalResourceException;
import fr.prcaen.externalresources.exception.ResponseException;
import fr.prcaen.externalresources.model.Resources;
import fr.prcaen.externalresources.url.Url;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.HONEYCOMB_MR2;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
package fr.prcaen.externalresources;



public final class Downloader {
  private static final int CONNECT_TIMEOUT_MILLIS = 15 * 1000; // 15s
  private static final int READ_TIMEOUT_MILLIS = 20 * 1000;    // 20s
  private static final int WRITE_TIMEOUT_MILLIS = 20 * 1000;   // 20s

  @NonNull private final Context context;
  @NonNull private final OkHttpClient client;
  @NonNull private final Converter converter;
  @NonNull private final Url url;
  @NonNull private final Options options;

// Path: library/src/main/java/fr/prcaen/externalresources/converter/Converter.java
// public interface Converter {
//   Resources fromReader(Reader reader) throws IOException;
// }
// 
// Path: library/src/main/java/fr/prcaen/externalresources/exception/ExternalResourceException.java
// public class ExternalResourceException extends RuntimeException {
// 
//   public ExternalResourceException(String detailMessage) {
//     super(detailMessage);
//   }
// 
//   public ExternalResourceException(String message, Throwable cause) {
//     super(message, cause);
//   }
// 
//   public ExternalResourceException(Throwable cause) {
//     super(cause);
//   }
// }
// 
// Path: library/src/main/java/fr/prcaen/externalresources/exception/ResponseException.java
// public final class ResponseException extends ExternalResourceException {
// 
//   private final boolean localCacheOnly;
//   private final int responseCode;
// 
//   public ResponseException(String message, @Cache.Policy int networkPolicy, int responseCode) {
//     super(message);
// 
//     this.localCacheOnly = networkPolicy == Cache.POLICY_OFFLINE;
//     this.responseCode = responseCode;
//   }
// 
//   public boolean isLocalCacheOnly() {
//     return localCacheOnly;
//   }
// 
//   public int getResponseCode() {
//     return responseCode;
//   }
// }
// 
// Path: library/src/main/java/fr/prcaen/externalresources/model/Resources.java
// @SuppressWarnings("unused") public final class Resources {
//   protected final ConcurrentHashMap<String, Resource> members;
// 
//   public Resources() {
//     this.members = new ConcurrentHashMap<>();
//   }
// 
//   public Resources(@NonNull ConcurrentHashMap<String, Resource> members) {
//     this.members = members;
//   }
// 
//   public static Resources from(Reader reader, Converter converter) throws IOException {
//     return converter.fromReader(reader);
//   }
// 
//   public static Resources from(String string, Converter converter) throws IOException {
//     return from(new StringReader(string), converter);
//   }
// 
//   public static Resources fromJson(Reader reader) throws IOException {
//     return from(reader, new JsonConverter());
//   }
// 
//   public static Resources fromJson(String string) throws IOException {
//     return from(string, new JsonConverter());
//   }
// 
//   public static Resources fromJson(InputStream reader) throws IOException {
//     return fromJson(new InputStreamReader(reader));
//   }
// 
//   public static Resources fromXml(Reader reader) throws IOException {
//     return from(reader, new XmlConverter());
//   }
// 
//   public static Resources fromXml(String string) throws IOException {
//     return from(string, new XmlConverter());
//   }
// 
//   public static Resources fromXml(InputStream reader) throws IOException {
//     return fromXml(new InputStreamReader(reader));
//   }
// 
//   public Resource add(String key, Resource value) {
//     return members.put(key, value);
//   }
// 
//   @NonNull protected Set<Entry<String, Resource>> entrySet() {
//     return members.entrySet();
//   }
// 
//   public boolean has(String key) {
//     return members.containsKey(key);
//   }
// 
//   public Resource get(String key) {
//     return members.get(key);
//   }
// 
//   public Resources merge(Resources resources) {
//     members.putAll(resources.members);
// 
//     return this;
//   }
// }
// 
// Path: library/src/main/java/fr/prcaen/externalresources/url/Url.java
// public interface Url {
// 
//   void fontScale(float fontScale);
// 
//   void hardKeyboardHidden(int hardKeyboardHidden);
// 
//   void keyboard(int keyboard);
// 
//   void keyboardHidden(int keyboardHidden);
// 
//   void locale(Locale locale);
// 
//   void mcc(int mcc);
// 
//   void mnc(int mnc);
// 
//   void navigation(int navigation);
// 
//   void navigationHidden(int navigationHidden);
// 
//   void orientation(int orientation);
// 
//   void screenLayout(int screenLayout);
// 
//   void touchscreen(int touchscreen);
// 
//   void uiMode(int uiMode);
// 
//   void densityDpi(int densityDpi);
// 
//   void screenWidthDp(int screenWidthDp);
// 
//   void screenHeightDp(int screenHeightDp);
// 
//   void smallestScreenWidthDp(int smallestScreenWidthDp);
// 
//   String build();
// }


// Path: library/src/main/java/fr/prcaen/externalresources/Downloader.java
import android.content.Context;
import android.content.res.Configuration;
import android.support.annotation.NonNull;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import fr.prcaen.externalresources.converter.Converter;
import fr.prcaen.externalresources.exception.ExternalResourceException;
import fr.prcaen.externalresources.exception.ResponseException;
import fr.prcaen.externalresources.model.Resources;
import fr.prcaen.externalresources.url.Url;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.HONEYCOMB_MR2;
import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;

package fr.prcaen.externalresources;



public final class Downloader {
  private static final int CONNECT_TIMEOUT_MILLIS = 15 * 1000; // 15s
  private static final int READ_TIMEOUT_MILLIS = 20 * 1000;    // 20s
  private static final int WRITE_TIMEOUT_MILLIS = 20 * 1000;   // 20s

  @NonNull private final Context context;
  @NonNull private final OkHttpClient client;
  @NonNull private final Converter converter;
  @NonNull private final Url url;
  @NonNull private final Options options;

  public Downloader(@NonNull Context context, @NonNull Converter converter, @NonNull Url url,