gt:                 if (operation != null) {
context: /*
   * This is the source code of Telegram for Android v. 3.x.x.
   * It is licensed under GNU GPL v. 2 or later.
   * You should have received a copy of the license in this archive (see LICENSE).
   *
   * Copyright Nikolai Kudashov, 2013-2017.
   */
  
  package com.porogram.profosure1.messenger;
  
  import com.porogram.profosure1.tgnet.TLObject;
  import com.porogram.profosure1.tgnet.TLRPC;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.LinkedList;
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.concurrent.Semaphore;
  
  public class FileLoader {
  
      public interface FileLoaderDelegate {
          void fileUploadProgressChanged(String location, float progress, boolean isEncrypted);
          void fileDidUploaded(String location, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile, byte[] key, byte[] iv, long totalFileSize);
          void fileDidFailedUpload(String location, boolean isEncrypted);
          void fileDidLoaded(String location, File finalFile, int type);
          void fileDidFailedLoad(String location, int state);
          void fileLoadProgressChanged(String location, float progress);
      }
  
      public static final int MEDIA_DIR_IMAGE = 0;
      public static final int MEDIA_DIR_AUDIO = 1;
      public static final int MEDIA_DIR_VIDEO = 2;
      public static final int MEDIA_DIR_DOCUMENT = 3;
      public static final int MEDIA_DIR_CACHE = 4;
  
      private HashMap<Integer, File> mediaDirs = null;
      private volatile DispatchQueue fileLoaderQueue = new DispatchQueue("fileUploadQueue");
  
      private LinkedList<FileUploadOperation> uploadOperationQueue = new LinkedList<>();
      private LinkedList<FileUploadOperation> uploadSmallOperationQueue = new LinkedList<>();
      private LinkedList<FileLoadOperation> loadOperationQueue = new LinkedList<>();
      private LinkedList<FileLoadOperation> audioLoadOperationQueue = new LinkedList<>();
      private LinkedList<FileLoadOperation> photoLoadOperationQueue = new LinkedList<>();
      private ConcurrentHashMap<String, FileUploadOperation> uploadOperationPaths = new ConcurrentHashMap<>();
      private ConcurrentHashMap<String, FileUploadOperation> uploadOperationPathsEnc = new ConcurrentHashMap<>();
      private ConcurrentHashMap<String, FileLoadOperation> loadOperationPaths = new ConcurrentHashMap<>();
      private HashMap<String, Long> uploadSizes = new HashMap<>();
  
      private FileLoaderDelegate delegate = null;
  
      private int currentLoadOperationsCount = 0;
      private int currentAudioLoadOperationsCount = 0;
      private int currentPhotoLoadOperationsCount = 0;
      private int currentUploadOperationsCount = 0;
      private int currentUploadSmallOperationsCount = 0;
  
      private static volatile FileLoader Instance = null;
  
      public static FileLoader getInstance() {
          FileLoader localInstance = Instance;
          if (localInstance == null) {
              synchronized (FileLoader.class) {
                  localInstance = Instance;
                  if (localInstance == null) {
                      Instance = localInstance = new FileLoader();
                  }
              }
          }
          return localInstance;
      }
  
      public void setMediaDirs(HashMap<Integer, File> dirs) {
          mediaDirs = dirs;
      }
  
      public File checkDirectory(int type) {
          return mediaDirs.get(type);
      }
  
      public File getDirectory(int type) {
          File dir = mediaDirs.get(type);
          if (dir == null && type != MEDIA_DIR_CACHE) {
              dir = mediaDirs.get(MEDIA_DIR_CACHE);
          }
          try {
              if (!dir.isDirectory()) {
                  dir.mkdirs();
              }
          } catch (Exception e) {
              //don't promt
          }
          return dir;
      }
  
      public void cancelUploadFile(final String location, final boolean enc) {
          fileLoaderQueue.postRunnable(new Runnable() {
              @Override
              public void run() {
                  FileUploadOperation operation;
                  if (!enc) {
                      operation = uploadOperationPaths.get(location);
                  } else {
                      operation = uploadOperationPathsEnc.get(location);
                  }
                  uploadSizes.remove(location);
                  if (operation != null) {
                      uploadOperationPathsEnc.remove(location);
                      uploadOperationQueue.remove(operation);
                      uploadSmallOperationQueue.remove(operation);
                      operation.cancel();
                  }
              }
          });
      }
  
      public void checkUploadNewDataAvailable(final String location, final boolean encrypted, final long finalSize) {
          fileLoaderQueue.postRunnable(new Runnable() {
              @Override
              public void run() {
                  FileUploadOperation operation;
                  if (encrypted) {
                      operation = uploadOperationPathsEnc.get(location);
                  } else {
                      operation = uploadOperationPaths.get(location);
                  }
                  if (operation != null) {
                      operation.checkNewDataAvailable(finalSize);
                  } else if (finalSize != 0) {
                      uploadSizes.put(location, finalSize);
                  }
              }
          });
      }
  
      public void uploadFile(final String location, final boolean encrypted, final boolean small, final int type) {
          uploadFile(location, encrypted, small, 0, type);
      }
  
      public void uploadFile(final String location, final boolean encrypted, final boolean small, final int estimatedSize, final int type) {
          if (location == null) {
              return;
          }
          fileLoaderQueue.postRunnable(new Runnable() {
              @Override
              public void run() {
                  if (encrypted) {
                      if (uploadOperationPathsEnc.containsKey(location)) {
                          return;
                      }
                  } else {
                      if (uploadOperationPaths.containsKey(location)) {
                          return;
                      }
                  }
                  int esimated = estimatedSize;
                  if (esimated != 0) {
                      Long finalSize = uploadSizes.get(location);
                      if (finalSize != null) {
                          esimated = 0;
                          uploadSizes.remove(location);
                      }
                  }
                  FileUploadOperation operation = new FileUploadOperation(location, encrypted, esimated, type);
                  if (encrypted) {
                      uploadOperationPathsEnc.put(location, operation);
                  } else {
                      uploadOperationPaths.put(location, operation);
                  }
                  operation.setDelegate(new FileUploadOperation.FileUploadOperationDelegate() {
                      @Override
                      public void didFinishUploadingFile(final FileUploadOperation operation, final TLRPC.InputFile inputFile, final TLRPC.InputEncryptedFile inputEncryptedFile, final byte[] key, final byte[] iv) {
                          fileLoaderQueue.postRunnable(new Runnable() {
                              @Override
                              public void run() {
                                  if (encrypted) {
                                      uploadOperationPathsEnc.remove(location);
                                  } else {
                                      uploadOperationPaths.remove(location);
                                  }
                                  if (small) {
                                      currentUploadSmallOperationsCount--;
                                      if (currentUploadSmallOperationsCount < 1) {
                                          FileUploadOperation operation = uploadSmallOperationQueue.poll();
                                          if (operation != null) {
                                              currentUploadSmallOperationsCount++;
                                              operation.start();
                                          }
                                      }
                                  } else {
                                      currentUploadOperationsCount--;
                                      if (currentUploadOperationsCount < 1) {
                                          FileUploadOperation operation = uploadOperationQueue.poll();
                                          if (operation != null) {
                                              currentUploadOperationsCount++;
                                              operation.start();
                                          }
                                      }
                                  }
                                  if (delegate != null) {
                                      delegate.fileDidUploaded(location, inputFile, inputEncryptedFile, key, iv, operation.getTotalFileSize());
                                  }
                              }
                          });
                      }
  
                      @Override
                      public void didFailedUploadingFile(final FileUploadOperation operation) {
                          fileLoaderQueue.postRunnable(new Runnable() {
                              @Override
                              public void run() {
                                  if (encrypted) {
                                      uploadOperationPathsEnc.remove(location);
                                  } else {
                                      uploadOperationPaths.remove(location);
                                  }
                                  if (delegate != null) {
                                      delegate.fileDidFailedUpload(location, encrypted);
                                  }
                                  if (small) {
                                      currentUploadSmallOperationsCount--;
                                      if (currentUploadSmallOperationsCount < 1) {
                                          FileUploadOperation operation = uploadSmallOperationQueue.poll();
                                          if (operation != null) {
                                              currentUploadSmallOperationsCount++;
                                              operation.start();
                                          }
                                      }
                                  } else {
                                      currentUploadOperationsCount--;
                                      if (currentUploadOperationsCount < 1) {
                                          FileUploadOperation operation = uploadOperationQueue.poll();
                                          if (operation != null) {
                                              currentUploadOperationsCount++;
                                              operation.start();
                                          }
                                      }
                                  }
                              }
                          });
                      }
  
                      @Override
                      public void didChangedUploadProgress(FileUploadOperation operation, final float progress) {
                          if (delegate != null) {
                              delegate.fileUploadProgressChanged(location, progress, encrypted);
                          }
                      }
                  });
                  if (small) {
                      if (currentUploadSmallOperationsCount < 1) {
                          currentUploadSmallOperationsCount++;
                          operation.start();
                      } else {
                          uploadSmallOperationQueue.add(operation);
                      }
                  } else {
                      if (currentUploadOperationsCount < 1) {
                          currentUploadOperationsCount++;
                          operation.start();
                      } else {
                          uploadOperationQueue.add(operation);
                      }
                  }
              }
          });
      }
  
      public void cancelLoadFile(TLRPC.Document document) {
          cancelLoadFile(document, null, null, null);
      }
  
      public void cancelLoadFile(TLRPC.TL_webDocument document) {
          cancelLoadFile(null, document, null, null);
      }
  
      public void cancelLoadFile(TLRPC.PhotoSize photo) {
          cancelLoadFile(null, null, photo.location, null);
      }
  
      public void cancelLoadFile(TLRPC.FileLocation location, String ext) {
          cancelLoadFile(null, null, location, ext);
      }
  
      private void cancelLoadFile(final TLRPC.Document document, final TLRPC.TL_webDocument webDocument, final TLRPC.FileLocation location, final String locationExt) {
          if (location == null && document == null) {
              return;
          }
          fileLoaderQueue.postRunnable(new Runnable() {
              @Override
              public void run() {
                  String fileName = null;
                  if (location != null) {
                      fileName = getAttachFileName(location, locationExt);
                  } else if (document != null) {
                      fileName = getAttachFileName(document);
                  } else if (webDocument != null) {
                      fileName = getAttachFileName(webDocument);
                  }
                  if (fileName == null) {
                      return;
                  }
                  FileLoadOperation operation = loadOperationPaths.remove(fileName);
  