package ch.cern.cvmfs.model;


import android.content.Context;

import com.molina.cvmfs.repository.Repository;
import com.molina.cvmfs.repository.exception.CacheDirectoryNotFound;
import com.molina.cvmfs.repository.exception.FailedToLoadSourceException;
import com.molina.cvmfs.rootfile.exception.RootFileException;

import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Queue;

import ch.cern.cvmfs.R;

public class RepositoryManager extends Thread {

	private static final Object LOCK = new Object();
	private static RepositoryManager INSTANCE;
	private Repository currentRepository;
	private Queue<Runnable> tasks;
	private boolean closed;

	private RepositoryManager() {
		closed = false;
		tasks = new ArrayDeque<>();
	}

	public synchronized static RepositoryManager getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new RepositoryManager();
			INSTANCE.start();
		}
		return INSTANCE;
	}

	public static RepositoryDescription[] getRepositoryList(Context context) {
		String[] unformattedList = context.getResources().getStringArray(R.array.repo_list);
		RepositoryDescription[] repos = new RepositoryDescription[unformattedList.length];
		int i = 0;
		for (String repo : unformattedList) {
			String[] parts = repo.split(";");
			repos[i++] = new RepositoryDescription(parts[0], parts[1], parts[2]);
		}
		return repos;
	}

	@Override
	public void run() {
		while (!closed) {
			while (tasks.isEmpty()) {
				synchronized (INSTANCE) {
					try {
						INSTANCE.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
			Runnable task = tasks.poll();
			task.run();
			synchronized (LOCK) {
				LOCK.notify();
			}
		}
	}

	public synchronized void close() {
		closed = true;
		INSTANCE.notify();
	}

	public Repository setRepositoryInstance(final String url, final String cacheDirectory) {
		tasks.clear();
		addTask(new Runnable() {
			@Override
			public void run() {
				try {
					currentRepository = new Repository(url, cacheDirectory);
				} catch (FailedToLoadSourceException | IOException | RootFileException | CacheDirectoryNotFound e) {
					e.printStackTrace();
				}
			}
		});
		return currentRepository;
	}

	public synchronized Repository getRepositoryInstance() {
		return currentRepository;
	}

	public void addTask(Runnable newTask) {
		synchronized (INSTANCE) {
			tasks.add(newTask);
			INSTANCE.notify();
		}
		synchronized (LOCK) {
			try {
				LOCK.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

@@ -243,24 +243,98 @@
 eException;%0A
+import com.molina.cvmfs.repository.exception.RepositoryNotFoundException;%0A
 import com.m
@@ -590,16 +590,75 @@
 ject();%0A
+%09private static final Object LOCK_INSTANCE = new Object();%0A
 %09private
@@ -1574,32 +1574,37 @@
 %09%09synchronized (
+LOCK_
 INSTANCE) %7B%0A%09%09%09%09
@@ -1616,16 +1616,21 @@
 %7B%0A%09%09%09%09%09%09
+LOCK_
 INSTANCE
@@ -1883,16 +1883,21 @@
 true;%0A%09%09
+LOCK_
 INSTANCE
@@ -1899,24 +1899,27 @@
 TANCE.notify
+All
 ();%0A%09%7D%0A%0A%09pub
@@ -2256,16 +2256,46 @@
 otFound 
+%7C RepositoryNotFoundException 
 e) %7B%0A%09%09%09
@@ -2513,16 +2513,21 @@
 onized (
+LOCK_
 INSTANCE
@@ -2552,24 +2552,29 @@
 ewTask);%0A%09%09%09
+LOCK_
 INSTANCE.not

Use proper lock in RepositoryManager