diff --git a/chrome/content/zotero/xpcom/connector/translate_item.js b/chrome/content/zotero/xpcom/connector/translate_item.js
index 770294325..6c9a76bbc 100644
--- a/chrome/content/zotero/xpcom/connector/translate_item.js
+++ b/chrome/content/zotero/xpcom/connector/translate_item.js
@@ -38,19 +38,6 @@ Zotero.Translate.ItemSaver.prototype = {
* Saves items to Standalone or the server
*/
"saveItems":function(items, callback) {
- // don't save documents as documents, since we can't pass them around
- var nItems = items.length;
- for(var i=0; i.
+
+ ***** END LICENSE BLOCK *****
+*/
+
+/**
+ * @class Manages the translator sandbox
+ * @param {Zotero.Translate} translate
+ * @param {String|window} sandboxLocation
+ */
+Zotero.Translate.SandboxManager = function(sandboxLocation) {
+ this.sandbox = {"Zotero":{}};
+}
+
+Zotero.Translate.SandboxManager.prototype = {
+ /**
+ * Evaluates code in the sandbox
+ * @param {String} code Code to evaluate
+ * @param {String[]} functions Functions to import into the sandbox (rather than leaving
+ * as inner functions)
+ */
+ "eval":function(code, functions) {
+ // delete functions to import
+ for(var i in functions) {
+ delete this.sandbox[functions[i]];
+ }
+
+ // eval in sandbox scope
+ with(this.sandbox) {
+ eval(code);
+ }
+ // import inner functions (what a mess)
+ for(var i in functions) {
+ try {
+ this.sandbox[functions[i]] = eval(functions[i]);
+ } catch(e) {}
+ }
+ },
+
+ /**
+ * Imports an object into the sandbox
+ *
+ * @param {Object} object Object to be imported (under Zotero)
+ * @param {Boolean} passTranslateAsFirstArgument Whether the translate instance should be passed
+ * as the first argument to the function.
+ */
+ "importObject":function(object, passAsFirstArgument, attachTo) {
+ if(!attachTo) attachTo = this.sandbox.Zotero;
+
+ for(var key in (object.__exposedProps__ ? object.__exposedProps__ : object)) {
+ if(Function.prototype[key]) continue;
+ if(typeof object[key] === "function" || typeof object[key] === "object") {
+ // magic closures
+ attachTo[key] = new function() {
+ var fn = object[key];
+ return function() {
+ var args = (passAsFirstArgument ? [passAsFirstArgument] : []);
+ for(var i=0; i