diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..43d013f
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,2 @@
+language: d
+script: make test
diff --git a/src/dfmt.d b/src/dfmt.d
index 83bd5dc..14a55d9 100644
--- a/src/dfmt.d
+++ b/src/dfmt.d
@@ -159,7 +159,7 @@ private:
             const i = index;
             if (i > 0)
             {
-                if (tokens[i-1].line < tokens[i].line)
+                if (tokens[i-1].line < current.line)
                 {
                     if (tokens[i-1].type != tok!"comment"
                         && tokens[i-1].type != tok!"{")
@@ -171,6 +171,11 @@ private:
             writeToken();
             if (i >= tokens.length-1)
                 newline();
+            else if (tokens[i+1].line-1 > tokens[i].line)
+            {
+                newline();
+                newline();
+            }
             else if (tokens[i+1].line > tokens[i].line)
                 newline();
             else if (tokens[i+1].type != tok!"{")
@@ -192,6 +197,8 @@ private:
                 {
                     writeToken();
                     tempIndent = 0;
+                    if (current.type == tok!"comment")
+                        break;
                     if (!(t == tok!"import" && current.type == tok!"import"))
                         write("\n");
                     newline();
@@ -226,7 +233,8 @@ private:
         else if (current.type == tok!"return")
         {
             writeToken();
-            write(" ");
+            if (current.type != tok!";")
+                write(" ");
         }
         else if (current.type == tok!"switch")
             formatSwitch();
@@ -310,17 +318,6 @@ private:
             case tok!"(":
                 writeParens(true);
                 break;
-            case tok!":":
-                if (!assumeSorted(astInformation.ternaryColonLocations)
-                    .equalRange(current.index).empty)
-                {
-                    write(" ");
-                    writeToken();
-                    write(" ");
-                }
-                else
-                    writeToken();
-                break;
             case tok!"@":
             case tok!"!":
             case tok!"...":
@@ -330,6 +327,10 @@ private:
             case tok!"$":
                 writeToken();
                 break;
+            case tok!":":
+                write(" : ");
+                index += 1;
+                break;
             case tok!"]":
                 writeToken();
                 if (current.type == tok!"identifier")
@@ -340,6 +341,8 @@ private:
                 writeToken();
                 if (current.type != tok!"comment")
                     newline();
+                if (peekImplementation(tok!"class",0))
+                    newline();
                 break;
             case tok!"{":
                 writeBraces();
@@ -538,7 +541,8 @@ private:
             else if (current.type == tok!")")
             {
                 if (peekIs(tok!"identifier") || (index + 1 < tokens.length
-                    && isKeyword(tokens[index + 1].type)))
+                    && (isKeyword(tokens[index+1].type)
+                     || tokens[index+1].type == tok!"@")))
                 {
                     writeToken();
                     if (space_afterwards)
@@ -807,9 +811,6 @@ struct ASTInformation
 
     /// Locations of unary operators
     size_t[] unaryLocations;
-
-    /// Locations of ':' operators in ternary expressions
-    size_t[] ternaryColonLocations;
 }
 
 /// Collects information from the AST that is useful for the formatter
@@ -882,13 +883,6 @@ final class FormatVisitor : ASTVisitor
         unary.accept(this);
     }
 
-    override void visit(const TernaryExpression ternary)
-    {
-        if (ternary.colon.type != tok!"")
-            astInformation.ternaryColonLocations ~= ternary.colon.index;
-        ternary.accept(this);
-    }
-
 private:
     ASTInformation* astInformation;
     alias visit = ASTVisitor.visit;
diff --git a/tests/DeclSpacing.d b/tests/DeclSpacing.d
new file mode 100644
index 0000000..a3af881
--- /dev/null
+++ b/tests/DeclSpacing.d
@@ -0,0 +1,6 @@
+import std.stdio;
+class Foo {}
+import std.conv;
+void main() {return;}
+const baz = 11;
+class Foo2:Foo {}
diff --git a/tests/DeclSpacing.d.ref b/tests/DeclSpacing.d.ref
new file mode 100644
index 0000000..7383c47
--- /dev/null
+++ b/tests/DeclSpacing.d.ref
@@ -0,0 +1,18 @@
+import std.stdio;
+
+class Foo
+{
+}
+
+import std.conv;
+
+void main()
+{
+    return;
+}
+
+const baz = 11;
+
+class Foo2 : Foo
+{
+}
diff --git a/tests/catchExceptionNested.d b/tests/catchExceptionNested.d
new file mode 100644
index 0000000..bddfd10
--- /dev/null
+++ b/tests/catchExceptionNested.d
@@ -0,0 +1,31 @@
+class U0 : Exception {
+    this() @safe pure nothrow { super("U0 error message"); }
+}
+ 
+class U1 : Exception {
+    this() @safe pure nothrow { super("U1 error message"); }
+}
+ 
+void foo() {
+    import std.stdio;
+ 
+    foreach (immutable i; 0 .. 2) {
+        try {
+            i.bar;
+        } catch (U0) {
+            "Function foo caught exception U0".writeln;
+        }
+    }
+}
+ 
+void bar(in int i) @safe pure {
+    i.baz;
+}
+ 
+void baz(in int i) @safe pure {
+    throw i ? new U1 : new U0;
+}
+ 
+void main() {
+    foo;
+}
diff --git a/tests/catchExceptionNested.d.ref b/tests/catchExceptionNested.d.ref
new file mode 100644
index 0000000..22d8d26
--- /dev/null
+++ b/tests/catchExceptionNested.d.ref
@@ -0,0 +1,49 @@
+class U0 : Exception
+{
+    this() @safe pure nothrow
+    {
+        super("U0 error message");
+    }
+
+}
+
+class U1 : Exception
+{
+    this() @safe pure nothrow
+    {
+        super("U1 error message");
+    }
+
+}
+
+void foo()
+{
+    import std.stdio;
+
+    foreach (immutable i; 0 .. 2)
+    {
+        try
+        {
+            i.bar;
+        }
+        catch(U0)
+        {
+            "Function foo caught exception U0".writeln;
+        }
+    }
+}
+
+void bar(in int i) @safe pure
+{
+    i.baz;
+}
+
+void baz(in int i) @safe pure
+{
+    throw i ? new U1 : new U0;
+}
+
+void main()
+{
+    foo;
+}
diff --git a/tests/heronian.d b/tests/heronian.d
deleted file mode 100644
index ffe6334..0000000
--- a/tests/heronian.d
+++ /dev/null
@@ -1,45 +0,0 @@
-import std.stdio, std.math, std.range, std.algorithm, std.numeric, std.traits, std.typecons;
- 
-double hero(in uint a, in uint b, in uint c) pure nothrow @safe @nogc {
-    immutable s = (a + b + c) / 2.0;
-    immutable a2 = s * (s - a) * (s - b) * (s - c);
-    return (a2 > 0) ? a2.sqrt : 0.0;
-}
- 
-bool isHeronian(in uint a, in uint b, in uint c) pure nothrow @safe @nogc {
-    immutable h = hero(a, b, c);
-    return h > 0 && h.floor == h.ceil;
-}
- 
-T gcd3(T)(in T x, in T y, in T z) pure nothrow @safe @nogc {
-    return gcd(gcd(x, y), z);
-}
- 
-void main() /*@safe*/ {
-    enum uint maxSide = 200;
- 
-    // Sort by increasing area, perimeter, then sides.
-    //auto h = cartesianProduct!3(iota(1, maxSide + 1))
-    auto r = iota(1, maxSide + 1);
-    const h = cartesianProduct(r, r, r)
-              //.filter!({a, b, c} => ...
-              .filter!(t => t[0] <= t[1] && t[1] <= t[2] &&
-                            t[0] + t[1] > t[2] &&
-                            t[].gcd3 == 1 && t[].isHeronian)
-              .array
-              .schwartzSort!(t => tuple(t[].hero, t[].only.sum, t.reverse))
-              .release;
- 
-    static void showTriangles(R)(R ts) @safe {
-        "Area Perimeter Sides".writeln;
-        foreach (immutable t; ts)
-            writefln("%3s %8d %3dx%dx%d", t[].hero, t[].only.sum, t[]);
-    }
- 
-    writefln("Primitive Heronian triangles with sides up to %d: %d", maxSide, h.length);
-    "\nFirst ten when ordered by increasing area, then perimeter,then maximum sides:".writeln;
-    showTriangles(h.take(10));
- 
-    "\nAll with area 210 subject to the previous ordering:".writeln;
-    showTriangles(h.filter!(t => t[].hero == 210));
-}
diff --git a/tests/heronian.d.ref b/tests/heronian.d.ref
deleted file mode 100644
index 14d84c9..0000000
--- a/tests/heronian.d.ref
+++ /dev/null
@@ -1,48 +0,0 @@
-import std.stdio, std.math, std.range, std.algorithm, std.numeric, std.traits,
-    std.typecons;
-
-double hero(in uint a, in uint b, in uint c) pure nothrow @safe @nogc
-{
-    immutable s = (a + b + c) / 2.0;
-    immutable a2 = s * (s - a) * (s - b) * (s - c);
-    return (a2 > 0) ? a2.sqrt : 0.0;
-}
-
-bool isHeronian(in uint a, in uint b, in uint c) pure nothrow @safe @nogc
-{
-    immutable h = hero(a, b, c);
-    return h > 0 && h.floor == h.ceil;
-}
-
-T gcd3(T)(in T x, in T y, in T z) pure nothrow @safe @nogc
-{
-    return gcd(gcd(x, y), z);
-}
-
-void main() /*@safe*/
-{
-    enum uint maxSide = 200;
-    // Sort by increasing area, perimeter, then sides.
-    //auto h = cartesianProduct!3(iota(1, maxSide + 1))
-    auto r = iota(1, maxSide + 1);
-    const h = cartesianProduct(r, r, r)
-        //.filter!({a, b, c} => ...
-        .filter!(t => t[0] <= t[1] && t[1] <= t[2] && t[0] + t[1] > t[2] &&
-                      t[].gcd3 == 1 && t[].isHeronian)
-        .array.schwartzSort!(t => tuple(t[].hero, t[].only.sum, t.reverse))
-        .release;
-
-    static void showTriangles(R)(R ts) @safe
-    {
-        "Area Perimeter Sides".writeln;
-        foreach (immutable t; ts)
-            writefln("%3s %8d %3dx%dx%d", t[].hero, t[].only.sum, t[]);
-    }
-
-    writefln("Primitive Heronian triangles with sides up to %d: %d", maxSide, h.length);
-    "\nFirst ten when ordered by increasing area, then perimeter,then maximum sides:"
-        .writeln;
-    showTriangles(h.take(10));
-    "\nAll with area 210 subject to the previous ordering:".writeln;
-    showTriangles(h.filter!(t => t[].hero == 210));
-}
diff --git a/tests/swap.d b/tests/swap.d
new file mode 100644
index 0000000..d5ee7d3
--- /dev/null
+++ b/tests/swap.d
@@ -0,0 +1,24 @@
+import std.algorithm: swap; // from Phobos standard library
+ 
+// The D solution uses templates and it's similar to the C++ one:
+void mySwap(T)(ref T left, ref T right) {
+    auto temp = left;
+    left = right;
+    right = temp;
+}
+ 
+void main() {
+    import std.stdio;
+ 
+    int[] a = [10, 20];
+    writeln(a);
+ 
+    // The std.algorithm standard library module
+    // contains a generic swap:
+    swap(a[0], a[1]);
+    writeln(a);
+ 
+    // Using mySwap:
+    mySwap(a[0], a[1]);
+    writeln(a);
+}
diff --git a/tests/swap.d.ref b/tests/swap.d.ref
new file mode 100644
index 0000000..a5176e3
--- /dev/null
+++ b/tests/swap.d.ref
@@ -0,0 +1,24 @@
+import std.algorithm : swap; // from Phobos standard library
+
+// The D solution uses templates and it's similar to the C++ one:
+void mySwap(T)(ref T left, ref T right)
+{
+    auto temp = left;
+    left = right;
+    right = temp;
+}
+
+void main()
+{
+    import std.stdio;
+
+    int[] a = [10, 20];
+    writeln(a);
+    // The std.algorithm standard library module
+    // contains a generic swap:
+    swap(a[0], a[1]);
+    writeln(a);
+    // Using mySwap:
+    mySwap(a[0], a[1]);
+    writeln(a);
+}
diff --git a/tests/test.sh b/tests/test.sh
index ea46ff2..463159f 100755
--- a/tests/test.sh
+++ b/tests/test.sh
@@ -4,5 +4,5 @@ set -e
 for source in *.d
 do
 	../bin/dfmt "${source}" >"${source}.out"
-	diff -u "${source}.ref" "${source}.out" || echo "fail ${source}"
+	diff -u "${source}.ref" "${source}.out"
 done