diff --git a/chrome/content/zotero/xpcom/connector/repo.js b/chrome/content/zotero/xpcom/connector/repo.js
index 87eeb81d2c..a9f6601202 100644
--- a/chrome/content/zotero/xpcom/connector/repo.js
+++ b/chrome/content/zotero/xpcom/connector/repo.js
@@ -29,6 +29,9 @@ Zotero.Repo = new function() {
 	var _timeoutID;
 	const infoRe = /^\s*{[\S\s]*?}\s*?[\r\n]/;
 	
+	this.SOURCE_ZOTERO_STANDALONE = 1;
+	this.SOURCE_REPO = 2;
+	
 	/**
 	 * Try to retrieve translator metadata from Zotero Standalone and initialize repository check
 	 * timer
@@ -58,13 +61,14 @@ Zotero.Repo = new function() {
 		// try standalone
 		Zotero.Connector.callMethod("getTranslatorCode", {"translatorID":translatorID}, function(result) {
 			if(result) {
-				_haveCode(result, translatorID, callback);
+				_haveCode(result, translatorID, Zotero.Repo.SOURCE_ZOTERO_STANDALONE, callback);
 				return;
 			}
 			
 			// then try repo
-			Zotero.HTTP.doGet(ZOTERO_CONFIG.REPOSITORY_URL+"/code/"+translatorID, function(xmlhttp) {
-				_haveCode(xmlhttp.status === 200 ? xmlhttp.responseText : false, translatorID, callback);
+			Zotero.HTTP.doGet(ZOTERO_CONFIG.REPOSITORY_URL+"/code/"+ZOTERO_CONFIG.REPOSITORY_CHANNEL+"/"+translatorID, function(xmlhttp) {
+				_haveCode(xmlhttp.status === 200 ? xmlhttp.responseText : false, translatorID,
+					Zotero.Repo.SOURCE_REPO, callback);
 			});
 		});
 	};
@@ -72,7 +76,7 @@ Zotero.Repo = new function() {
 	/**
 	 * Called when code has been retrieved from standalone or repo
 	 */
-	function _haveCode(code, translatorID, callback) {
+	function _haveCode(code, translatorID, source, callback) {
 		if(!code) {
 			Zotero.logError(new Error("Code could not be retrieved for " + translatorID));
 			callback(false);
@@ -112,7 +116,7 @@ Zotero.Repo = new function() {
 				}
 			}
 		}
-		callback(code);
+		callback(code, source);
 	}
 	
 	/**
diff --git a/chrome/content/zotero/xpcom/connector/translator.js b/chrome/content/zotero/xpcom/connector/translator.js
index 253d9bb873..38bb15121a 100644
--- a/chrome/content/zotero/xpcom/connector/translator.js
+++ b/chrome/content/zotero/xpcom/connector/translator.js
@@ -110,7 +110,8 @@ Zotero.Translators = new function() {
 		}
 		
 		// only need to get code if it is of some use
-		if(translator.runMode === Zotero.Translator.RUN_MODE_IN_BROWSER) {
+		if(translator.runMode === Zotero.Translator.RUN_MODE_IN_BROWSER
+				&& !translator.hasOwnProperty("code")) {
 			translator.getCode(function() { callback(translator) });
 		} else {
 			callback(translator);
@@ -120,14 +121,16 @@ Zotero.Translators = new function() {
 	/**
 	 * Gets all translators for a specific type of translation
 	 * @param {String} type The type of translators to get (import, export, web, or search)
-	 * @param {Function} [callback] An optional callback to be executed when translators have been
-	 *                              retrieved. If no callback is specified, translators are
-	 *                              returned.
+	 * @param {Function} callback A required callback to be executed when translators have been
+	 *                            retrieved.
+	 * @param {Boolean} [debugMode] Whether to assume debugging mode. If true, code is included for 
+	 *                              unsupported translators, and code originally retrieved from the
+	 *                              repo is re-retrieved from Zotero Standalone.
 	 */
-	this.getAllForType = function(type, callback, includeUnsupported) {
+	this.getAllForType = function(type, callback, debugMode) {
 		if(!_initialized) Zotero.Translators.init()
 		var translators = _cache[type].slice(0);
-		new Zotero.Translators.CodeGetter(translators, callback, translators, includeUnsupported);
+		new Zotero.Translators.CodeGetter(translators, callback, translators, debugMode);
 		return true;
 	}
 	
@@ -325,13 +328,13 @@ Zotero.Translators = new function() {
  * @param {Zotero.Translator[]} translators Translators for which to retrieve code
  * @param {Function} callback Callback to call once code has been retrieved
  * @param {Function} callbackArgs All arguments to be passed to callback (including translators)
- * @param {Boolean} [includeUnsupported] If true, include code for unsupported translators
+ * @param {Boolean} [debugMode] If true, include code for unsupported translators
  */
-Zotero.Translators.CodeGetter = function(translators, callback, callbackArgs, includeUnsupported) {
+Zotero.Translators.CodeGetter = function(translators, callback, callbackArgs, debugMode) {
 	this._translators = translators;
 	this._callbackArgs = callbackArgs;
 	this._callback = callback;
-	this._includeUnsupported = includeUnsupported;
+	this._debugMode = debugMode;
 	this.getCodeFor(0);
 }
 
@@ -344,9 +347,17 @@ Zotero.Translators.CodeGetter.prototype.getCodeFor = function(i) {
 			return;
 		}
 		
-		if(this._translators[i].runMode === Zotero.Translator.RUN_MODE_IN_BROWSER || this._includeUnsupported) {
-			// get next translator
-			this._translators[i].getCode(function() { me.getCodeFor(i+1) });
+		var translator = this._translators[i];
+		
+		// retrieve code if no code and translator is supported locally
+		if((translator.runMode === Zotero.Translator.RUN_MODE_IN_BROWSER && !translator.hasOwnProperty("code"))
+				// or if debug mode is enabled (even if unsupported locally)
+				|| (this._debugMode && (!translator.hasOwnProperty("code")
+				// or if in debug mode and the code we have came from the repo (which doesn't
+				// include test cases)
+				|| translator.codeSource === Zotero.Repo.SOURCE_REPO))) {
+				// get next translator
+			translator.getCode(function() { me.getCodeFor(i+1) });
 			return;
 		}
 		
@@ -439,22 +450,19 @@ Zotero.Translator.prototype.init = function(info) {
  * Retrieves code for this translator
  */
 Zotero.Translator.prototype.getCode = function(callback) {
-	if(this.code) {
-		callback(true);
-	} else {
-		var me = this;
-		Zotero.Repo.getTranslatorCode(this.translatorID,
-			function(code) {
-				if(!code) {
-					callback(false);
-				} else {
-					// cache code for session only (we have standalone anyway)
-					me.code = code;
-					callback(true);
-				}
+	var me = this;
+	Zotero.Repo.getTranslatorCode(this.translatorID,
+		function(code, source) {
+			if(!code) {
+				callback(false);
+			} else {
+				// cache code for session only (we have standalone anyway)
+				me.code = code;
+				me.codeSource = source;
+				callback(true);
 			}
-		);
-	}
+		}
+	);
 }
 
 Zotero.Translator.prototype.__defineGetter__("displayOptions", function() {
diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js
index 7afc1a0f7a..3942badf0d 100644
--- a/chrome/content/zotero/xpcom/zotero.js
+++ b/chrome/content/zotero/xpcom/zotero.js
@@ -29,6 +29,7 @@ const ZOTERO_CONFIG = {
 	REPOSITORY_URL: 'https://repo.zotero.org/repo',
 	REPOSITORY_CHECK_INTERVAL: 86400, // 24 hours
 	REPOSITORY_RETRY_INTERVAL: 3600, // 1 hour
+	REPOSITORY_CHANNEL: 'trunk',
 	BASE_URI: 'http://zotero.org/',
 	WWW_BASE_URL: 'http://www.zotero.org/',
 	SYNC_URL: 'https://sync.zotero.org/',