function SeeThru (DOMNode, options) {

		var self = this;
		var ready = false;
		var callbacks = [];
		var defaultOptions = {
			start: 'external', // 'clicktoplay' or 'external' defaults to external
			end: 'stop', // 'loop', 'rewind', 'stop' any other input will default to 'stop'
			mask: false, // this lets you define a <img> (selected by #id or .class - class will use the first occurence)used as a black and white mask instead of adding the alpha to the video
			alphaMask: false, // defines if the used `mask` uses black and white or alpha information - defaults to false, i.e. black and white
			width: null, // lets you specify a pixel value used as width -- overrides all other calculations
			height: null, // lets you specify a pixel value used as height -- overrides all other calculations
			poster: false, // the plugin will display the image set in the video's poster-attribute when not playing if set to true
			unmult: false, // set this to true if your video material is premultiplied on black - might cause performance issues
			videoStyles: { display: 'none' }, // this is the CSS that is used to hide the original video - can be updated in order to work around autoplay restrictions
			namespace: 'seeThru' // this will be used for prefixing the CSS classnames applied to the created elements
		};

		options = options || {};
		self._video = getNode(DOMNode);

		if (!self._video || self._video.tagName !== 'VIDEO') throw new Error('Could not use specified source');

		self._options = (function (options) {
			for (var key in defaultOptions) {
				if (defaultOptions.hasOwnProperty(key)) {
					if (!(key in options)) {
						options[key] = defaultOptions[key];
					}
				}
			}
			return options;
		})(options);

		/**
		* @method init
		* sets up transparent video once the video has metadata
		* @returns self
		* @API private
		*/
		self._init = function () {
			function runInit () {
				function playSelfAndUnbind () {
					self._video.play();
					if (self._options.poster) {
						self._seeThru.getPoster().removeEventListener('click', playSelfAndUnbind);
					} else {
						self._seeThru.getCanvas().removeEventListener('click', playSelfAndUnbind);
					}
				}

				if (elementStore.has(self._video)) { throw new Error('seeThru already initialized on passed video element!'); }

				self._seeThru = new TransparentVideo(self._video, self._options);

				// attach behavior for start options
				if (self._options.start === 'clicktoplay') {
					if (self._options.poster) {
						self._seeThru.getPoster().addEventListener('click', playSelfAndUnbind);
					} else {
						self._seeThru.getCanvas().addEventListener('click', playSelfAndUnbind);
					}
				}

				// attach behavior for end options
				if (self._options.end === 'rewind') {
					self._video.addEventListener('ended', function () {
						self._video.currentTime = 0;
						self._seeThru.getCanvas().addEventListener('click', playSelfAndUnbind);
					});
				} else if (self._options.end !== 'stop') {
					self._video.addEventListener('ended', function () {
						self._video.currentTime = 0;
						self._video.play();
					});
				}

				// attach behavior for posterframe option
				if (self._options.poster && self._video.poster) {
					self._video.addEventListener('play', function () {
						self._seeThru.getPoster().style.display = 'none';
					});
					self._video.addEventListener('pause', function () {
						self._seeThru.getPoster().style.display = 'block';
					});
				}

				// some events that are registered on the canvas representation
				// will be echoed on the original video element so that pre-existing
				// event handlers bound to the video element will keep working
				// it is recommended to use `.getCanvas()` to bind new behavior though
				eventsToEcho.forEach(function (eventName) {
					self._seeThru.getCanvas().addEventListener(eventName, function () {
						var evt;
						if (canConstructEvents) {
							evt = new Event(eventName);
						} else {
							evt = document.createEvent('Event');
							evt.initEvent(eventName, true, true);
						}
						self._video.dispatchEvent(evt);
					});
				});

				self._seeThru.startRendering();

				ready = true;

				elementStore.push(self._video);

				callbacks.forEach(function (cb) {
					cb(self, self._video, self.getCanvas());
				});
			}

			if (self._video.readyState > 0) {
				runInit();
			} else {
				self._video.addEventListener('loadedmetadata', runInit);
			}

			return self;
		};

		/**
		* @method getCanvas
		* returns the canvas element that is used for on-screen displaylay
		* @returns {DOMElement}
		* @API public
		*/
		self.getCanvas = function () {
			return self._seeThru.getCanvas();
		};

		/**
		* @method play
		* starts playback of the associated video element
		* @returns self
		* @API public
		*/
		self.play = function () {
			self._video.play();
			return self;
		};

		/**
		* @method pause
		* halts playback of the associated video element
		* @returns self
		* @API public
		*/
		self.pause = function () {
			self._video.pause();
			return self;
		};

		/**
		* @method revert
		* reverts the transparent video back to its original state
		* @API public
		*/
		self.revert = function () {
			self._seeThru.teardown();
			elementStore.remove(self._video);
		};

		/**
		* @method updateMask
		* @param {String|DOMElement|DOMCollection} mask
		* swaps the static mask currently used for sourcing alpha
		* @returns self
		* @API public
		*/
		self.updateMask = function (mask) {
			self._seeThru.updateMask(getNode(mask));
			return self;
		};

		/**
		* @method ready
		* @param {Function} cb
		* defers the passed callback until the associated video element has metadata
		* passes itself as the 1st argument of the callback
		* @returns self
		* @API public
		*/
		self.ready = function (cb) {
			if (ready) {
				setTimeout(function () {
					cb(self, self._video, self.getCanvas());
				}, 0);
			} else {
				callbacks.push(cb);
			}
			return self;
		};

	}
@constructor SeeThru
handles a video element turned into a transparent mock version of itself
@param {String|DOMElement|DOMNode} DOMNode
@param {Object} [options]