diff --git a/.eslintrc b/.eslintrc
index bcd88942f..fcb231522 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -8,7 +8,7 @@
         "max-len": [2, 80, 4],
         "semi": [2, "always"],
         "strict": [2, "never"],
-        "no-console": [2, {"allow": ["log", "warn", "error", "groupCollapsed", "groupEnd"]}],
+        "no-console": [2, {"allow": ["log", "warn", "error", "groupCollapsed", "groupEnd", "time", "timeEnd"]}],
         "valid-jsdoc": ["error", {"requireReturn": false}]
     },
     "env": {
diff --git a/package.json b/package.json
index e55a497e1..2d4d54773 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,8 @@
   },
   "dependencies": {
     "htmlparser2": "3.9.0",
-    "memoizee": "0.3.10"
+    "memoizee": "0.3.10",
+    "promise": "7.1.1"
   },
   "devDependencies": {
     "eslint": "2.7.0",
diff --git a/playground/index.html b/playground/index.html
index 0d4903d3d..82535807b 100644
--- a/playground/index.html
+++ b/playground/index.html
@@ -79,12 +79,6 @@
           </block>
           <block type="control_delete_this_clone"></block>
         </category>
-        <category name="Wedo">
-            <block type="wedo_setcolor"></block>
-            <block type="wedo_motorspeed"></block>
-            <block type="wedo_whentilt"></block>
-            <block type="wedo_whendistanceclose"></block>
-        </category>
         <category name="Operators">
             <block type="operator_add">
               <value name="NUM1">
diff --git a/src/blocks/scratch3_control.js b/src/blocks/scratch3_control.js
index 1d05a8c7a..e13edefd9 100644
--- a/src/blocks/scratch3_control.js
+++ b/src/blocks/scratch3_control.js
@@ -1,3 +1,5 @@
+var Promise = require('promise');
+
 function Scratch3ControlBlocks(runtime) {
     /**
      * The runtime instantiating this block package.
@@ -38,11 +40,12 @@ Scratch3ControlBlocks.prototype.forever = function(args, util) {
     util.startSubstack();
 };
 
-Scratch3ControlBlocks.prototype.wait = function(args, util) {
-    util.yield();
-    util.timeout(function() {
-        util.done();
-    }, 1000 * args.DURATION);
+Scratch3ControlBlocks.prototype.wait = function(args) {
+    return new Promise(function(resolve) {
+        setTimeout(function() {
+            resolve();
+        }, 1000 * args.DURATION);
+    });
 };
 
 Scratch3ControlBlocks.prototype.if = function(args, util) {
diff --git a/src/blocks/scratch3_operators.js b/src/blocks/scratch3_operators.js
index 94329b5a3..75077061c 100644
--- a/src/blocks/scratch3_operators.js
+++ b/src/blocks/scratch3_operators.js
@@ -1,3 +1,5 @@
+var Promise = require('promise');
+
 function Scratch3OperatorsBlocks(runtime) {
     /**
      * The runtime instantiating this block package.
@@ -15,7 +17,16 @@ Scratch3OperatorsBlocks.prototype.getPrimitives = function() {
         'math_number': this.number,
         'text': this.text,
         'operator_add': this.add,
-        'operator_equals': this.equals
+        'operator_subtract': this.subtract,
+        'operator_multiply': this.multiply,
+        'operator_divide': this.divide,
+        'operator_lt': this.lt,
+        'operator_equals': this.equals,
+        'operator_gt': this.gt,
+        'operator_and': this.and,
+        'operator_or': this.or,
+        'operator_not': this.not,
+        'operator_random': this.random
     };
 };
 
@@ -31,8 +42,53 @@ Scratch3OperatorsBlocks.prototype.add = function (args) {
     return args.NUM1 + args.NUM2;
 };
 
+Scratch3OperatorsBlocks.prototype.subtract = function (args) {
+    return args.NUM1 - args.NUM2;
+};
+
+Scratch3OperatorsBlocks.prototype.multiply = function (args) {
+    return args.NUM1 * args.NUM2;
+};
+
+Scratch3OperatorsBlocks.prototype.divide = function (args) {
+    return args.NUM1 / args.NUM2;
+};
+
+Scratch3OperatorsBlocks.prototype.lt = function (args) {
+    return Boolean(args.OPERAND1 < args.OPERAND2);
+};
+
 Scratch3OperatorsBlocks.prototype.equals = function (args) {
-    return args.OPERAND1 == args.OPERAND2;
+    return Boolean(args.OPERAND1 == args.OPERAND2);
+};
+
+Scratch3OperatorsBlocks.prototype.gt = function (args) {
+    return Boolean(args.OPERAND1 > args.OPERAND2);
+};
+
+Scratch3OperatorsBlocks.prototype.and = function (args) {
+    return Boolean(args.OPERAND1 && args.OPERAND2);
+};
+
+Scratch3OperatorsBlocks.prototype.or = function (args) {
+    return Boolean(args.OPERAND1 || args.OPERAND2);
+};
+
+Scratch3OperatorsBlocks.prototype.not = function (args) {
+    return Boolean(!args.OPERAND);
+};
+
+Scratch3OperatorsBlocks.prototype.random = function (args) {
+    // As a demo, this implementation of random returns after 1 second of yield.
+    // @todo Match Scratch 2.0 implementation with int-truncation.
+    // See: http://bit.ly/1Qc0GzC
+    var examplePromise = new Promise(function(resolve) {
+        setTimeout(function() {
+            var res = (Math.random() * (args.TO - args.FROM)) + args.FROM;
+            resolve(res);
+        }, 1000);
+    });
+    return examplePromise;
 };
 
 module.exports = Scratch3OperatorsBlocks;
diff --git a/src/blocks/wedo2.js b/src/blocks/wedo2.js
deleted file mode 100644
index d7516bc18..000000000
--- a/src/blocks/wedo2.js
+++ /dev/null
@@ -1,152 +0,0 @@
-
-var YieldTimers = require('../util/yieldtimers.js');
-
-function WeDo2Blocks(runtime) {
-    /**
-     * The runtime instantiating this block package.
-     * @type {Runtime}
-     */
-    this.runtime = runtime;
-
-    /**
-     * Current motor speed, as a percentage (100 = full speed).
-     * @type {number}
-     * @private
-     */
-    this._motorSpeed = 100;
-
-    /**
-     * The timeout ID for a pending motor action.
-     * @type {?int}
-     * @private
-     */
-    this._motorTimeout = null;
-}
-
-/**
- * Retrieve the block primitives implemented by this package.
- * @return {Object.<string, Function>} Mapping of opcode to Function.
- */
-WeDo2Blocks.prototype.getPrimitives = function() {
-    return {
-        'wedo_motorclockwise': this.motorClockwise,
-        'wedo_motorcounterclockwise': this.motorCounterClockwise,
-        'wedo_motorspeed': this.motorSpeed,
-        'wedo_setcolor': this.setColor,
-        'wedo_whendistanceclose': this.whenDistanceClose,
-        'wedo_whentilt': this.whenTilt
-    };
-};
-
-/**
- * Clamp a value between a minimum and maximum value.
- * @todo move this to a common utility class.
- * @param {number} val The value to clamp.
- * @param {number} min The minimum return value.
- * @param {number} max The maximum return value.
- * @returns {number} The clamped value.
- * @private
- */
-WeDo2Blocks.prototype._clamp = function(val, min, max) {
-    return Math.max(min, Math.min(val, max));
-};
-
-/**
- * Common implementation for motor blocks.
- * @param {string} direction The direction to turn ('left' or 'right').
- * @param {number} durationSeconds The number of seconds to run.
- * @param {Object} util The util instance to use for yielding and finishing.
- * @private
- */
-WeDo2Blocks.prototype._motorOnFor = function(direction, durationSeconds, util) {
-    if (this._motorTimeout > 0) {
-        // @todo maybe this should go through util
-        YieldTimers.resolve(this._motorTimeout);
-        this._motorTimeout = null;
-    }
-    if (typeof window !== 'undefined' && window.native) {
-        window.native.motorRun(direction, this._motorSpeed);
-    }
-
-    var instance = this;
-    var myTimeout = this._motorTimeout = util.timeout(function() {
-        if (instance._motorTimeout == myTimeout) {
-            instance._motorTimeout = null;
-        }
-        if (typeof window !== 'undefined' && window.native) {
-            window.native.motorStop();
-        }
-        util.done();
-    }, 1000 * durationSeconds);
-
-    util.yield();
-};
-
-WeDo2Blocks.prototype.motorClockwise = function(argValues, util) {
-    this._motorOnFor('right', parseFloat(argValues[0]), util);
-};
-
-WeDo2Blocks.prototype.motorCounterClockwise = function(argValues, util) {
-    this._motorOnFor('left', parseFloat(argValues[0]), util);
-};
-
-WeDo2Blocks.prototype.motorSpeed = function(argValues) {
-    var speed = argValues[0];
-    switch (speed) {
-    case 'slow':
-        this._motorSpeed = 20;
-        break;
-    case 'medium':
-        this._motorSpeed = 50;
-        break;
-    case 'fast':
-        this._motorSpeed = 100;
-        break;
-    }
-};
-
-/**
- * Convert a color name to a WeDo color index.
- * Supports 'mystery' for a random hue.
- * @param {string} colorName The color to retrieve.
- * @returns {number} The WeDo color index.
- * @private
- */
-WeDo2Blocks.prototype._getColor = function(colorName) {
-    var colors = {
-        'yellow': 7,
-        'orange': 8,
-        'coral': 9,
-        'magenta': 1,
-        'purple': 2,
-        'blue': 3,
-        'green': 6,
-        'white': 10
-    };
-
-    if (colorName == 'mystery') {
-        return Math.floor((Math.random() * 10) + 1);
-    }
-
-    return colors[colorName];
-};
-
-WeDo2Blocks.prototype.setColor = function(argValues, util) {
-    if (typeof window !== 'undefined' && window.native) {
-        var colorIndex = this._getColor(argValues[0]);
-        window.native.setLedColor(colorIndex);
-    }
-    // Pause for quarter second
-    util.yield();
-    util.timeout(function() {
-        util.done();
-    }, 250);
-};
-
-WeDo2Blocks.prototype.whenDistanceClose = function() {
-};
-
-WeDo2Blocks.prototype.whenTilt = function() {
-};
-
-module.exports = WeDo2Blocks;
diff --git a/src/engine/execute.js b/src/engine/execute.js
index 0d1dbc3cc..188f0bf52 100644
--- a/src/engine/execute.js
+++ b/src/engine/execute.js
@@ -1,11 +1,10 @@
-var YieldTimers = require('../util/yieldtimers.js');
+var Thread = require('./thread');
 
 /**
- * If set, block calls, args, and return values will be logged to the console.
- * @const {boolean}
+ * Execute a block.
+ * @param {!Sequencer} sequencer Which sequencer is executing.
+ * @param {!Thread} thread Thread which to read and execute.
  */
-var DEBUG_BLOCK_CALLS = true;
-
 var execute = function (sequencer, thread) {
     var runtime = sequencer.runtime;
 
@@ -13,13 +12,19 @@ var execute = function (sequencer, thread) {
     var currentBlockId = thread.peekStack();
     var currentStackFrame = thread.peekStackFrame();
 
-    // Save the yield timer ID, in case a primitive makes a new one
-    // @todo hack - perhaps patch this to allow more than one timer per
-    // primitive, for example...
-    var oldYieldTimerId = YieldTimers.timerId;
-
     var opcode = runtime.blocks.getOpcode(currentBlockId);
 
+    if (!opcode) {
+        console.warn('Could not get opcode for block: ' + currentBlockId);
+        return;
+    }
+
+    var blockFunction = runtime.getOpcodeFunction(opcode);
+    if (!blockFunction) {
+        console.warn('Could not get implementation for opcode: ' + opcode);
+        return;
+    }
+
     // Generate values for arguments (inputs).
     var argValues = {};
 
@@ -34,53 +39,65 @@ var execute = function (sequencer, thread) {
     for (var inputName in inputs) {
         var input = inputs[inputName];
         var inputBlockId = input.block;
-        // Push to the stack to evaluate this input.
-        thread.pushStack(inputBlockId);
-        var result = execute(sequencer, thread);
-        thread.popStack();
-        argValues[input.name] = result;
+        // Is there no value for this input waiting in the stack frame?
+        if (typeof currentStackFrame.reported[inputName] === 'undefined') {
+            // If there's not, we need to evaluate the block.
+            var reporterYielded = (
+                sequencer.stepToReporter(thread, inputBlockId, inputName)
+            );
+            // If the reporter yielded, return immediately;
+            // it needs time to finish and report its value.
+            if (reporterYielded) {
+                return;
+            }
+        }
+        argValues[inputName] = currentStackFrame.reported[inputName];
     }
 
-    if (!opcode) {
-        console.warn('Could not get opcode for block: ' + currentBlockId);
-        return;
-    }
+    // If we've gotten this far, all of the input blocks are evaluated,
+    // and `argValues` is fully populated. So, execute the block primitive.
+    // First, clear `currentStackFrame.reported`, so any subsequent execution
+    // (e.g., on return from a substack) gets fresh inputs.
+    currentStackFrame.reported = {};
 
-    var blockFunction = runtime.getOpcodeFunction(opcode);
-    if (!blockFunction) {
-        console.warn('Could not get implementation for opcode: ' + opcode);
-        return;
-    }
-
-    if (DEBUG_BLOCK_CALLS) {
-        console.groupCollapsed('Executing: ' + opcode);
-        console.log('with arguments: ', argValues);
-        console.log('and stack frame: ', currentStackFrame);
-    }
-    var primitiveReturnValue = null;
-    // @todo deal with the return value
-    primitiveReturnValue = blockFunction(argValues, {
+    var primitiveReportedValue = null;
+    primitiveReportedValue = blockFunction(argValues, {
         yield: thread.yield.bind(thread),
         done: function() {
             sequencer.proceedThread(thread);
         },
-        timeout: YieldTimers.timeout,
-        stackFrame: currentStackFrame,
+        stackFrame: currentStackFrame.executionContext,
         startSubstack: function (substackNum) {
             sequencer.stepToSubstack(thread, substackNum);
         }
     });
-    // Update if the thread has set a yield timer ID
-    // @todo hack
-    if (YieldTimers.timerId > oldYieldTimerId) {
-        thread.yieldTimerId = YieldTimers.timerId;
+
+    // Deal with any reported value.
+    // If it's a promise, wait until promise resolves.
+    var isPromise = (
+        primitiveReportedValue &&
+        primitiveReportedValue.then &&
+        typeof primitiveReportedValue.then === 'function'
+    );
+    if (isPromise) {
+        if (thread.status === Thread.STATUS_RUNNING) {
+            // Primitive returned a promise; automatically yield thread.
+            thread.status = Thread.STATUS_YIELD;
+        }
+        // Promise handlers
+        primitiveReportedValue.then(function(resolvedValue) {
+            // Promise resolved: the primitive reported a value.
+            thread.pushReportedValue(resolvedValue);
+            sequencer.proceedThread(thread);
+        }, function(rejectionReason) {
+            // Promise rejected: the primitive had some error.
+            // Log it and proceed.
+            console.warn('Primitive rejected promise: ', rejectionReason);
+            sequencer.proceedThread(thread);
+        });
+    } else if (thread.status === Thread.STATUS_RUNNING) {
+        thread.pushReportedValue(primitiveReportedValue);
     }
-    if (DEBUG_BLOCK_CALLS) {
-        console.log('ending stack frame: ', currentStackFrame);
-        console.log('returned: ', primitiveReturnValue);
-        console.groupEnd();
-    }
-    return primitiveReturnValue;
 };
 
 module.exports = execute;
diff --git a/src/engine/runtime.js b/src/engine/runtime.js
index f6ad79f0b..8c4c862e1 100644
--- a/src/engine/runtime.js
+++ b/src/engine/runtime.js
@@ -6,8 +6,7 @@ var util = require('util');
 var defaultBlockPackages = {
     'scratch3_control': require('../blocks/scratch3_control'),
     'scratch3_event': require('../blocks/scratch3_event'),
-    'scratch3_operators': require('../blocks/scratch3_operators'),
-    'wedo2': require('../blocks/wedo2')
+    'scratch3_operators': require('../blocks/scratch3_operators')
 };
 
 /**
diff --git a/src/engine/sequencer.js b/src/engine/sequencer.js
index deaa15266..1498d6320 100644
--- a/src/engine/sequencer.js
+++ b/src/engine/sequencer.js
@@ -1,6 +1,5 @@
 var Timer = require('../util/timer');
 var Thread = require('./thread');
-var YieldTimers = require('../util/yieldtimers.js');
 var execute = require('./execute.js');
 
 function Sequencer (runtime) {
@@ -53,16 +52,8 @@ Sequencer.prototype.stepThreads = function (threads) {
                 // Normal-mode thread: step.
                 this.startThread(activeThread);
             } else if (activeThread.status === Thread.STATUS_YIELD) {
-                // Yield-mode thread: check if the time has passed.
-                if (!YieldTimers.resolve(activeThread.yieldTimerId)) {
-                    // Thread is still yielding
-                    // if YieldTimers.resolve returns false.
-                    numYieldingThreads++;
-                }
-            } else if (activeThread.status === Thread.STATUS_DONE) {
-                // Moved to a done state - finish up
-                activeThread.status = Thread.STATUS_RUNNING;
-                // @todo Deal with the return value
+                // Yielding thread: do nothing for this step.
+                continue;
             }
             if (activeThread.stack.length === 0 &&
                 activeThread.status === Thread.STATUS_DONE) {
@@ -101,7 +92,7 @@ Sequencer.prototype.startThread = function (thread) {
     // move to done.
     if (thread.status === Thread.STATUS_RUNNING &&
         thread.peekStack() === currentBlockId) {
-        this.proceedThread(thread, currentBlockId);
+        this.proceedThread(thread);
     }
 };
 
@@ -128,6 +119,27 @@ Sequencer.prototype.stepToSubstack = function (thread, substackNum) {
     }
 };
 
+/**
+ * Step a thread into an input reporter, and manage its status appropriately.
+ * @param {!Thread} thread Thread object to step to reporter.
+ * @param {!string} blockId ID of reporter block.
+ * @param {!string} inputName Name of input on parent block.
+ * @return {boolean} True if yielded, false if it finished immediately.
+ */
+Sequencer.prototype.stepToReporter = function (thread, blockId, inputName) {
+    var currentStackFrame = thread.peekStackFrame();
+    // Push to the stack to evaluate the reporter block.
+    thread.pushStack(blockId);
+    // Save name of input for `Thread.pushReportedValue`.
+    currentStackFrame.waitingReporter = inputName;
+    // Actually execute the block.
+    this.startThread(thread);
+    // If a reporter yielded, caller must wait for it to unyield.
+    // The value will be populated once the reporter unyields,
+    // and passed up to the currentStackFrame on next execution.
+    return thread.status === Thread.STATUS_YIELD;
+};
+
 /**
  * Finish stepping a thread and proceed it to the next block.
  * @param {!Thread} thread Thread object to proceed.
@@ -136,7 +148,8 @@ Sequencer.prototype.proceedThread = function (thread) {
     var currentBlockId = thread.peekStack();
     // Mark the status as done and proceed to the next block.
     this.runtime.glowBlock(currentBlockId, false);
-    thread.status = Thread.STATUS_DONE;
+    // If the block was yielding, move back to running state.
+    thread.status = Thread.STATUS_RUNNING;
     // Pop from the stack - finished this level of execution.
     thread.popStack();
     // Push next connected block, if there is one.
@@ -148,6 +161,10 @@ Sequencer.prototype.proceedThread = function (thread) {
     while (thread.peekStack() === null && thread.stack.length > 0) {
         thread.popStack();
     }
+    // If we still can't find a next block to run, mark the thread as done.
+    if (thread.peekStack() === null) {
+        thread.status = Thread.STATUS_DONE;
+    }
 };
 
 module.exports = Sequencer;
diff --git a/src/engine/thread.js b/src/engine/thread.js
index c98efab48..e5c4df2e4 100644
--- a/src/engine/thread.js
+++ b/src/engine/thread.js
@@ -28,32 +28,27 @@ function Thread (firstBlock) {
      * @type {number}
      */
     this.status = 0; /* Thread.STATUS_RUNNING */
-
-    /**
-     * Yield timer ID (for checking when the thread should unyield).
-     * @type {number}
-     */
-    this.yieldTimerId = -1;
 }
 
 /**
  * Thread status for initialized or running thread.
- * Threads are in this state when the primitive is called for the first time.
+ * This is the default state for a thread - execution should run normally,
+ * stepping from block to block.
  * @const
  */
 Thread.STATUS_RUNNING = 0;
 
 /**
  * Thread status for a yielded thread.
- * Threads are in this state when a primitive has yielded.
+ * Threads are in this state when a primitive has yielded; execution is paused
+ * until the relevant primitive unyields.
  * @const
  */
 Thread.STATUS_YIELD = 1;
 
 /**
  * Thread status for a finished/done thread.
- * Thread is moved to this state when the interpreter
- * can proceed with execution.
+ * Thread is in this state when there are no more blocks to execute.
  * @const
  */
 Thread.STATUS_DONE = 2;
@@ -67,7 +62,11 @@ Thread.prototype.pushStack = function (blockId) {
     // Push an empty stack frame, if we need one.
     // Might not, if we just popped the stack.
     if (this.stack.length > this.stackFrames.length) {
-        this.stackFrames.push({});
+        this.stackFrames.push({
+            reported: {}, // Collects reported input values.
+            waitingReporter: null, // Name of waiting reporter.
+            executionContext: {} // A context passed to block implementations.
+        });
     }
 };
 
@@ -97,6 +96,27 @@ Thread.prototype.peekStackFrame = function () {
     return this.stackFrames[this.stackFrames.length - 1];
 };
 
+/**
+ * Get stack frame above the current top.
+ * @return {?Object} Second to last stack frame stored on this thread.
+ */
+Thread.prototype.peekParentStackFrame = function () {
+    return this.stackFrames[this.stackFrames.length - 2];
+};
+
+/**
+ * Push a reported value to the parent of the current stack frame.
+ * @param {!Any} value Reported value to push.
+ */
+Thread.prototype.pushReportedValue = function (value) {
+    var parentStackFrame = this.peekParentStackFrame();
+    if (parentStackFrame) {
+        var waitingReporter = parentStackFrame.waitingReporter;
+        parentStackFrame.reported[waitingReporter] = value;
+        parentStackFrame.waitingReporter = null;
+    }
+};
+
 /**
  * Yields the thread.
  */
diff --git a/src/util/yieldtimers.js b/src/util/yieldtimers.js
deleted file mode 100644
index 45e244eaf..000000000
--- a/src/util/yieldtimers.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * @fileoverview Timers that are synchronized with the Scratch sequencer.
- */
-var Timer = require('./timer');
-
-function YieldTimers () {}
-
-/**
- * Shared collection of timers.
- * Each timer is a [Function, number] with the callback
- * and absolute time for it to run.
- * @type {Object.<number,Array>}
- */
-YieldTimers.timers = {};
-
-/**
- * Monotonically increasing timer ID.
- * @type {number}
- */
-YieldTimers.timerId = 0;
-
-/**
- * Utility for measuring time.
- * @type {!Timer}
- */
-YieldTimers.globalTimer = new Timer();
-
-/**
- * The timeout function is passed to primitives and is intended
- * as a convenient replacement for window.setTimeout.
- * The sequencer will attempt to resolve the timer every time
- * the yielded thread would have been stepped.
- * @param {!Function} callback To be called when the timer is done.
- * @param {number} timeDelta Time to wait, in ms.
- * @return {number} Timer ID to be used with other methods.
- */
-YieldTimers.timeout = function (callback, timeDelta) {
-    var id = ++YieldTimers.timerId;
-    YieldTimers.timers[id] = [
-        callback,
-        YieldTimers.globalTimer.time() + timeDelta
-    ];
-    return id;
-};
-
-/**
- * Attempt to resolve a timeout.
- * If the time has passed, call the callback.
- * Otherwise, do nothing.
- * @param {number} id Timer ID to resolve.
- * @return {boolean} True if the timer has resolved.
- */
-YieldTimers.resolve = function (id) {
-    var timer = YieldTimers.timers[id];
-    if (!timer) {
-        // No such timer.
-        return false;
-    }
-    var callback = timer[0];
-    var time = timer[1];
-    if (YieldTimers.globalTimer.time() < time) {
-        // Not done yet.
-        return false;
-    }
-    // Execute the callback and remove the timer.
-    callback();
-    delete YieldTimers.timers[id];
-    return true;
-};
-
-/**
- * Reject a timer so the callback never executes.
- * @param {number} id Timer ID to reject.
- */
-YieldTimers.reject = function (id) {
-    if (YieldTimers.timers[id]) {
-        delete YieldTimers.timers[id];
-    }
-};
-
-/**
- * Reject all timers currently stored.
- * Especially useful for a Scratch "stop."
- */
-YieldTimers.rejectAll = function () {
-    YieldTimers.timers = {};
-    YieldTimers.timerId = 0;
-};
-
-module.exports = YieldTimers;