// Path: MyApplication/app/src/main/java/com/example/mikhail_sianko/myapplication/threads/OnResultCallback.java
// public interface OnResultCallback<Result, Progress> extends ProgressCallback<Progress> {
// 
//     void onSuccess(Result result);
// 
//     void onError(Exception e);
// }
// 
// Path: MyApplication/app/src/main/java/com/example/mikhail_sianko/myapplication/threads/Operation.java
// public interface Operation<Params, Progress, Result> {
// 
//     Result doing(Params params, ProgressCallback<Progress> progressCallback) throws Exception;
// 
// }
// 
// Path: MyApplication/app/src/main/java/com/example/mikhail_sianko/myapplication/threads/ProgressCallback.java
// public interface ProgressCallback<Progress> {
// 
//     void onProgressChanged(Progress progress);
// 
// }
// 
// Path: MyApplication/app/src/main/java/com/example/mikhail_sianko/myapplication/threads/ThreadManager.java
// public class ThreadManager {
// 
//     public static final int COUNT_CORE = 3;
//     private final ExecutorService executorService;
// 
//     public ThreadManager() {
//         this(Executors.newFixedThreadPool(3));
//     }
// 
//     public ThreadManager(final ExecutorService executorService) {
//         this.executorService = executorService;
//     }
// 
//     public<Params, Progress, Result> void execute(final Operation<Params, Progress, Result> operation, final Params param, final OnResultCallback<Result, Progress> onResultCallback) {
//         final Handler handler = new Handler();
//         executorService.execute(new Runnable() {
// 
//             @Override
//             public void run() {
//                 try {
//                     final Result result = operation.doing(param, new ProgressCallback<Progress>() {
// 
//                         @Override
//                         public void onProgressChanged(final Progress progress) {
//                             handler.post(new Runnable() {
// 
//                                 @Override
//                                 public void run() {
//                                     onResultCallback.onProgressChanged(progress);
//                                 }
//                             });
//                         }
//                     });
//                     handler.post(new Runnable() {
// 
//                         @Override
//                         public void run() {
//                             onResultCallback.onSuccess(result);
//                         }
//                     });
//                 } catch (Exception e) {
//                     onResultCallback.onError(e);
//                 }
//             }
//         });
//     }
// 
// }
// 
// Path: MyApplication/util-lib/src/main/java/com/training2016/android/http/HttpClient.java
// public class HttpClient {
// 
//     public String get(String url) throws Exception {
//         return doRequest(url, "GET", null, null);
//     }
// 
//     public String get(String url, Map<String, String> headers) throws Exception {
//         return doRequest(url, "GET", headers, null);
//     }
// 
//     public String post(String url, Map<String, String> header, String body) throws Exception {
//         return doRequest(url, "POST", header, body);
//     }
// 
//     private String doRequest(String url, String type, Map<String, String> header, String body) throws Exception {
//         String response = null;
//         HttpURLConnection connection = null;
//         try {
//             URL reqUrl = new URL(url);
//             connection = ((HttpURLConnection) reqUrl.openConnection());
//             connection.setRequestMethod(type);
//             if (header != null) {
//                 for (String key : header.keySet()) {
//                     connection.addRequestProperty(key, header.get(key));
//                 }
//             }
//             if (body != null) {
//                 applyBody(connection, body);
//             }
// 
//             InputStream inputStream;
// 
//             boolean isSuccess = connection.getResponseCode() >= 200 && connection.getResponseCode() < 300;
//             if (isSuccess) {
//                 inputStream = connection.getInputStream();
//             } else {
//                 inputStream = connection.getErrorStream();
//             }
// 
//             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//             StringBuilder stringBuilder = new StringBuilder();
//             String line;
//             while ((line = reader.readLine()) != null) {
//                 stringBuilder.append(line);
//             }
//             response = stringBuilder.toString();
// 
//             inputStream.close();
// 
//             if (!isSuccess) {
//                 System.out.println("http exception = " + response);
//                 throw new Exception(response);
//             }
// 
//         } finally {
//             if (connection != null) {
//                 connection.disconnect();
//             }
//         }
//         return response;
//     }
// 
//     public interface ResultConverter<Result> {
// 
//         Result convert(InputStream inputStream);
// 
//     }
// 
//     public <Result> Result getResult(String url, ResultConverter<Result> resultConverter) throws IOException {
//         HttpURLConnection connection = null;
//         InputStream inputStream = null;
//         try {
//             URL reqUrl = new URL(url);
//             connection = ((HttpURLConnection) reqUrl.openConnection());
//             connection.setRequestMethod("GET");
//             inputStream = connection.getInputStream();
//             return resultConverter.convert(inputStream);
//         } finally {
//             if (inputStream != null) {
//                 inputStream.close();
//             }
//             if (connection != null) {
//                 connection.disconnect();
//             }
//         }
//     }
// 
//     private void applyBody(HttpURLConnection httpURLConnection, String body) throws Exception {
//         byte[] outputInBytes = body.getBytes("UTF-8");
//         OutputStream os = httpURLConnection.getOutputStream();
//         os.write(outputInBytes);
//         os.close();
//     }
// 
// 
// }


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.widget.ImageView;
import com.example.mikhail_sianko.myapplication.threads.OnResultCallback;
import com.example.mikhail_sianko.myapplication.threads.Operation;
import com.example.mikhail_sianko.myapplication.threads.ProgressCallback;
import com.example.mikhail_sianko.myapplication.threads.ThreadManager;
import com.training2016.android.http.HttpClient;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.concurrent.Executors;
package com.example.mikhail_sianko.myapplication.malevich;




class MalevichImpl implements Malevich {

    public static final int MAX_MEMORY_FOR_IMAGES = 64 * 1000 * 1000;

    //TODO queue LIFO
// Path: MyApplication/app/src/main/java/com/example/mikhail_sianko/myapplication/threads/OnResultCallback.java
// public interface OnResultCallback<Result, Progress> extends ProgressCallback<Progress> {
// 
//     void onSuccess(Result result);
// 
//     void onError(Exception e);
// }
// 
// Path: MyApplication/app/src/main/java/com/example/mikhail_sianko/myapplication/threads/Operation.java
// public interface Operation<Params, Progress, Result> {
// 
//     Result doing(Params params, ProgressCallback<Progress> progressCallback) throws Exception;
// 
// }
// 
// Path: MyApplication/app/src/main/java/com/example/mikhail_sianko/myapplication/threads/ProgressCallback.java
// public interface ProgressCallback<Progress> {
// 
//     void onProgressChanged(Progress progress);
// 
// }
// 
// Path: MyApplication/app/src/main/java/com/example/mikhail_sianko/myapplication/threads/ThreadManager.java
// public class ThreadManager {
// 
//     public static final int COUNT_CORE = 3;
//     private final ExecutorService executorService;
// 
//     public ThreadManager() {
//         this(Executors.newFixedThreadPool(3));
//     }
// 
//     public ThreadManager(final ExecutorService executorService) {
//         this.executorService = executorService;
//     }
// 
//     public<Params, Progress, Result> void execute(final Operation<Params, Progress, Result> operation, final Params param, final OnResultCallback<Result, Progress> onResultCallback) {
//         final Handler handler = new Handler();
//         executorService.execute(new Runnable() {
// 
//             @Override
//             public void run() {
//                 try {
//                     final Result result = operation.doing(param, new ProgressCallback<Progress>() {
// 
//                         @Override
//                         public void onProgressChanged(final Progress progress) {
//                             handler.post(new Runnable() {
// 
//                                 @Override
//                                 public void run() {
//                                     onResultCallback.onProgressChanged(progress);
//                                 }
//                             });
//                         }
//                     });
//                     handler.post(new Runnable() {
// 
//                         @Override
//                         public void run() {
//                             onResultCallback.onSuccess(result);
//                         }
//                     });
//                 } catch (Exception e) {
//                     onResultCallback.onError(e);
//                 }
//             }
//         });
//     }
// 
// }
// 
// Path: MyApplication/util-lib/src/main/java/com/training2016/android/http/HttpClient.java
// public class HttpClient {
// 
//     public String get(String url) throws Exception {
//         return doRequest(url, "GET", null, null);
//     }
// 
//     public String get(String url, Map<String, String> headers) throws Exception {
//         return doRequest(url, "GET", headers, null);
//     }
// 
//     public String post(String url, Map<String, String> header, String body) throws Exception {
//         return doRequest(url, "POST", header, body);
//     }
// 
//     private String doRequest(String url, String type, Map<String, String> header, String body) throws Exception {
//         String response = null;
//         HttpURLConnection connection = null;
//         try {
//             URL reqUrl = new URL(url);
//             connection = ((HttpURLConnection) reqUrl.openConnection());
//             connection.setRequestMethod(type);
//             if (header != null) {
//                 for (String key : header.keySet()) {
//                     connection.addRequestProperty(key, header.get(key));
//                 }
//             }
//             if (body != null) {
//                 applyBody(connection, body);
//             }
// 
//             InputStream inputStream;
// 
//             boolean isSuccess = connection.getResponseCode() >= 200 && connection.getResponseCode() < 300;
//             if (isSuccess) {
//                 inputStream = connection.getInputStream();
//             } else {
//                 inputStream = connection.getErrorStream();
//             }
// 
//             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//             StringBuilder stringBuilder = new StringBuilder();
//             String line;
//             while ((line = reader.readLine()) != null) {
//                 stringBuilder.append(line);
//             }
//             response = stringBuilder.toString();
// 
//             inputStream.close();
// 
//             if (!isSuccess) {
//                 System.out.println("http exception = " + response);
//                 throw new Exception(response);
//             }
// 
//         } finally {
//             if (connection != null) {
//                 connection.disconnect();
//             }
//         }
//         return response;
//     }
// 
//     public interface ResultConverter<Result> {
// 
//         Result convert(InputStream inputStream);
// 
//     }
// 
//     public <Result> Result getResult(String url, ResultConverter<Result> resultConverter) throws IOException {
//         HttpURLConnection connection = null;
//         InputStream inputStream = null;
//         try {
//             URL reqUrl = new URL(url);
//             connection = ((HttpURLConnection) reqUrl.openConnection());
//             connection.setRequestMethod("GET");
//             inputStream = connection.getInputStream();
//             return resultConverter.convert(inputStream);
//         } finally {
//             if (inputStream != null) {
//                 inputStream.close();
//             }
//             if (connection != null) {
//                 connection.disconnect();
//             }
//         }
//     }
// 
//     private void applyBody(HttpURLConnection httpURLConnection, String body) throws Exception {
//         byte[] outputInBytes = body.getBytes("UTF-8");
//         OutputStream os = httpURLConnection.getOutputStream();
//         os.write(outputInBytes);
//         os.close();
//     }
// 
// 
// }


// Path: MyApplication/app/src/main/java/com/example/mikhail_sianko/myapplication/malevich/MalevichImpl.java
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.widget.ImageView;
import com.example.mikhail_sianko.myapplication.threads.OnResultCallback;
import com.example.mikhail_sianko.myapplication.threads.Operation;
import com.example.mikhail_sianko.myapplication.threads.ProgressCallback;
import com.example.mikhail_sianko.myapplication.threads.ThreadManager;
import com.training2016.android.http.HttpClient;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.concurrent.Executors;

package com.example.mikhail_sianko.myapplication.malevich;




class MalevichImpl implements Malevich {

    public static final int MAX_MEMORY_FOR_IMAGES = 64 * 1000 * 1000;

    //TODO queue LIFO
    private ThreadManager threadManager = new ThreadManager(Executors.newFixedThreadPool(ThreadManager.COUNT_CORE));