function resolveMemberExpression( node, compute ) {
		var properties = linkedList();
		var property;
		var computed;
		var locals;
		var obj;

		// Ignore placeholder nodes:
		if ( node.start >= node.end ) {
			return;
		}

		// Resolve members of the `MemberExpression`:
		resolveMembers( node );

		// Check if the object identifier is valid...
		property = properties.first();
		if ( !property ) {
			return;
		}
		// Ignore if the object identifier is a reserved name:
		if ( isReservedName( property.value.name ) ) {
			return;
		}
		// If object identifier exists in the local scope, don't resolve from global scope...
		locals = resolveLocalScope( ast, property.value );
		if ( contains( locals, property.value.name ) ) {
			return;
		}
		// Enter object's namespace:
		obj = context;
		properties = properties.iterator();
		obj = obj[ properties.next().value.name ];
		if ( !obj ) {
			// Object not defined in context:
			return;
		}
		// Fetch properties from context:
		property = properties.next();
		while ( !property.done ) {
			// Ignore placeholder nodes:
			if ( property.value.start >= property.value.end ) {
				return;
			}
			// Case: 'bar' in `foo['bar']` - property already pushed as a string token. Ignore...
			if ( property.value.type === 'Literal' ) {
				try {
					if ( !hasProp( obj, property.value.value ) ) {
						// Property not found in context:
						break;
					}
					obj = obj[ property.value.value ];
				} catch ( error ) { // eslint-disable-line no-unused-vars
					break;
				}
				property = properties.next();
				continue;
			}
			// Case: `foo.bar` - resolve property and push it as a token...
			if ( property.value.type === 'Identifier' ) {
				try {
					if ( !hasProp( obj, property.value.name ) ) {
						// Property not found in context:
						break;
					}
					obj = obj[ property.value.name ];
				} catch ( error ) { // eslint-disable-line no-unused-vars
					break;
				}
				if ( !compute ) {
					// Push token if property exists in context:
					if ( isLiteralType( typeof obj ) ) {
						tokens.push({
							'value': property.value.name,
							'type': 'variable',
							'start': property.value.start,
							'end': property.value.end
						});
					} else {
						tokens.push({
							'value': property.value.name,
							'type': typeof obj,
							'start': property.value.start,
							'end': property.value.end
						});
					}
				}
				property = properties.next();
				continue;
			}
			// Case: `foo[a.b].bar` - recursively compute the internal `MemberExpression`...
			if ( property.value.type === 'MemberExpression' ) {
				computed = resolveMemberExpression( property.value, true );
				if ( !isLiteralType( typeof computed ) ) {
					// Couldn't compute the internal `MemberExpression` into a definite name:
					break;
				}
				try {
					if ( !hasProp( obj, computed ) ) {
						// Property not found in context:
						break;
					}
					obj = obj[ computed ];
				} catch ( error ) { // eslint-disable-line no-unused-vars
					break;
				}
				property = properties.next();
				continue;
			}
			break;
		}
		if ( compute ) {
			return obj;
		}

		/**
		* Resolves members of the `MemberExpression` node.
		*
		* @private
		* @param {Object} node - node to be traversed
		*/
		function resolveMembers( node ) {
			if ( node.object.type === 'Identifier' ) {
				// Reached a resolvable MemberExpression (a.b in a.b.c.d), save property(b) & object(a) and exit:
				properties.unshift( node.property );
				properties.unshift( node.object );
			} else if ( node.object.type === 'MemberExpression' ) {
				// Found node with another MemberExpression as object, save property and traverse it:
				properties.unshift( node.property );
				resolveMembers( node.object );
			}
		}
	}
Resolves a `MemberExpression` node.

@private
@param {Object} node - AST node
@param {boolean} compute - boolean indicating whether to compute the `MemberExpression`
@returns {(void|*)} computed value of the `MemberExpression` if compute is true