gt: 		return dbManager.select(url, user.username, null);
context: /*******************************************************************************
   * This file is part of RedReader.
   *
   * RedReader is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * RedReader is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with RedReader.  If not, see <http://www.gnu.org/licenses/>.
   ******************************************************************************/
  
  package org.quantumbadger.redreader.cache;
  
  import android.content.Context;
  import android.content.SharedPreferences;
  import android.net.Uri;
  import android.preference.PreferenceManager;
  import android.util.Log;
  import org.apache.http.*;
  import org.apache.http.client.HttpClient;
  import org.apache.http.client.params.ClientPNames;
  import org.apache.http.conn.params.ConnManagerPNames;
  import org.apache.http.conn.params.ConnPerRoute;
  import org.apache.http.conn.routing.HttpRoute;
  import org.apache.http.conn.scheme.PlainSocketFactory;
  import org.apache.http.conn.scheme.Scheme;
  import org.apache.http.conn.scheme.SchemeRegistry;
  import org.apache.http.conn.ssl.SSLSocketFactory;
  import org.apache.http.impl.client.DefaultHttpClient;
  import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
  import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
  import org.apache.http.params.BasicHttpParams;
  import org.apache.http.params.CoreConnectionPNames;
  import org.apache.http.params.CoreProtocolPNames;
  import org.apache.http.params.HttpParams;
  import org.apache.http.protocol.HttpContext;
  import org.quantumbadger.redreader.account.RedditAccount;
  import org.quantumbadger.redreader.activities.BugReportActivity;
  import org.quantumbadger.redreader.common.*;
  import org.quantumbadger.redreader.jsonwrap.JsonValue;
  
  import java.io.*;
  import java.net.URI;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.LinkedList;
  import java.util.UUID;
  import java.util.concurrent.PriorityBlockingQueue;
  import java.util.concurrent.atomic.AtomicBoolean;
  
  // TODO consider moving to service
  public final class CacheManager {
  
  	private static final String ext = ".rr_cache_data", tempExt = ".rr_cache_data_tmp";
  
  	private static final AtomicBoolean isAlreadyInitialized = new AtomicBoolean(false);
  	private final CacheDbManager dbManager;
  
  	private final PriorityBlockingQueue<CacheRequest> requests = new PriorityBlockingQueue<CacheRequest>();
  
  	private final UniqueSynchronizedQueue<Long> fileDeletionQueue = new UniqueSynchronizedQueue<Long>();
  
  	private final PrioritisedDownloadQueue downloadQueue;
  	private final PrioritisedCachedThreadPool mDiskCacheThreadPool = new PrioritisedCachedThreadPool(2, "Disk Cache");
  
  	private final Context context;
  
  	private static CacheManager singleton;
  
  	public static synchronized CacheManager getInstance(final Context context) {
  		if(singleton == null) singleton = new CacheManager(context.getApplicationContext());
  		return singleton;
  	}
  
  	public static HttpClient createHttpClient(final Context context) {
  
  		final HttpParams params = new BasicHttpParams();
  		params.setParameter(CoreProtocolPNames.USER_AGENT, Constants.ua(context));
  		params.setParameter(CoreConnectionPNames.SO_TIMEOUT, 20000);
  		params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 20000);
  		params.setParameter(CoreConnectionPNames.MAX_HEADER_COUNT, 100);
  		params.setParameter(ClientPNames.HANDLE_REDIRECTS, true);
  		params.setParameter(ClientPNames.MAX_REDIRECTS, 5);
  		params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 50);
  		params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRoute() {
  			public int getMaxForRoute(HttpRoute route) {
  				return 25;
  			}
  		});
  
  		final SchemeRegistry schemeRegistry = new SchemeRegistry();
  		schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
  		schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
  
  		final ThreadSafeClientConnManager connManager = new ThreadSafeClientConnManager(params, schemeRegistry);
  
  		final DefaultHttpClient httpClient = new DefaultHttpClient(connManager, params);
  		httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(3, true));
  
  		httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
  
  			public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException {
  
  				final HttpEntity entity = response.getEntity();
  				final Header encHeader = entity.getContentEncoding();
  
  				if(encHeader == null) return;
  
  				for (final HeaderElement elem : encHeader.getElements()) {
  					if ("gzip".equalsIgnoreCase(elem.getName())) {
  						response.setEntity(new GzipDecompressingEntity(entity));
  						return;
  					}
  				}
  			}
  		});
  
  		return httpClient;
  	}
  
  	private CacheManager(final Context context) {
  
  		if(!isAlreadyInitialized.compareAndSet(false, true)) {
  			throw new RuntimeException("Attempt to initialize the cache twice.");
  		}
  
  		this.context = context;
  
  		dbManager = new CacheDbManager(context);
  
  		final HttpClient httpClient = createHttpClient(context);
  		downloadQueue = new PrioritisedDownloadQueue(httpClient);
  
  		final RequestHandlerThread requestHandler = new RequestHandlerThread();
  		requestHandler.start();
  	}
  
  	private Long isCacheFile(final String file) {
  
  		if(!file.endsWith(ext)) return null;
  
  		final String[] fileSplit = file.split("\\.");
  		if(fileSplit.length != 2) return null;
  
  		try {
  			return Long.parseLong(fileSplit[0]);
  		} catch(Exception e) {
  			return null;
  		}
  	}
  
  	private void getCacheFileList(final File dir, final HashSet<Long> currentFiles) {
  
  		final String[] list = dir.list();
  		if(list == null) return;
  
  		for(final String file : list) {
  
  			final Long cacheFileId = isCacheFile(file);
  
  			if(cacheFileId != null) {
  				currentFiles.add(cacheFileId);
  			}
  		}
  	}
  
  	private static void pruneTemp(final File dir) {
  
  		final String[] list = dir.list();
  		if(list == null) return;
  
  		for(final String file : list) {
  
  			if(file.endsWith(tempExt)) {
  				new File(dir, file).delete();
  			}
  		}
  	}
  
  	public void pruneTemp() {
  
  		final File externalCacheDir = context.getExternalCacheDir();
  		final File internalCacheDir = context.getCacheDir();
  
  		if(externalCacheDir != null) {
  			pruneTemp(externalCacheDir);
  		}
  
  		if(internalCacheDir != null) {
  			pruneTemp(internalCacheDir);
  		}
  	}
  
  	public synchronized void pruneCache() {
  
  		try {
  
  			final HashSet<Long> currentFiles = new HashSet<Long>(128);
  
  			final File externalCacheDir = context.getExternalCacheDir();
  			final File internalCacheDir = context.getCacheDir();
  
  			if(externalCacheDir != null) {
  				getCacheFileList(externalCacheDir, currentFiles);
  			}
  
  			if(internalCacheDir != null) {
  				getCacheFileList(internalCacheDir, currentFiles);
  			}
  
  			final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
  			final HashMap<Integer, Long> maxAge = PrefsUtility.pref_cache_maxage(context, prefs);
  
  			final LinkedList<Long> filesToDelete = dbManager.getFilesToPrune(currentFiles, maxAge, 72);
  			for(final long id : filesToDelete) {
  				fileDeletionQueue.enqueue(id);
  			}
  
  		} catch(Throwable t) {
  			BugReportActivity.handleGlobalError(context, t);
  		}
  
  	}
  
  	public synchronized void emptyTheWholeCache() {
  		dbManager.emptyTheWholeCache();
  	}
  
  	public void makeRequest(final CacheRequest request) {
  		requests.put(request);
  	}
  
  	private void processDeletionQueue() {
  
  		final int maxToDelete = 2;
  
  		int deleted = 0;
  
  		Long toDelete;
  
  		while(maxToDelete > deleted++ && (toDelete = fileDeletionQueue.dequeue()) != null) {
  
  			// Attempt to delete file
  			final File f = getExistingCacheFile(toDelete);
  
  			if(f != null && !f.delete()) {
  				f.deleteOnExit();
  			}
  		}
  	}
  
  	public LinkedList<CacheEntry> getSessions(URI url, RedditAccount user) {
  