Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScript.xtext
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScript.xtext	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScript.xtext	(revision 440)
@@ -1,3 +1,3 @@
-grammar com.framsticks.framclipse.FramScript with org.eclipse.xtext.common.Terminals
+grammar com.framsticks.framclipse.FramScript with org.eclipse.xtext.common.Terminals hidden(SL_COMMENT, ML_COMMENT, WS)
 
 import "http://www.eclipse.org/emf/2002/Ecore" as ecore
@@ -54,24 +54,26 @@
 	'prop:'
 	headers += PropertyHeader*
-	'id:' name=ID 
+	'id:' name=ID
 	headers += PropertyHeader+
 	;
-	
+
 State :
-	'state:' 
+	'state:'
 	headers += PropertyHeader*
-	'id:' name=ID 
+	'id:' name=ID
 	headers += PropertyHeader+
 	;
-	
+
 Include : {Include}
-	code=Code?
-	(properties+=Property |
-	states+=State)*
+	(
+		code=Code?
+		(properties+=Property |
+		states+=State)*
+	) | {Block} statements+=Statement+
 ;
-	
+
 Header :
-	name=ID value=HEADER_VALUE ;
-	
+	name=HEADER_ID value=HEADER_VALUE ;
+
 NeuroHeader returns Header :
 {IntHeader}		name=('prefinputs:' | 'prefoutput:' | 'preflocation:' | 'vhints:') intValue=IntValue |
@@ -79,32 +81,33 @@
 {IconHeader}	name='icon:~' icon=Icon '~' |
 				Header ;
-				
-Icon : 
+
+Icon :
 	INT (',' INT)+ ;
-	
+
 PropertyHeader returns Header :
 	TypeHeader |
 	FlagsHeader |
 	Header ;
-	
+
 ShowHeader returns Header :
-	name='expdef:' value=ID |
+	name='expdef:' importURI=ID |
 	Header ;
-	
+
 FlagsHeader returns Header :
 {IntHeader}	name='flags:' intValue=INT ;
-	
+
 TypeHeader :
-	name='type:' type=PropertyType ;
-	
+	name=TYPE_HEADER type=PropertyType ;
+
+// This terminal is defined separately for use with FramScriptAuxiliaryLexer.
+terminal TYPE_HEADER : 'type:';
+
 PropertyType :
-	name=ID (min=Number (max=Number default=Number?)? enums+=ENUM_LITERAL* )? ;
-	
-terminal ENUM_LITERAL :
-	'~' !('~'|'\r'|'\n')+ ;
-
-Number :
-	'-'? (INT | DOUBLE) ;
-	
+	name=ID (min=Number max=Number default=(Number|HEADER_VALUE)? enums+=ENUM_LITERAL* )? ;
+
+Number : IntNumber | DoubleNumber ;
+IntNumber : '-'? INT ;
+DoubleNumber : '-'? DOUBLE ;
+
 CodeSection returns Code :
 	'code:~' Code '~' ;
@@ -123,12 +126,21 @@
 IncludeDeclaration :
 	'@include' importURI=STRING ;
-	
+
+/*
+ * For some reason, the '#include' keyword is not matched.
+ * It is possible it has been overshadowed by SL_COMMENT,
+ * despite the order in which the two have been defined.
+ * This has been worked around in FramScriptAuxiliaryLexer.
+ */
 PropertyIncludeDeclaration :
-	'#include' importURI=STRING ;
-	
+	PROP_INCLUDE importURI=STRING ;
+
+// keyword separated for use in FramScriptAuxiliaryLexer
+terminal PROP_INCLUDE : '#include' ;
+
 Block :
-{Block}	'{' statements+=Statement* '}' ;
-	
-Statement :	
+	'{' statements+=Statement+ '}' ;
+
+Statement :
 	( VariableDeclarationStatement |
 	ExpressionStatement |
@@ -145,4 +157,5 @@
 	WhileStatement |
 	ForStatement |
+	ForEachStatement |
 {EmptyStatement} ';' ;
 
@@ -154,9 +167,16 @@
 	
 IfStatement :
-	'if' '(' condition=Expression ')' if=Statement ('else' else=Statement)? ;
-	
-ForStatement : 
-	'for' '(' init=Assignment? ';' condition=Expression? ';' step=Assignment? ')' body=Statement ;
-	
+	'if' '(' condition=Expression ')' if=Statement (=>'else' else=Statement)? ;
+
+ForStatement :
+	'for' '(' (init=Assignment | init=VariableDeclarationStatement)? ';' condition=Expression? ';' step=Assignment? ')' body=Statement ;
+
+ForEachStatement :
+	'for' '(' (decl=Iterator|ref=[VariableDeclaration]) 'in' colection=Expression ')' body=Statement ;
+
+Iterator returns VariableDeclaration :
+	'var' name=ID
+;
+
 WhileStatement :
 	'while' '(' condition=Expression ')' body=Statement ;
@@ -182,6 +202,6 @@
 SwitchStatement :
 	'switch' condition=ParExpression '{' labels+=SwitchGroup* '}' ;
-	
-SwitchGroup : 
+
+SwitchGroup :
 	label=SwitchLabel body=SwitchBlock ;
 	
@@ -206,62 +226,85 @@
 
 Expression :
-	UnaryExpression ({Expression.left=current} op=Operator right=Expression)? | 
+	UnaryExpression ({Expression.left=current} op=Operator right=Expression)? |
 	WildcardExpression ;
-	
-UnaryExpression  :
+
+UnaryExpression :
 	QualifiedExpression2 ({UnaryExpression.arg=current} op = IncrementOperator)? |
 	op = (IncrementOperator | UnaryOperator) arg = QualifiedExpression2 |
+	FunctionLiteral |
 	Literal ;
-	
+
 QualifiedExpression2 returns QualifiedExpression :
 	QualifiedExpression |
 	(PropertyAccess|StateAccess) ({QualifiedExpression.parent=current}'.' child=QualifiedExpression )? ;
-	
+
 QualifiedExpression :
-	ArrayElementExpression ({QualifiedExpression.parent=current}'.' child=QualifiedExpression )? ;
-	
+	MemberAccess ({QualifiedExpression.parent=current}'.' child=QualifiedExpression )? ;
+
+MemberAccess returns QualifiedExpression:
+	ArrayElementExpression ( {MemberAccess.left=current} '.[' child=Expression ']')? ;
+
 ArrayElementExpression :
 	TerminalExpression ({ArrayElementExpression.array=current} ('[' indexes+=Expression ']')+ )? ;
- 
+
 TerminalExpression:
+				Cast |
+				TypeOf |
 				Invocation |
 				Array |
-				Vector | 
+				Vector |
+				Dictionary |
 {VariableRef} 	var=[VariableDeclaration];
- 				
+
+Cast :
+	type=('int'|'float'|'string') '(' expression=Expression ')' ;
+
+TypeOf :
+	'typeof' '(' expression=Expression ')' ;
+
 Invocation :
 	function=[Function] '(' (args+=Expression (',' args+=Expression)*)? ')' ;
-	
+
 WildcardExpression :
 	value=ID '.*' ;
-	
+
 PropertyAccess returns QualifiedExpression :
-	('Fields.'|'ExpParams.'|'ShowParams.'|'VisParams.') property=[Property] ;
-	
+{PropertyAccess}	('Fields'|'ExpParams'|'ShowParams'|'VisParams') ('.*' | =>('.' property=[Property]) | '.[' (=>property=[Property|STRING] | child=Expression ) ']')? ;
+
 StateAccess returns QualifiedExpression :
-	'ExpState.' state=[State] ;
-	
+{StateAccess}	'ExpState' (".*" | =>('.' state=[State]) | '.[' (=>state=[State|STRING] | child=Expression ) ']')? ;
+
+FunctionLiteral:
+	'function' function=[Function] ;
+
 Literal:
-{IntLiteral}	value=IntValue | 
-{DoubleLiteral}	value=DoubleValue | 
-{StringLiteral}	value=STRING | 
-{HexLiteral}	value=HEX | 
+{IntLiteral}	value=IntValue |
+{DoubleLiteral}	value=DoubleValue |
+{StringLiteral}	value=STRING |
+{RawStringLiteral}	value=ML_STRING |
+{HexLiteral}	value=HEX |
 {NullLiteral}	'null' ;
 
 Array :
-	'[' elements+=Expression (',' elements+=Expression)* ']' ;
+{Array}	'[' (elements+=Expression (',' elements+=Expression)*)? ']' ;
 
 Vector  :
 	'(' elements+=Expression (',' elements+=Expression)* ')' ;
 
-Operator : 
-	'+' | '-' | '*'| '/' | 
+Dictionary :
+{Dictionary}	'{' ( keys+=DictKey values+=Expression (',' keys+=DictKey values+=Expression)* )? '}' ;
+
+DictKey :
+	STRING ':' ;
+
+Operator :
+	'+' | '-' | '*'| '/' |
 	'&'| '|' | '%' |
 	'==' | '!=' | '>=' | '<=' | '<' | '>' |
 	'&&' | '||' ;
-	
+
 UnaryOperator :
-	'!' | '+' | '-' | 'typeof';
-	
+	'!' | '+' | '-';
+
 IncrementOperator :
 	'++' | '--' ;
@@ -272,17 +315,51 @@
 DoubleValue hidden() :
 	('+'|'-')? DOUBLE ;
-	
-terminal DOUBLE : 
+
+terminal DOUBLE :
 	('0'..'9')*'.'('0'..'9')+ ('e' INT)? |
 	INT 'e' INT ;
-	
-terminal HEX : 
+
+terminal ENUM_LITERAL :
+	'~' !('~'|'\r'|'\n')+ ;
+
+terminal HEX :
 	'0x' (('0'..'9')|('a'..'f')|('A'..'F'))+ ;
-	
-terminal HEADER_VALUE : 
-	':' !('~'|' '|'\t'|'\r'|'\n') !('\n'|'\r')* ('\r'? '\n') |
-	':~' -> '~'('\r'? '\n') 
-	;
-	
-terminal SL_COMMENT : ('//' | '# ')  !('\n'|'\r')* ('\r'? '\n')?;
-
+
+terminal ML_STRING :
+	'"""' -> '"""' |
+	"'''" -> "'''"
+;
+
+terminal SL_COMMENT : ('//' | '#') -> NL ;
+
+terminal HEADER_ID :
+	(
+		'name' |
+		'longname' |
+		'description' |
+		'group' |
+		'help' |
+		'info' |
+		'neurons'
+	) ':'
+;
+
+/*
+ * This rule should not match anything,
+ * so expect an error when generating the artifacts.
+ * If it is not there, something went wrong.
+ * This rule is here just to make Xtext generate a constant
+ * to be used in a custom lexer (FramScriptAuriliaryLexer),
+ * which takes context into account,
+ * so it is able to recognise HEADER_VALUE
+ * without conflicting with Framscript code syntax.
+ * It should match the following rules,
+ * but only when preceded with HEADER_ID:
+ *	'~' NL ('\\~'|!'~')* '~' NL | -> NL,
+ * where NL is defined as: '\r' '\n'? | '\n',
+ * The final NL is not matched, but it is a part of context.
+ * This token is also emitted for the default value in PropertyType.
+ */
+terminal HEADER_VALUE : 'name:';
+
+terminal fragment NL : '\r' '\n'? | '\n' ;
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptAuxiliaryLexer.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptAuxiliaryLexer.java	(revision 440)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptAuxiliaryLexer.java	(revision 440)
@@ -0,0 +1,240 @@
+package com.framsticks.framclipse;
+
+import org.antlr.runtime.CharStream;
+import org.antlr.runtime.RecognitionException;
+import org.antlr.runtime.Token;
+
+import com.framsticks.framclipse.parser.antlr.internal.InternalFramScriptLexer;
+
+public class FramScriptAuxiliaryLexer extends InternalFramScriptLexer {
+
+	private static final int FLG_MULTILINE = 0x1;
+	private static final int FLG_TYPE_IS_NUMERIC = 0x2;	// if raised, the default value should be analysed with internal lexer
+	private static final int FLG_TYPE_IS_STRING = 0x4;	// if raised, the max value can be omitted and should be 0
+	private static final int CTX_NONE = 0;
+	private static final int CTX_TYPE = 1;
+	private static final int CTX_TYPE_ID = 2;
+	private static final int CTX_TYPE_MIN = 3;
+	private static final int CTX_TYPE_MAX = 4;
+	private static final int CTX_TYPE_DEFAULT = 5;
+
+	private int context = CTX_NONE;
+	private int flags = 0;
+	private Token previous = Token.INVALID_TOKEN;
+
+	private void checkML() {
+		setFlag(FLG_MULTILINE, next() == '~');
+	}
+
+	private boolean isSet(int flag) {
+		return (flags & flag) != 0;
+	}
+
+	private void setFlag(int flag, boolean state) {
+		if (state)
+			flags |= flag;
+		else
+			flags &= ~flag;
+	}
+
+	private void setState(int tokenType) {
+		state.token = null;
+		state.channel = Token.DEFAULT_CHANNEL;
+		state.tokenStartCharIndex = input.index();
+		state.tokenStartCharPositionInLine = input.getCharPositionInLine();
+		state.tokenStartLine = input.getLine();
+		state.text = null;
+		state.type = tokenType;
+	}
+
+	char next() {
+		return next(1);
+	}
+
+	char next(int i) {
+		return (char)input.LA(i);
+	}
+
+	void consumeUntilAny(String term) {
+		term += (char)CharStream.EOF;
+		while (term.indexOf(next()) == -1)
+			matchAny();
+	}
+
+	@Override
+	public Token nextToken() {
+		switch (previous.getType()) {
+		case RULE_HEADER_ID:
+			setState(RULE_HEADER_VALUE);
+			checkML();
+			mHEADER_VALUE();
+			return previous = emit();
+		case RULE_TYPE_HEADER:
+			checkML();
+			context = CTX_TYPE;
+			if (isSet(FLG_MULTILINE)) {
+				setState(RULE_WS);	// any ignored token
+				matchAny();	// consume '~'
+				return previous = emit();
+			}
+			break;
+		case RULE_WS:
+			if (context == CTX_TYPE_MIN) {
+				if (isSet(FLG_TYPE_IS_STRING)) {
+					if (!Character.isDigit(next()) && next() != '-') {	// if string length is omitted
+						if (isSet(FLG_MULTILINE))
+							matchAny();	// ignore expected '~'
+						setState(RULE_INT);
+						state.text = "0";	// pretend the max value is 0
+						return previous = emit();
+					}
+				}
+			}
+			if (previous.getText().indexOf('\n') != -1 ||
+					previous.getText().indexOf('\r') != -1) {
+				if (!isSet(FLG_MULTILINE)) {
+					context = CTX_NONE;
+				}
+				// workaround for '#include'
+				if (willMatch("#include")) {
+					setState(RULE_PROP_INCLUDE);
+					try {
+						mRULE_PROP_INCLUDE();
+					} catch (RecognitionException e) {
+						reportError(e);
+					}
+					return previous = emit();
+				}
+				if (!isSet(FLG_MULTILINE)) {
+					break;
+				}
+			}
+			if (context == CTX_TYPE_MAX) {
+				if (isSet(FLG_MULTILINE)) {
+					context = CTX_TYPE_DEFAULT;
+				} else {
+					context = CTX_NONE;
+				}
+				if (isSet(FLG_TYPE_IS_NUMERIC)) {
+					if (isSet(FLG_MULTILINE) && !Character.isDigit(next())
+							&& next() != '-') {	// if default value is omitted
+						previous = aux_ENUM_LITERAL();
+						if (previous != null)
+							return previous;
+					}
+					break;
+				} else {
+					setState(RULE_HEADER_VALUE);
+					mRULE_TYPE_HEADER_VALUE();
+					return previous = emit();
+				}
+			} else if (context == CTX_TYPE_DEFAULT) {
+				previous = aux_ENUM_LITERAL();
+				if (previous != null)
+					return previous;
+			}
+			break;
+		case RULE_ID:
+			if (context == CTX_TYPE) {
+				if ("df".indexOf(previous.getText().charAt(0)) == -1) {
+					setFlag(FLG_TYPE_IS_NUMERIC, false);
+					setFlag(FLG_TYPE_IS_STRING, previous.getText().charAt(0) == (int)'s');
+				} else {
+					setFlag(FLG_TYPE_IS_NUMERIC, true);
+				}
+				context = CTX_TYPE_ID;
+				break;
+			}
+			context = CTX_NONE;
+			break;
+		case RULE_HEADER_VALUE:
+		case RULE_ENUM_LITERAL:
+			if (context == CTX_TYPE_DEFAULT) {
+				previous = aux_ENUM_LITERAL();
+				if (previous != null)
+					return previous;
+			}
+			context = CTX_NONE;
+			break;
+		case RULE_DOUBLE:
+		case RULE_INT:
+			if (context == CTX_TYPE_DEFAULT) {
+				break;	// avoid changing context
+			} else if (context == CTX_TYPE_ID) {
+				context = CTX_TYPE_MIN;
+				break;
+			} else if (context == CTX_TYPE_MIN) {
+				context = CTX_TYPE_MAX;
+				break;
+			}
+			context = CTX_NONE;
+			break;
+		default:
+			if ("-".equals(previous.getText()) ||
+					"+".equals(previous.getText())) {
+				break;
+			}
+			context = CTX_NONE;
+		case RULE_SL_COMMENT:
+			break;
+		}
+		return previous = super.nextToken();
+	}
+
+	private boolean willMatch(String string) {
+		for (int i = 0; i < string.length(); ++i) {
+			if (next(i+1) != string.charAt(i))
+				return false;
+		}
+		return true;
+	}
+
+	private Token aux_ENUM_LITERAL() {
+		// CTX_TYPE_DEFAULT assumes raised FLG_MULTILINE
+		if (next() == '~') {
+			setState(RULE_WS);	// any ignored token
+			matchAny();
+			context = CTX_NONE;
+			return emit();
+		} else if (next() == '\\' && next(2) == '~') {
+			matchAny();	// not assigned to any terminal
+			setState(RULE_ENUM_LITERAL);
+			matchAny();	// consume '~'
+			mRULE_TYPE_HEADER_VALUE();
+			return emit();
+		}
+		return null;
+	}
+	
+	private void mRULE_TYPE_HEADER_VALUE() {
+		if (isSet(FLG_MULTILINE)) {
+			do {
+				consumeUntilAny("\\~");
+				if (next() == '\\' && next(2) != '~') {
+					matchAny();
+					continue;
+				}
+			} while (false);
+		} else {
+			consumeUntilAny("~\r\n");
+		}
+	}
+
+	private void mHEADER_VALUE() {
+		if (isSet(FLG_MULTILINE)) {
+			matchAny();	// consume '~'
+			do {
+				consumeUntilAny("\\~");
+				if (next() == '\\') {
+					matchAny();
+					if (next() == '~')
+						matchAny();
+					continue;
+				}
+			} while (false);
+			matchAny();
+		} else {
+			consumeUntilAny("\r\n");
+		}
+	}
+}
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptRuntimeModule.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptRuntimeModule.java	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptRuntimeModule.java	(revision 440)
@@ -16,8 +16,9 @@
 import com.framsticks.framclipse.script.context.Framscontext;
 import com.framsticks.framclipse.script.model.Framscript;
+import com.google.inject.Binder;
 import com.thoughtworks.xstream.XStream;
 
 /**
- * Use this class to register components to be used within the IDE.
+ * Use this class to register components to be used at runtime / without the Equinox extension registry.
  */
 public class FramScriptRuntimeModule extends com.framsticks.framclipse.AbstractFramScriptRuntimeModule {
@@ -56,3 +57,10 @@
 	}
 
+	@Override
+	public void configureRuntimeLexer(Binder binder) {
+		binder.bind(org.eclipse.xtext.parser.antlr.Lexer.class)
+                        .annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.parser.antlr.LexerBindings.RUNTIME))
+                        .to(FramScriptAuxiliaryLexer.class);
+	}
+
 }
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptValueConverterService.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptValueConverterService.java	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptValueConverterService.java	(revision 440)
@@ -18,13 +18,26 @@
 			protected String internalToValue(String s, INode node)
 					throws ValueConverterException {
-				if (s.startsWith(":~")) {
-					return s.substring(2, s.lastIndexOf('~')).trim();
-				} else {
-					return s.substring(1).trim();
+				String r = s;
+				if (s.startsWith("~")) {
+					r = s.substring(1, s.lastIndexOf('~'));
 				}
+				return r.trim().replaceAll("\\~", "~");
 			}
 
 		};
 	}
-	
+
+	@ValueConverter(rule = "ML_STRING")
+	public IValueConverter<String> ML_STRING() {
+
+		return new AbstractToStringConverter<String>() {
+
+			@Override
+			protected String internalToValue(String s, INode node)
+					throws ValueConverterException {
+				return s.substring(3, s.length()-3);
+			}
+
+		};
+	}
 }
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/GenerateFramScript.mwe2
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/GenerateFramScript.mwe2	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/GenerateFramScript.mwe2	(revision 440)
@@ -80,6 +80,6 @@
 			// Java-based API for validation
 			fragment = validation.JavaValidatorFragment auto-inject {
-			//	composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
-			//	composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
+				composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
+				composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
 			}
 
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/formatting/FramScriptFormatter.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/formatting/FramScriptFormatter.java	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/formatting/FramScriptFormatter.java	(revision 440)
@@ -17,22 +17,15 @@
 
 /**
- * This class contains custom formatting description.
+ * This class contains custom formatting declarations.
  * 
- * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#formatting
- * on how and when to use it
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#formatting
+ * on how and when to use it.
  * 
- * Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an
- * example
+ * Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an example
  */
 public class FramScriptFormatter extends AbstractDeclarativeFormatter {
-	
-	@Override
-	protected FramScriptGrammarAccess getGrammarAccess() {
-		return (FramScriptGrammarAccess) super.getGrammarAccess();
-	}
-
 	@Override
 	protected void configureFormatting(FormattingConfig c) {
-		FramScriptGrammarAccess f = getGrammarAccess();
+		FramScriptGrammarAccess f = (FramScriptGrammarAccess) getGrammarAccess();
 		
 		//Headers
@@ -68,5 +61,5 @@
 		c.setNoSpace().before(f.getFlagsHeaderAccess().getIntValueAssignment_2());
 		
-		c.setNoSpace().after(f.getTypeHeaderAccess().getNameTypeKeyword_0_0());
+		c.setNoSpace().after(f.getTypeHeaderAccess().getNameTYPE_HEADERTerminalRuleCall_0_0());
 		c.setLinewrap().after(f.getTypeHeaderAccess().getTypeAssignment_1());
 		
@@ -94,9 +87,9 @@
 		// BlockIndentation
 		BlockElements block = f.getBlockAccess();
-		c.setIndentation(block.getLeftCurlyBracketKeyword_1(), 
-				block.getRightCurlyBracketKeyword_3());
-		c.setLinewrap().before(block.getLeftCurlyBracketKeyword_1());
-		c.setLinewrap().after(block.getLeftCurlyBracketKeyword_1());
-		c.setLinewrap().after(block.getRightCurlyBracketKeyword_3());
+		c.setIndentation(block.getLeftCurlyBracketKeyword_0(),
+				block.getRightCurlyBracketKeyword_2());
+		c.setLinewrap().before(block.getLeftCurlyBracketKeyword_0());
+		c.setLinewrap().after(block.getLeftCurlyBracketKeyword_0());
+		c.setLinewrap().after(block.getRightCurlyBracketKeyword_2());
 
 		// Param
@@ -104,5 +97,6 @@
 		c.setNoLinewrap().around(fullStop);
 		c.setNoSpace().around(fullStop);
-		c.setNoSpace().after(f.getPropertyAccessAccess().getAlternatives_0());
+		c.setNoSpace().after(f.getPropertyAccessAccess().getAlternatives_1());
+		c.setNoSpace().after(f.getPropertyAccessAccess().getAlternatives_2());
 		
 		// Invocation
@@ -117,7 +111,7 @@
 		
 		//Arrays
-		c.setNoSpace().after(f.getArrayAccess().getLeftSquareBracketKeyword_0());
+		c.setNoSpace().after(f.getArrayAccess().getLeftSquareBracketKeyword_1());
 		c.setNoSpace().before(f.getArrayAccess().getRightSquareBracketKeyword_3());
-		c.setNoSpace().before(f.getArrayAccess().getCommaKeyword_2_0());
+		c.setNoSpace().before(f.getArrayAccess().getCommaKeyword_2_1_0());
 		
 		// Unary expression
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/resource/FramScriptResourceDescription.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/resource/FramScriptResourceDescription.java	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/resource/FramScriptResourceDescription.java	(revision 440)
@@ -13,4 +13,5 @@
 import com.framsticks.framclipse.framScript.State;
 import com.framsticks.framclipse.framScript.VariableDeclaration;
+import com.framsticks.framclipse.framScript.VariableDeclarations;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
@@ -19,7 +20,10 @@
 public class FramScriptResourceDescription extends DefaultResourceDescription {
 
+	private Resource resource;
+
 	public FramScriptResourceDescription(Resource resource,
 			IDefaultResourceDescriptionStrategy resourceDescriptionStrategy) {
 		super(resource, resourceDescriptionStrategy);
+		this.resource = resource;
 	}
 
@@ -49,5 +53,9 @@
 		if (input instanceof VariableDeclaration) {
 			VariableDeclaration dec = (VariableDeclaration) input;
-			return dec.eContainer().eContainer() instanceof Code;
+			EObject decs = dec.eContainer();
+			return decs instanceof VariableDeclarations &&
+					(decs.eContainer() instanceof Code ||
+							"inc".equals(resource.getURI().fileExtension()) &&
+							decs.eContainer().eContainer() == null);
 		}
 		return false;
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptImportUriResolver.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptImportUriResolver.java	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptImportUriResolver.java	(revision 440)
@@ -8,12 +8,12 @@
 public class FramScriptImportUriResolver extends ImportUriResolver {
 	@Override
-	public String apply(EObject from) {
+	public String resolve(EObject from) {
 		if (from instanceof Header) {
 			Header header = (Header) from;
 			if (header.getName().equals("expdef:")) {
-				return header.getValue() + ".expdef";
+				return header.getImportURI() + ".expdef";
 			}
 		}
-		return super.apply(from);
+		return super.resolve(from);
 	}
 }
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptScopeProvider.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptScopeProvider.java	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptScopeProvider.java	(revision 440)
@@ -20,7 +20,10 @@
 import org.eclipse.emf.ecore.EStructuralFeature;
 import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
 import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
 import org.eclipse.xtext.resource.EObjectDescription;
 import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.resource.IResourceDescription;
+import org.eclipse.xtext.scoping.IGlobalScopeProvider;
 import org.eclipse.xtext.scoping.IScope;
 import org.eclipse.xtext.scoping.Scopes;
@@ -30,17 +33,25 @@
 import com.framsticks.framclipse.framScript.Block;
 import com.framsticks.framclipse.framScript.Code;
+import com.framsticks.framclipse.framScript.Expdef;
+import com.framsticks.framclipse.framScript.ForEachStatement;
+import com.framsticks.framclipse.framScript.ForStatement;
 import com.framsticks.framclipse.framScript.FramScriptFactory;
 import com.framsticks.framclipse.framScript.Function;
 import com.framsticks.framclipse.framScript.GotoStatment;
+import com.framsticks.framclipse.framScript.Header;
+import com.framsticks.framclipse.framScript.IncludeDeclaration;
 import com.framsticks.framclipse.framScript.Invocation;
 import com.framsticks.framclipse.framScript.LabeledStatement;
 import com.framsticks.framclipse.framScript.Model;
+import com.framsticks.framclipse.framScript.PropertyIncludeDeclaration;
 import com.framsticks.framclipse.framScript.ProposableFunctionImpl;
 import com.framsticks.framclipse.framScript.ProposableVariableDeclarationImpl;
 import com.framsticks.framclipse.framScript.QualifiedExpression;
+import com.framsticks.framclipse.framScript.Show;
 import com.framsticks.framclipse.framScript.Statement;
 import com.framsticks.framclipse.framScript.VariableDeclaration;
 import com.framsticks.framclipse.framScript.VariableDeclarations;
 import com.framsticks.framclipse.framScript.VariableRef;
+import com.framsticks.framclipse.resource.FramScriptResourceDescriptionManager;
 import com.framsticks.framclipse.script.ConstantProvider;
 import com.framsticks.framclipse.script.ExpressionTraverser;
@@ -54,20 +65,27 @@
  * This class contains custom scoping description.
  * 
- * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping
- * on how and when to use it 
- *
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
+ * on how and when to use it.
  */
 public class FramScriptScopeProvider extends AbstractDeclarativeScopeProvider {
-	
+
 	private final ConstantProvider provider;
-	
+
 	private final ExpressionTraverser traverser;
-	
+
+	@Inject
+	private IGlobalScopeProvider globalScopeProvider;
+
+	@Inject
+	private FramScriptResourceDescriptionManager descriptionManager;
+
 	private Resource resource;
-	
+
 	private Map<String, IScope> typesScopes = Maps.newHashMap();
 	private Map<Type, IScope> functionScopes = Maps.newHashMap();
 	private Map<Type, IScope> fieldScopes = Maps.newHashMap();
-	
+
+	private FramScriptImportUriResolver resolver = new FramScriptImportUriResolver();
+
 	@Inject
 	public FramScriptScopeProvider(ConstantProvider provider, ExpressionTraverser traverser) {
@@ -77,5 +95,72 @@
 		initTypes();
 	}
-	
+
+	@Override
+	public IScope getScope(EObject context, EReference reference) {
+		if (reference.getEContainingClass().getName().equals("VariableRef") &&
+				reference.getName().equals("var")) {
+			if (context instanceof VariableRef) {
+				QualifiedExpression parent = getParent((VariableRef) context);
+				if (parent != null) {
+					return getScope(parent, reference);
+				}
+				EObject object = context;
+				while (object != null && !(object.eContainer() instanceof Block ||
+						object.eContainer() instanceof ForStatement ||
+						object.eContainer() instanceof ForEachStatement)) {
+					object = object.eContainer();
+				}
+				Statement statement = (Statement) object;
+				EObject blockOrFor = object.eContainer();
+
+				if (blockOrFor instanceof Block) {
+					Block block = (Block) blockOrFor;
+					return Scopes.scopeFor(precedingDeclarations(block, statement),
+							nextValidScope(block, reference));
+				} else
+					return getScope(blockOrFor, reference);
+			} else if (context.eContainer() instanceof Block) {
+				Block block = (Block) context.eContainer();
+				List<VariableDeclaration> vars = precedingDeclarations(block, (Statement)context);
+				IScope outerScope = Scopes.scopeFor(vars, nextValidScope(block, reference));
+				if (context instanceof Block) {
+					return outerScope;
+				}
+				return new SimpleScope(outerScope,
+						super.getScope(context, reference).getAllElements());
+			}
+		}
+		return super.getScope(context, reference);
+	}
+
+	private IScope nextValidScope(EObject context, EReference ref) {
+		if (ref.getEContainingClass().getName().equals("VariableRef") &&
+				ref.getName().equals("var")) {
+			if (context instanceof Block) {
+				EObject parent = context.eContainer();
+				if (parent == null) {	// may happen in .inc files.
+					return scope_VariableRef_var((Model)context, ref);
+				}
+				if (!(parent instanceof Block)) {
+					return getScope(parent, ref);
+				}
+			}
+		}
+		return getScope(context, ref);
+	}
+
+	private List<VariableDeclaration> precedingDeclarations(Block block, Statement statement){
+		List<VariableDeclaration> vars = Lists.newArrayList();
+		for (Statement stmt : block.getStatements()) {
+			// Everything after the statement is out of scope.
+			if (stmt == statement) {
+				break;
+			} else if (stmt instanceof VariableDeclarations) {
+				vars.addAll(((VariableDeclarations) stmt).getVars());
+			}
+		}
+		return vars;
+	}
+
 	protected void initTypes() {
 		List<Function> allFunctions = Lists.newArrayList();
@@ -116,6 +201,8 @@
 			scope = scope_Invocation_function(getFunction(inv), ref);
 		}
-		scope = filterByArgumentsCount(scope, inv.getArgs().size());
-		return scope;
+		Show show = getShow(inv);
+		IScope showScope = show == null ? IScope.NULLSCOPE :
+			new SimpleScope(filterByArgumentsCount(getScope(show, ref), inv.getArgs().size()));
+		return new SimpleScope(showScope, filterByArgumentsCount(scope, inv.getArgs().size()));
 	}
 
@@ -132,5 +219,12 @@
 	}
 
-	private IScope filterByArgumentsCount(IScope scope, int size) {
+	protected IScope scope_Invocation_function(Show show, EReference ref) {
+		return addAliases(new SimpleScope(showExpdefIncludes(show, ref)));
+	}
+
+	/*
+	 * Make sure scope contains only function descriptions.
+	 */
+	private List<IEObjectDescription> filterByArgumentsCount(IScope scope, int size) {
 		List<IEObjectDescription> filtered = Lists.newArrayList();
 		for (IEObjectDescription desc : scope.getAllElements()) {
@@ -140,7 +234,7 @@
 			}
 		}
-		return new SimpleScope(filtered);
-	}
-	
+		return filtered;
+	}
+
 	private IScope addAliases(IScope scope) {
 		Iterable<IEObjectDescription> contents = scope.getAllElements();
@@ -155,29 +249,50 @@
 	}
 
-	protected IScope scope_VariableRef_var(VariableRef var, EReference ref) {
-		QualifiedExpression parent = getParent(var);
-		if (parent != null) {
-			return scope_VariableRef_var(parent, ref);
-		} else {
-			return scope_VariableRef_var(getBlock(var), ref);
-		}
-	}
-
 	protected IScope scope_VariableRef_var(QualifiedExpression var, EReference ref) {
 		Type type = traverser.getLastType(var);
 		IScope scope = fieldScopes.get(type);
-		return scope != null ? scope : IScope.NULLSCOPE;
-	}
-	
+		return new SimpleScope(nextValidScope(var.eContainer(), ref),
+				scope != null ? scope.getAllElements() : new ArrayList<IEObjectDescription>());
+	}
+
 	protected IScope scope_VariableRef_var(Block block, EReference ref) {
+		// Scope for Blocks is constructed earlier in getScope, so we stop here.
+		return IScope.NULLSCOPE;
+	}
+
+	protected IScope scope_VariableRef_var(ForStatement fs, EReference ref) {
 		List<VariableDeclaration> vars = Lists.newArrayList();
-		for (Statement stmt : block.getStatements()) {
-			if (stmt instanceof VariableDeclarations) {
-				vars.addAll(((VariableDeclarations) stmt).getVars());
-			}
-		}
-		return Scopes.scopeFor(vars, getScope(block.eContainer(), ref));
-	}
-	
+		Statement init = fs.getInit();
+		if (init instanceof VariableDeclarations) {
+			vars.addAll(((VariableDeclarations)init).getVars());
+		}
+		return Scopes.scopeFor(vars, getScope(fs.eContainer(), ref));
+	}
+
+	protected IScope scope_VariableRef_var(ForEachStatement fes, EReference ref) {
+		List<VariableDeclaration> vars = Lists.newArrayList();
+		if (fes.getDecl() == null)
+			return getScope(fes.eContainer(), ref);
+		else {
+			vars.add(fes.getDecl());
+			return Scopes.scopeFor(vars, getScope(fes.eContainer(), ref));
+		}
+	}
+
+	/*
+	 * Blocks are handled specially in getScope,
+	 * and scope_VariableRef_var(Block, EReference) returns IScope.NULLSCOPE,
+	 * which breaks the chain of scopes,
+	 * so we have to ensure each unspecified scope_VariableRef_var call
+	 * is redirected to getScope in this class, instead of super.getScope.
+	 */
+	protected IScope scope_VariableRef_var(EObject ctx, EReference ref) {
+		EObject parent = ctx.eContainer();
+		if (parent == null)
+			return IScope.NULLSCOPE;
+		else
+			return getScope(parent, ref);
+	}
+
 	protected IScope scope_VariableRef_var(Function f, EReference ref) {
 		List<VariableDeclaration> vars = Lists.newArrayList();
@@ -185,5 +300,5 @@
 		return Scopes.scopeFor(vars, getScope(f.eContainer(), ref));
 	}
-	
+
 	protected IScope scope_VariableRef_var(Code code, EReference ref) {
 		List<VariableDeclaration> vars = Lists.newArrayList();
@@ -193,9 +308,69 @@
 		return Scopes.scopeFor(vars, getScope(code.eContainer(), ref));
 	}
-	
+
+	private List<IEObjectDescription> showExpdefIncludes(Show show, EReference ref) {
+		ArrayList<IEObjectDescription> result = Lists.newArrayList();
+		// Get expdef header
+		Header expdefHeader= null;
+		for (Header h : show.getHeaders()) {
+			if ("expdef:".equals(h.getName())) {
+					expdefHeader = h;
+					break;
+			}
+		}
+		if (expdefHeader == null)
+			return result;
+		// Find resource by name
+		ResourceSet resourceSet = show.eResource().getResourceSet();
+		String expdefFile = resolver.resolve(expdefHeader);
+		Resource expdefResource = findResourceByName(resourceSet, expdefFile);
+		if (expdefResource == null)
+			return result;
+		// Mine include directives
+		ArrayList<String> included = Lists.newArrayList();
+		Expdef expdef = (Expdef) expdefResource.getContents().get(0);
+		for (PropertyIncludeDeclaration pid : expdef.getPropertyImports())
+			included.add(pid.getImportURI());
+		for (IncludeDeclaration id : expdef.getCode().getIncludes())
+			included.add(id.getImportURI());
+		// Get globals
+		for (String filename : included) {
+			Resource includedResource = findResourceByName(resourceSet, filename);
+			if (includedResource == null) {
+				String showURI = show.eResource().getURI().toString();
+				URI includeURI = URI.createURI(showURI.subSequence(
+						0, showURI.lastIndexOf("/")+1) + filename);
+				includedResource = resourceSet.getResource(
+						includeURI, true);
+				if (includedResource == null)
+					continue;
+			}
+			IResourceDescription resourceDescription =
+					descriptionManager.getResourceDescription(includedResource);
+			result.addAll(Lists.newArrayList(resourceDescription.getExportedObjectsByType(ref.getEReferenceType())));
+		}
+		return result;
+	}
+
+	private Resource findResourceByName(ResourceSet resourceSet,
+			String filename) {
+		for (Resource res : resourceSet.getResources()) {
+			if (res.getURI().toString().endsWith("/" + filename)) {
+				return res;
+			}
+		}
+		return null;
+	}
+
 	protected IScope scope_VariableRef_var(Model model, EReference ref) {
-//		IScope outerScope = delegateGetScope(model, ref).getOuterScope();
-		IScope types = typesScopes.get(getExtension(model));
-		return new SimpleScope(types.getAllElements());
+		IScope outerScope = globalScopeProvider.getScope(model.eResource(), ref, null);
+		if (model instanceof Show) {
+			outerScope = new SimpleScope(outerScope, showExpdefIncludes((Show)model, ref));
+		}
+		String ext = getExtension(model);
+		if ("inc".equals(ext))	// There is no description for .inc in XML,
+			ext = "script";	// so we pretend it is a .script.
+		IScope types = typesScopes.get(ext);
+		return new SimpleScope(outerScope, types.getAllElements());
 	}
 
@@ -211,5 +386,13 @@
 		return Scopes.scopeFor(labels);
 	}
-	
+
+	protected IScope scope_Property(Show show, EReference ref) {
+		return new SimpleScope(delegateGetScope(show, ref), showExpdefIncludes(show, ref));
+	}
+
+	protected IScope scope_State(Show show, EReference ref) {
+		return new SimpleScope(delegateGetScope(show, ref), showExpdefIncludes(show, ref));
+	}
+
 	private Function createFunction(Element element) {
 		Function function = new ProposableFunctionImpl(element);
@@ -233,5 +416,5 @@
 		return global;
 	}
-	
+
 	private VariableDeclaration createVariableDeclaration(String name) {
 		VariableDeclaration var = FramScriptFactory.eINSTANCE.createVariableDeclaration();
@@ -240,10 +423,10 @@
 		return var;
 	}
-	
+
 	private QualifiedExpression getParent(QualifiedExpression expr) {
 		EStructuralFeature feature = expr.eContainingFeature();
 		if (feature.equals(QUALIFIED_EXPRESSION__CHILD)) {
 			return (QualifiedExpression) expr.eContainer();
-		} else if (feature.equals(QUALIFIED_EXPRESSION__PARENT) 
+		} else if (feature.equals(QUALIFIED_EXPRESSION__PARENT)
 				|| feature.equals(ARRAY_ELEMENT_EXPRESSION__ARRAY)) {
 			return getParent((QualifiedExpression) expr.eContainer());
@@ -252,12 +435,5 @@
 		}
 	}
-	
-	private Block getBlock(EObject object) {
-		while (object != null && !(object instanceof Block)) {
-			object = object.eContainer();
-		}
-		return (Block) object;
-	}
-	
+
 	private Function getFunction(EObject object) {
 		while (object != null && !(object instanceof Function)) {
@@ -266,8 +442,15 @@
 		return (Function) object;
 	}
-	
+
+	private Show getShow(EObject object) {
+		while (object != null && !(object instanceof Show)) {
+			object = object.eContainer();
+		}
+		return (Show) object;
+	}
+
 	private String getExtension(EObject object) {
 		return object.eResource().getURI().fileExtension();
 	}
-	
+
 }
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/script/XMLConstantProvider.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/script/XMLConstantProvider.java	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/script/XMLConstantProvider.java	(revision 440)
@@ -85,5 +85,5 @@
 		for (File file : framscontext.getFiles()) {
 			String ext = file.getPattern();
-			ext = ext.substring(ext.indexOf('.') + 1, ext.length());
+			ext = ext.substring(ext.lastIndexOf('.') + 1, ext.length());
 			if (file.getCode() != null) {
 				for (Context context : file.getCode().getContexts()) {
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/script/model/Element.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/script/model/Element.java	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/script/model/Element.java	(revision 440)
@@ -21,5 +21,5 @@
 	@XStreamAlias("default")
 	@XStreamAsAttribute
-	private Double def;
+	private String def;
 
 	private String description;
@@ -47,5 +47,5 @@
 	}
 
-	public Double getDef() {
+	public String getDef() {
 		return def;
 	}
Index: java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/validation/FramScriptJavaValidator.java
===================================================================
--- java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/validation/FramScriptJavaValidator.java	(revision 438)
+++ java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/validation/FramScriptJavaValidator.java	(revision 440)
@@ -1,6 +1,19 @@
+/*
+ * generated by Xtext
+ */
 package com.framsticks.framclipse.validation;
 
+/**
+ * This class contains custom validation rules.
+ *
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation
+ */
+public class FramScriptJavaValidator extends com.framsticks.framclipse.validation.AbstractFramScriptJavaValidator {
 
-public class FramScriptJavaValidator extends AbstractFramScriptJavaValidator {
-
+//	@Check
+//	public void checkGreetingStartsWithCapital(Greeting greeting) {
+//		if (!Character.isUpperCase(greeting.getName().charAt(0))) {
+//			warning("Name should start with a capital", MyDslPackage.Literals.GREETING__NAME);
+//		}
+//	}
 }
