 						compiledToken = compileVariable(token as String);
 				}
 
-				// handle access operator
-				if (tokens[open] == '.')
+				// handle access and descendants operators
+				if (tokens[open] == '.' || tokens[open] == '..')
 				{
 					var propertyToken:String = tokens[open + 1] as String;
 					if (!token || !propertyToken || operators.hasOwnProperty(propertyToken))

					
					// the token on the right is a variable name, but we will store it as a String because it's a property lookup
					compiledParams = [compiledToken, new CompiledConstant(encodeString(propertyToken), propertyToken)];
					tokens.splice(open - 1, 3, compileOperator('.', compiledParams));
					continue;
				}
				

			{
				// find first closing bracket or '.'
				for (close = 0; close < tokens.length; close++)
					if ('..])}'.indexOf(tokens[close]) >= 0)
						break;
				if (close == tokens.length || close == 0)
					break; // possible error, or no operator found
				// work backwards to the preceeding opening bracket or stop if '.'
				for (open = close; open >= 0; open--)
					if ('..[({'.indexOf(tokens[open]) >= 0)
						break;
				if (open < 0 || open + 1 == tokens.length)
					break; // possible error, or no operator found
				
				// unless it's an operator, compile the token to the left
				token = open > 0 ? tokens[open - 1] : null;
