diff --git a/dsymbol b/dsymbol
index 47f4711..a8ffcc9 160000
--- a/dsymbol
+++ b/dsymbol
@@ -1 +1 @@
-Subproject commit 47f471114ad272dc0cd41996c7977413d7a68d63
+Subproject commit a8ffcc99d79b2b1195b7aac169a183706c2c9ec0
diff --git a/dub.json b/dub.json
index f2a477f..796968a 100644
--- a/dub.json
+++ b/dub.json
@@ -12,11 +12,11 @@
     "StdLoggerDisableWarning"
   ],
   "dependencies" : {
-    "libdparse": "~>0.9.10",
-    "dsymbol" : "~>0.4.8",
+    "libdparse": "~>0.10.8",
+    "dsymbol" : "~>0.5.3",
     "inifiled" : "~>1.3.1",
     "emsi_containers" : "~>0.8.0-alpha.7",
-    "libddoc" : "~>0.4.0",
+    "libddoc" : "~>0.5.0",
     "stdx-allocator" : "~>2.77.4"
   },
   "targetPath" : "bin",
diff --git a/libddoc b/libddoc
index e1dae8e..bf04727 160000
--- a/libddoc
+++ b/libddoc
@@ -1 +1 @@
-Subproject commit e1dae8ec11e03904ece4c36ae4fd497ebbbeb820
+Subproject commit bf0472714f435452c253fd7755d838e383cee987
diff --git a/libdparse b/libdparse
index f8460d0..fc3f8e6 160000
--- a/libdparse
+++ b/libdparse
@@ -1 +1 @@
-Subproject commit f8460d0d3581bebd41ee8629bd3e253c94c8a387
+Subproject commit fc3f8e6da9777ab3cef41933cfc5b36522d3b8a7
diff --git a/src/dscanner/analysis/assert_without_msg.d b/src/dscanner/analysis/assert_without_msg.d
index c01dc5d..6ee8f93 100644
--- a/src/dscanner/analysis/assert_without_msg.d
+++ b/src/dscanner/analysis/assert_without_msg.d
@@ -29,7 +29,7 @@ final class AssertWithoutMessageCheck : BaseAnalyzer
 
 	override void visit(const AssertExpression expr)
 	{
-		if (expr.message is null)
+		if (expr.assertArguments && expr.assertArguments.message is null)
 			addErrorMessage(expr.line, expr.column, KEY, MESSAGE);
 	}
 
diff --git a/src/dscanner/analysis/auto_function.d b/src/dscanner/analysis/auto_function.d
index 53aeac0..df7e2ad 100644
--- a/src/dscanner/analysis/auto_function.d
+++ b/src/dscanner/analysis/auto_function.d
@@ -53,7 +53,7 @@ public:
 
 		decl.accept(this);
 
-		if (decl.functionBody && autoFun && !_returns[$-1])
+		if (decl.functionBody.specifiedFunctionBody && autoFun && !_returns[$-1])
 			addErrorMessage(decl.name.line, decl.name.column, KEY, MESSAGE);
 	}
 
@@ -64,7 +64,7 @@ public:
 		rst.accept(this);
 	}
 
-	override void visit(const(AssertExpression) exp)
+	override void visit(const(AssertArguments) exp)
 	{
 		exp.accept(this);
 		if (_returns.length)
diff --git a/src/dscanner/analysis/if_constraints_indent.d b/src/dscanner/analysis/if_constraints_indent.d
index 45087e3..8391f7a 100644
--- a/src/dscanner/analysis/if_constraints_indent.d
+++ b/src/dscanner/analysis/if_constraints_indent.d
@@ -126,11 +126,11 @@ unittest
 
 	assertAnalyzerWarnings(q{
 void foo(R)(R r)
-if (R == int)
+if (R == null)
 {}
 
 void foo(R)(R r)
-	if (R == int) // [warn]: %s
+	if (R == null) // [warn]: %s
 {}
 	}c.format(
 		IfConstraintsIndentCheck.MESSAGE,
@@ -138,15 +138,15 @@ void foo(R)(R r)
 
 	assertAnalyzerWarnings(q{
 	void foo(R)(R r)
-	if (R == int)
+	if (R == null)
 	{}
 
 	void foo(R)(R r)
-if (R == int) // [warn]: %s
+if (R == null) // [warn]: %s
 	{}
 
 	void foo(R)(R r)
-		if (R == int) // [warn]: %s
+		if (R == null) // [warn]: %s
 	{}
 	}c.format(
 		IfConstraintsIndentCheck.MESSAGE,
@@ -155,15 +155,15 @@ if (R == int) // [warn]: %s
 
 	assertAnalyzerWarnings(q{
 	struct Foo(R)
-	if (R == int)
+	if (R == null)
 	{}
 
 	struct Foo(R)
-if (R == int) // [warn]: %s
+if (R == null) // [warn]: %s
 	{}
 
 	struct Foo(R)
-		if (R == int) // [warn]: %s
+		if (R == null) // [warn]: %s
 	{}
 	}c.format(
 		IfConstraintsIndentCheck.MESSAGE,
@@ -188,33 +188,33 @@ if (is(typeof(Num.init >= 0)) && is(typeof(-Num.init)) &&
 	assertAnalyzerWarnings(q{
 	struct Foo(R)
 	if
-	(R == int)
+	(R == null)
 	{}
 
 	struct Foo(R)
 	if
-		(R == int)
+		(R == null)
 	{}
 
 	struct Foo(R)
 if
-	(R == int) // [warn]: %s
+	(R == null) // [warn]: %s
 	{}
 
 	struct Foo(R)
 	if (
-	R == int)
+	R == null)
 	{}
 
 	struct Foo(R)
 	if (
-		R == int
+		R == null
 	)
 	{}
 
 	struct Foo(R)
 		if (
-		R == int // [warn]: %s
+		R == null // [warn]: %s
 	) {}
 	}c.format(
 		IfConstraintsIndentCheck.MESSAGE,
diff --git a/src/dscanner/analysis/incorrect_infinite_range.d b/src/dscanner/analysis/incorrect_infinite_range.d
index a92c1d2..be52b10 100644
--- a/src/dscanner/analysis/incorrect_infinite_range.d
+++ b/src/dscanner/analysis/incorrect_infinite_range.d
@@ -42,11 +42,8 @@ final class IncorrectInfiniteRangeCheck : BaseAnalyzer
 
 	override void visit(const FunctionBody fb)
 	{
-		if (fb.bodyStatement !is null)
-			visit(fb.bodyStatement.blockStatement);
-		else
-			if (fb.blockStatement !is null)
-				visit(fb.blockStatement);
+		if (fb.specifiedFunctionBody && fb.specifiedFunctionBody.blockStatement !is null)
+			visit(fb.specifiedFunctionBody.blockStatement);
 	}
 
 	override void visit(const BlockStatement bs)
diff --git a/src/dscanner/analysis/lambda_return_check.d b/src/dscanner/analysis/lambda_return_check.d
index fed78bd..b4b9189 100644
--- a/src/dscanner/analysis/lambda_return_check.d
+++ b/src/dscanner/analysis/lambda_return_check.d
@@ -8,6 +8,7 @@ module dscanner.analysis.lambda_return_check;
 import dparse.ast;
 import dparse.lexer;
 import dscanner.analysis.base;
+import dscanner.utils : safeAccess;
 
 final class LambdaReturnCheck : BaseAnalyzer
 {
@@ -20,23 +21,14 @@ final class LambdaReturnCheck : BaseAnalyzer
 
 	override void visit(const FunctionLiteralExpression fLit)
 	{
-		if (fLit.assignExpression is null)
-			return;
-		const UnaryExpression unary = cast(const UnaryExpression) fLit.assignExpression;
-		if (unary is null)
-			return;
-		if (unary.primaryExpression is null)
-			return;
-		if (unary.primaryExpression.functionLiteralExpression is null)
-			return;
-		if (unary.primaryExpression.functionLiteralExpression.parameters !is null)
-			return;
-		if (unary.primaryExpression.functionLiteralExpression.identifier != tok!"")
-			return;
-		if (unary.primaryExpression.functionLiteralExpression.functionBody is null)
-			return;
-		if (unary.primaryExpression.functionLiteralExpression.functionBody.blockStatement is null)
+		auto fe = safeAccess(fLit).assignExpression.as!UnaryExpression
+			.primaryExpression.functionLiteralExpression.unwrap;
+
+		if (fe is null || fe.parameters !is null || fe.identifier != tok!"" ||
+			fe.specifiedFunctionBody is null || fe.specifiedFunctionBody.blockStatement is null)
+		{
 			return;
+		}
 		addErrorMessage(fLit.line, fLit.column, KEY, "This lambda returns a lambda. Add parenthesis to clarify.");
 	}
 
diff --git a/src/dscanner/analysis/style.d b/src/dscanner/analysis/style.d
index 6ab0e9b..5a948a0 100644
--- a/src/dscanner/analysis/style.d
+++ b/src/dscanner/analysis/style.d
@@ -90,8 +90,9 @@ final class StyleChecker : BaseAnalyzer
 			pushWinStyle(la.identifier.text.length && la.identifier.text == "Windows");
 		}
 
-		if (dec.functionBody || (!dec.functionBody && !winStyle()))
-			checkLowercaseName("Function", dec.name);
+		if (dec.functionBody.specifiedFunctionBody ||
+			(dec.functionBody.missingFunctionBody && !winStyle()))
+				checkLowercaseName("Function", dec.name);
 
 		if (p)
 			popWinStyle;
diff --git a/src/dscanner/analysis/unused_label.d b/src/dscanner/analysis/unused_label.d
index b98ddc1..86e961f 100644
--- a/src/dscanner/analysis/unused_label.d
+++ b/src/dscanner/analysis/unused_label.d
@@ -31,22 +31,28 @@ final class UnusedLabelCheck : BaseAnalyzer
 		popScope();
 	}
 
+	override void visit(const FunctionLiteralExpression flit)
+	{
+		if (flit.specifiedFunctionBody)
+		{
+			pushScope();
+			flit.specifiedFunctionBody.accept(this);
+			popScope();
+		}
+	}
+
 	override void visit(const FunctionBody functionBody)
 	{
-		if (functionBody.blockStatement !is null)
+		if (functionBody.specifiedFunctionBody !is null)
 		{
 			pushScope();
-			functionBody.blockStatement.accept(this);
+			functionBody.specifiedFunctionBody.accept(this);
 			popScope();
 		}
-		if (functionBody.bodyStatement !is null)
-		{
-			pushScope();
-			functionBody.bodyStatement.accept(this);
-			popScope();
-		}
-		functionBody.outStatements.each!((a){pushScope(); a.accept(this); popScope();});
-		functionBody.inStatements.each!((a){pushScope(); a.accept(this); popScope();});
+        if (functionBody.missingFunctionBody && functionBody.missingFunctionBody.functionContracts)
+			functionBody.missingFunctionBody.functionContracts.each!((a){pushScope(); a.accept(this); popScope();});
+        if (functionBody.specifiedFunctionBody && functionBody.specifiedFunctionBody.functionContracts)
+			functionBody.specifiedFunctionBody.functionContracts.each!((a){pushScope(); a.accept(this); popScope();});
 	}
 
 	override void visit(const LabeledStatement labeledStatement)
diff --git a/src/dscanner/analysis/useless_assert.d b/src/dscanner/analysis/useless_assert.d
index af9d7e6..2339f9c 100644
--- a/src/dscanner/analysis/useless_assert.d
+++ b/src/dscanner/analysis/useless_assert.d
@@ -37,7 +37,7 @@ final class UselessAssertCheck : BaseAnalyzer
 	{
 		import std.conv : to;
 
-		UnaryExpression unary = cast(UnaryExpression) ae.assertion;
+		UnaryExpression unary = cast(UnaryExpression) ae.assertArguments.assertion;
 		if (unary is null)
 			return;
 		if (unary.primaryExpression is null)
diff --git a/src/dscanner/astprinter.d b/src/dscanner/astprinter.d
index 1b2cbbf..020e083 100644
--- a/src/dscanner/astprinter.d
+++ b/src/dscanner/astprinter.d
@@ -106,21 +106,6 @@ class XMLPrinter : ASTVisitor
 		output.writeln("</asmInstruction>");
 	}
 
-	override void visit(const AssertExpression assertExpression)
-	{
-		output.writeln("<assertExpression>");
-		output.writeln("<assertion>");
-		assertExpression.assertion.accept(this);
-		output.writeln("</assertion>");
-		if (assertExpression.message !is null)
-		{
-			output.writeln("<message>");
-			assertExpression.message.accept(this);
-			output.writeln("</message>");
-		}
-		output.writeln("</assertExpression>");
-	}
-
 	override void visit(const AssignExpression assignExpression)
 	{
 		if (assignExpression.expression is null)
@@ -1070,11 +1055,12 @@ class XMLPrinter : ASTVisitor
 	override void visit(const AsmUnaExp asmUnaExp) { mixin (tagAndAccept!"asmUnaExp"); }
 	override void visit(const AsmXorExp asmXorExp) { mixin (tagAndAccept!"asmXorExp"); }
 	override void visit(const AssocArrayLiteral assocArrayLiteral) { mixin (tagAndAccept!"assocArrayLiteral"); }
+	override void visit(const AssertExpression assertExpression) { mixin (tagAndAccept!"assertExpression"); }
+	override void visit(const AssertArguments assertArguments) { mixin (tagAndAccept!"assertArguments"); }
 	override void visit(const AttributeDeclaration attributeDeclaration) { mixin (tagAndAccept!"attributeDeclaration"); }
 	override void visit(const BaseClass baseClass) { mixin (tagAndAccept!"baseClass"); }
 	override void visit(const BaseClassList baseClassList) { mixin (tagAndAccept!"baseClassList"); }
 	override void visit(const BlockStatement blockStatement) { mixin (tagAndAccept!"blockStatement"); }
-	override void visit(const BodyStatement bodyStatement) { mixin (tagAndAccept!"bodyStatement"); }
 	override void visit(const CaseStatement caseStatement) { mixin (tagAndAccept!"caseStatement"); }
 	override void visit(const CastExpression castExpression) { mixin (tagAndAccept!"castExpression"); }
 	override void visit(const CastQualifier castQualifier) { mixin (tagAndAccept!"castQualifier"); }
@@ -1109,6 +1095,8 @@ class XMLPrinter : ASTVisitor
 	override void visit(const ImportExpression importExpression) { mixin (tagAndAccept!"importExpression"); }
 	override void visit(const IndexExpression indexExpression) { mixin (tagAndAccept!"indexExpression"); }
 	override void visit(const InStatement inStatement) { mixin (tagAndAccept!"inStatement"); }
+	override void visit(const InContractExpression inContractExpression) { mixin (tagAndAccept!"inContractExpression"); }
+	override void visit(const InOutContractExpression inOutContractExpression) { mixin (tagAndAccept!"inOutContractExpression"); }
 	override void visit(const KeyValuePairs keyValuePairs) { mixin (tagAndAccept!"keyValuePairs"); }
 	override void visit(const MixinExpression mixinExpression) { mixin (tagAndAccept!"mixinExpression"); }
 	override void visit(const MixinTemplateDeclaration mixinTemplateDeclaration) { mixin (tagAndAccept!"mixinTemplateDeclaration"); }
diff --git a/src/dscanner/utils.d b/src/dscanner/utils.d
index 2c3801d..11f2305 100644
--- a/src/dscanner/utils.d
+++ b/src/dscanner/utils.d
@@ -145,6 +145,13 @@ if (is(M == class))
 	/// Unprotect the class instance.
 	alias unwrap = m;
 
+	/// Allows cast to interfaces and classes inside the chain.
+	auto ref as(A)() @trusted
+	if (!__traits(hasMember, M, "as") && (is(A == class) || is(A == interface)))
+	{
+		return SafeAccess!(A)(cast(A) m);
+	}
+
 	/// Handles safe access.
 	auto ref opDispatch(string member, A...)(auto ref A a)
 	{
@@ -177,7 +184,7 @@ if (is(M == class))
 				else
 				{
 					if (m)
-					    __traits(getMember, m, member)(a);
+						__traits(getMember, m, member)(a);
 				}
 			}
 			else