Merge pull request #232 from ftomassetti/issue_231

issue231: fix how empty Enums are dumped
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/MultiTypeParameter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/MultiTypeParameter.java
index 8ad20e9..2e0c97d 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/body/MultiTypeParameter.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/MultiTypeParameter.java
@@ -23,6 +23,7 @@
 
 import com.github.javaparser.ast.expr.AnnotationExpr;
 import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.type.UnionType;
 import com.github.javaparser.ast.visitor.GenericVisitor;
 import com.github.javaparser.ast.visitor.VoidVisitor;
 
@@ -31,18 +32,18 @@
 import static com.github.javaparser.ast.internal.Utils.ensureNotNull;
 
 public class MultiTypeParameter extends BaseParameter {
-    private List<Type> types;
+    private UnionType type;
 	
     public MultiTypeParameter() {}
 
-    public MultiTypeParameter(int modifiers, List<AnnotationExpr> annotations, List<Type> types, VariableDeclaratorId id) {
+    public MultiTypeParameter(int modifiers, List<AnnotationExpr> annotations, UnionType type, VariableDeclaratorId id) {
         super(modifiers, annotations, id);
-        this.types = types;
+        this.type = type;
     }
 
-    public MultiTypeParameter(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers, List<AnnotationExpr> annotations, List<Type> types, VariableDeclaratorId id) {
+    public MultiTypeParameter(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers, List<AnnotationExpr> annotations, UnionType type, VariableDeclaratorId id) {
         super(beginLine, beginColumn, endLine, endColumn, modifiers, annotations, id);
-        this.types = types;
+        this.type = type;
 	}
 
     @Override
@@ -55,13 +56,11 @@
         v.visit(this, arg);
     }
 
-    public List<Type> getTypes() {
-        types = ensureNotNull(types);
-        return types;
+    public UnionType getType() {
+        return type;
     }
 
-    public void setTypes(List<Type> types) {
-        this.types = types;
-        setAsParentNodeOf(types);
+    public void setType(UnionType type) {
+        this.type = type;
     }
 }
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/CatchClause.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/CatchClause.java
index 3f43e79..209de18 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/CatchClause.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/CatchClause.java
@@ -23,9 +23,11 @@
 
 import com.github.javaparser.ast.Node;
 import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.Parameter;
 import com.github.javaparser.ast.body.VariableDeclaratorId;
 import com.github.javaparser.ast.expr.AnnotationExpr;
 import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.type.UnionType;
 import com.github.javaparser.ast.visitor.GenericVisitor;
 import com.github.javaparser.ast.visitor.VoidVisitor;
 
@@ -36,27 +38,23 @@
  */
 public final class CatchClause extends Node {
 
-    private MultiTypeParameter except;
+    private Parameter param;
 
     private BlockStmt catchBlock;
 
     public CatchClause() {
     }
 
-    public CatchClause(final MultiTypeParameter except, final BlockStmt catchBlock) {
-        setExcept(except);
+    public CatchClause(final Parameter param, final BlockStmt catchBlock) {
+        setParam(param);
         setCatchBlock(catchBlock);
     }
-	
-    public CatchClause(int exceptModifier, List<AnnotationExpr> exceptAnnotations, List<Type> exceptTypes, VariableDeclaratorId exceptId, BlockStmt catchBlock) {
-        this(new MultiTypeParameter(exceptModifier, exceptAnnotations, exceptTypes, exceptId), catchBlock);
-    }
 
     public CatchClause(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
-    	    final int exceptModifier, final List<AnnotationExpr> exceptAnnotations, final List<Type> exceptTypes, 
+    	    final int exceptModifier, final List<AnnotationExpr> exceptAnnotations, final Type exceptTypes,
     	    final VariableDeclaratorId exceptId, final BlockStmt catchBlock) {
         super(beginLine, beginColumn, endLine, endColumn);
-        setExcept(new MultiTypeParameter(beginLine, beginColumn, endLine, endColumn, exceptModifier, exceptAnnotations, exceptTypes, exceptId));
+        setParam(new Parameter(beginLine, beginColumn, endLine, endColumn, exceptModifier, exceptAnnotations, exceptTypes, false, exceptId));
         setCatchBlock(catchBlock);
     }
 
@@ -72,8 +70,8 @@
 		return catchBlock;
 	}
 
-	public MultiTypeParameter getExcept() {
-		return except;
+	public Parameter getParam() {
+		return param;
 	}
 
 	public void setCatchBlock(final BlockStmt catchBlock) {
@@ -81,8 +79,8 @@
 		setAsParentNodeOf(this.catchBlock);
 	}
 
-	public void setExcept(final MultiTypeParameter except) {
-		this.except = except;
-		setAsParentNodeOf(this.except);
+	public void setParam(final Parameter param) {
+		this.param = param;
+		setAsParentNodeOf(this.param);
 	}
 }
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java
new file mode 100644
index 0000000..0cd6fde
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java
@@ -0,0 +1,59 @@
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * Represents a set of types. A given value of this type has to be assignable to at all of the element types.
+ * As of Java 8 it is used in casts or while expressing bounds for generic types.
+ *
+ * For example:
+ * public class A&gt;T extends Serializable &amp; Cloneable&lt; { }
+ *
+ * Or:
+ * void foo((Serializable &amp; Cloneable)myObject);
+ *
+ * @since 3.0.0
+ */
+public class IntersectionType extends Type {
+
+    private List<ReferenceType> elements;
+
+    public IntersectionType(int beginLine, int beginColumn, int endLine,
+                            int endColumn, List<ReferenceType> elements) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setElements(elements);
+    }
+
+    public IntersectionType(List<ReferenceType> elements) {
+        super();
+        setElements(elements);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<ReferenceType> getElements() {
+        return elements;
+    }
+
+    public void setElements(List<ReferenceType> elements) {
+        if (this.elements != null) {
+            for (ReferenceType element : elements){
+                element.setParentNode(null);
+            }
+        }
+        this.elements = elements;
+        setAsParentNodeOf(this.elements);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java
new file mode 100644
index 0000000..83eeee6
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java
@@ -0,0 +1,52 @@
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * Represents a set of types. A given value of this type has to be assignable to at least one of the element types.
+ * As of Java 8 it is only used in catch clauses.
+ *
+ * @since 3.0.0
+ */
+public class UnionType extends Type {
+
+    private List<ReferenceType> elements;
+
+    public UnionType(int beginLine, int beginColumn, int endLine,
+                     int endColumn, List<ReferenceType> elements) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setElements(elements);
+    }
+
+    public UnionType(List<ReferenceType> elements) {
+        super();
+        setElements(elements);
+    }
+
+    public List<ReferenceType> getElements() {
+        return elements;
+    }
+
+    public void setElements(List<ReferenceType> elements) {
+        if (this.elements != null) {
+            for (ReferenceType element : elements){
+                element.setParentNode(null);
+            }
+        }
+        this.elements = elements;
+        setAsParentNodeOf(this.elements);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java
index 3d8d299..17d976e 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java
@@ -311,13 +311,13 @@
 	@Override
 	public Node visit(MultiTypeParameter _n, Object _arg) {
 		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
-		List<Type> types = visit(_n.getTypes(), _arg);
+		UnionType type = cloneNodes(_n.getType(), _arg);
 		VariableDeclaratorId id = cloneNodes(_n.getId(), _arg);
 		Comment comment = cloneNodes(_n.getComment(), _arg);
 
 		MultiTypeParameter r = new MultiTypeParameter(
 				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
-				_n.getModifiers(), annotations, types, id
+				_n.getModifiers(), annotations, type, id
 		);
 		r.setComment(comment);
 		return r;
@@ -407,6 +407,30 @@
 		return r;
 	}
 
+    @Override
+    public Node visit(IntersectionType _n, Object _arg) {
+        List<ReferenceType> elements = visit(_n.getElements(), _arg);
+
+        IntersectionType r = new IntersectionType(_n.getBeginLine(),
+                _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+                elements);
+        Comment comment = cloneNodes(_n.getComment(), _arg);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    public Node visit(UnionType _n, Object _arg) {
+        List<ReferenceType> elements = visit(_n.getElements(), _arg);
+
+        UnionType r = new UnionType(_n.getBeginLine(),
+                _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+                elements);
+        Comment comment = cloneNodes(_n.getComment(), _arg);
+        r.setComment(comment);
+        return r;
+    }
+
 	@Override
 	public Node visit(VoidType _n, Object _arg) {
 		Comment comment = cloneNodes(_n.getComment(), _arg);
@@ -1138,13 +1162,13 @@
 
 	@Override
 	public Node visit(CatchClause _n, Object _arg) {
-		MultiTypeParameter except = cloneNodes(_n.getExcept(), _arg);
+		Parameter param = cloneNodes(_n.getParam(), _arg);
 		BlockStmt catchBlock = cloneNodes(_n.getCatchBlock(), _arg);
 		Comment comment = cloneNodes(_n.getComment(), _arg);
 
 		CatchClause r = new CatchClause(
 				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
-				except.getModifiers(), except.getAnnotations(), except.getTypes(), except.getId(), catchBlock
+				param.getModifiers(), param.getAnnotations(), param.getType(), param.getId(), catchBlock
 		);
 		r.setComment(comment);
 		return r;
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/DumpVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/DumpVisitor.java
index bc9f953..ada8ce5 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/DumpVisitor.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/DumpVisitor.java
@@ -511,6 +511,33 @@
 		}
 	}
 
+    @Override public void visit(final IntersectionType n, final Object arg) {
+        printJavaComment(n.getComment(), arg);
+        boolean isFirst = true;
+        for (ReferenceType element : n.getElements()) {
+            element.accept(this, arg);
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                printer.print(" & ");
+            }
+        }
+    }
+
+    @Override public void visit(final UnionType n, final Object arg) {
+        printJavaComment(n.getComment(), arg);
+        boolean isFirst = true;
+        for (ReferenceType element : n.getElements()) {
+            element.accept(this, arg);
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                printer.print(" | ");
+            }
+        }
+    }
+
+
 	@Override public void visit(final WildcardType n, final Object arg) {
 		printJavaComment(n.getComment(), arg);
 		if (n.getAnnotations() != null) {
@@ -1068,11 +1095,9 @@
         printAnnotations(n.getAnnotations(), arg);
         printModifiers(n.getModifiers());
 
-        Iterator<Type> types = n.getTypes().iterator();
-        types.next().accept(this, arg);
-        while (types.hasNext()) {
-        	printer.print(" | ");
-        	types.next().accept(this, arg);
+        Type type = n.getType();
+        if (type != null) {
+        	type.accept(this, arg);
         }
         
         printer.print(" ");
@@ -1452,7 +1477,7 @@
 	@Override public void visit(final CatchClause n, final Object arg) {
 		printJavaComment(n.getComment(), arg);
 		printer.print(" catch (");
-		n.getExcept().accept(this, arg);
+		n.getParam().accept(this, arg);
 		printer.print(") ");
 		n.getCatchBlock().accept(this, arg);
 
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java
index 8f4a786..f8ca05d 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java
@@ -543,16 +543,9 @@
 	
 	@Override public Boolean visit(MultiTypeParameter n1, Node arg) {
 		MultiTypeParameter n2 = (MultiTypeParameter) arg;
-		if (n1.getTypes().size() != n2.getTypes().size()) {
-			return Boolean.FALSE;
-		}
-		Iterator<Type> n1types = n1.getTypes().iterator();
-		Iterator<Type> n2types = n2.getTypes().iterator();
-		while (n1types.hasNext() && n2types.hasNext()) {
-			if (!nodeEquals(n1types.next(), n2types.next())) {
-				return Boolean.FALSE;
-			}
-		}
+        if (!nodeEquals(n1.getType(), n2.getType())) {
+            return Boolean.FALSE;
+        }
 		return visit((BaseParameter) n1, arg);
 	}
 
@@ -669,6 +662,56 @@
 		return Boolean.TRUE;
 	}
 
+    @Override public Boolean visit(final IntersectionType n1, final Node arg) {
+        final IntersectionType n2 = (IntersectionType) arg;
+
+        List<ReferenceType> n1Elements = n1.getElements();
+        List<ReferenceType> n2Elements = n2.getElements();
+
+        if (n1Elements !=null && n2Elements != null) {
+            if(n1Elements.size() != n2Elements.size()){
+                return Boolean.FALSE;
+            }
+            else{
+                int i = 0;
+                for(ReferenceType aux: n1Elements){
+                    if(aux.accept(this, n2Elements.get(i))) {
+                        return Boolean.FALSE;
+                    }
+                    i++;
+                }
+            }
+        }  else if (n1Elements != n2Elements){
+            return Boolean.FALSE;
+        }
+        return Boolean.TRUE;
+    }
+
+    @Override public Boolean visit(final UnionType n1, final Node arg) {
+        final UnionType n2 = (UnionType) arg;
+
+        List<ReferenceType> n1Elements = n1.getElements();
+        List<ReferenceType> n2Elements = n2.getElements();
+
+        if (n1Elements !=null && n2Elements != null) {
+            if(n1Elements.size() != n2Elements.size()){
+                return Boolean.FALSE;
+            }
+            else{
+                int i = 0;
+                for(ReferenceType aux: n1Elements){
+                    if(aux.accept(this, n2Elements.get(i))) {
+                        return Boolean.FALSE;
+                    }
+                    i++;
+                }
+            }
+        }  else if (n1Elements != n2Elements){
+            return Boolean.FALSE;
+        }
+        return Boolean.TRUE;
+    }
+
 	public Boolean visit(VoidType n1, Node arg) {
 		VoidType n2 = (VoidType) arg;
 		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
@@ -1416,7 +1459,7 @@
 	@Override public Boolean visit(final CatchClause n1, final Node arg) {
 		final CatchClause n2 = (CatchClause) arg;
 
-		if (!nodeEquals(n1.getExcept(), n2.getExcept())) {
+		if (!nodeEquals(n1.getParam(), n2.getParam())) {
 			return Boolean.FALSE;
 		}
 
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitor.java
index 58fbf6d..2527e2a 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitor.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitor.java
@@ -130,6 +130,10 @@
 
 	public R visit(ReferenceType n, A arg);
 
+    public R visit(IntersectionType n, A arg);
+
+    public R visit(UnionType n, A arg);
+
 	public R visit(VoidType n, A arg);
 
 	public R visit(WildcardType n, A arg);
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java
index eac9cab..db729bd 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java
@@ -304,7 +304,7 @@
 	@Override
 	public R visit(final CatchClause n, final A arg) {
 		{
-			R result = n.getExcept().accept(this, arg);
+			R result = n.getParam().accept(this, arg);
 			if (result != null) {
 				return result;
 			}
@@ -1229,8 +1229,8 @@
 			}
 		}
 		{
-			for (final Type type : n.getTypes()) {
-				R result = type.accept(this, arg);
+			if (n.getType() != null) {
+				R result = n.getType().accept(this, arg);
 				if (result != null) {
 					return result;
 				}
@@ -1272,6 +1272,32 @@
 		return null;
 	}
 
+    @Override
+    public R visit(final IntersectionType n, final A arg) {
+        {
+            for (ReferenceType element : n.getElements()) {
+                R result = element.accept(this, arg);
+                if (result != null) {
+                    return result;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public R visit(final UnionType n, final A arg) {
+        {
+            for (ReferenceType element : n.getElements()) {
+                R result = element.accept(this, arg);
+                if (result != null) {
+                    return result;
+                }
+            }
+        }
+        return null;
+    }
+
 	@Override
 	public R visit(final ReturnStmt n, final A arg) {
 		if (n.getExpr() != null) {
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java
index 3d23cea..78cd30a 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java
@@ -248,7 +248,7 @@
 	}
 
 	@Override public Node visit(final CatchClause n, final A arg) {
-		n.setExcept((MultiTypeParameter) n.getExcept().accept(this, arg));
+		n.setParam((Parameter)n.getParam().accept(this, arg));
 		n.setCatchBlock((BlockStmt) n.getCatchBlock().accept(this, arg));
 		return n;
 
@@ -757,11 +757,7 @@
 	
 	@Override public Node visit(MultiTypeParameter n, A arg) {
     	visit((BaseParameter) n, arg);
-    	List<Type> types = new LinkedList<Type>();
-    	for (Type type : n.getTypes()) {
-    		types.add((Type) type.accept(this, arg));
-    	}
-        n.setTypes(types);
+        n.setType((UnionType)n.getType().accept(this, arg));
         return n;
     }
 
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitor.java
index b85bd55..d0785a9 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitor.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitor.java
@@ -130,6 +130,10 @@
 
 	void visit(ReferenceType n, A arg);
 
+    void visit(IntersectionType n, A arg);
+
+    void visit(UnionType n, A arg);
+
 	void visit(VoidType n, A arg);
 
 	void visit(WildcardType n, A arg);
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java
index ddad12f..17da52a 100644
--- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java
@@ -187,7 +187,7 @@
 
 	@Override public void visit(final CatchClause n, final A arg) {
 		visitComment(n.getComment(), arg);
-		n.getExcept().accept(this, arg);
+		n.getParam().accept(this, arg);
 		n.getCatchBlock().accept(this, arg);
 	}
 
@@ -637,8 +637,8 @@
 				a.accept(this, arg);
 			}
 		}
-		for (final Type type : n.getTypes()) {
-			type.accept(this, arg);
+        if (n.getType() != null) {
+			n.getType().accept(this, arg);
 		}
 		n.getId().accept(this, arg);
 	}
@@ -657,6 +657,20 @@
 		n.getType().accept(this, arg);
 	}
 
+    @Override public void visit(final IntersectionType n, final A arg) {
+        visitComment(n.getComment(), arg);
+        for (ReferenceType element : n.getElements()) {
+            element.accept(this, arg);
+        }
+    }
+
+    @Override public void visit(final UnionType n, final A arg) {
+        visitComment(n.getComment(), arg);
+        for (ReferenceType element : n.getElements()) {
+            element.accept(this, arg);
+        }
+    }
+
 	@Override public void visit(final ReturnStmt n, final A arg) {
 		visitComment(n.getComment(), arg);
 		if (n.getExpr() != null) {
diff --git a/javaparser-core/src/main/javacc/java_1_8.jj b/javaparser-core/src/main/javacc/java_1_8.jj
index 74ae8f2..ec4d466 100644
--- a/javaparser-core/src/main/javacc/java_1_8.jj
+++ b/javaparser-core/src/main/javacc/java_1_8.jj
@@ -1760,6 +1760,21 @@
   { return new ReferenceType(type.getBeginLine(), type.getBeginColumn(), token.endLine, token.endColumn, type, arrayCount, null, accum); }
 }
 
+IntersectionType IntersectionType():
+{
+	int line;
+	int column;
+	Type elementType;
+	List elements = null;
+}
+{
+    elementType=ReferenceType() {
+        line=elementType.getBeginLine(); column=elementType.getBeginColumn();
+        elements = add(elements, elementType); }
+    "&" (elementType=ReferenceType() { elements = add(elements, elementType); } )+
+    { return new IntersectionType(line, column, token.endLine, token.endColumn, elements); }
+}
+
 ClassOrInterfaceType ClassOrInterfaceType():
 {
 	ClassOrInterfaceType ret;
@@ -2265,20 +2280,35 @@
 	int line;
 	int column;
 	AnnotationExpr ann;
+	Type st;
 	List annotations = null;
+	List typesOfMultiCast = null;
+	boolean isMulti = false;
 }
 {
   "(" {line=token.beginLine; column=token.beginColumn;}
    (ann = Annotation()   { annotations = add(annotations, ann);})*
   (
   	  LOOKAHEAD(2)
-  	  type = PrimitiveType() ")" ret = UnaryExpression() { type.setAnnotations(annotations); ret = new CastExpr(line, column, token.endLine, token.endColumn,type, ret); }
+  	  type = PrimitiveType() ")" ret = UnaryExpression() { type.setAnnotations(annotations); ret = new CastExpr(line, column, token.endLine, token.endColumn, type, ret); }
   	|
-  	  type = ReferenceType() ")" ret = UnaryExpressionNotPlusMinus() { type.setAnnotations(annotations); ret = new CastExpr(line, column, token.endLine, token.endColumn,type, ret); }
-  )
+  	  type = ReferenceType() { typesOfMultiCast = add(typesOfMultiCast, type); type.setAnnotations(annotations); }
+  	  ( "&" type = ReferenceType() {
+  	    typesOfMultiCast = add(typesOfMultiCast, type);
+  	    }
+  	  )*
+  	  ")" ret = UnaryExpressionNotPlusMinus() {
+  	    if (typesOfMultiCast.size() > 1) {
+  	        type = new IntersectionType(line, column, token.endLine, token.endColumn, typesOfMultiCast);
+  	    }
+  	    ret = new CastExpr(line, column, token.endLine, token.endColumn, type, ret);
+  	  }
+ )
   { return ret; }
 }
 
+
+
 Expression PrimaryExpression():
 {
 	Expression ret;
@@ -3036,6 +3066,7 @@
 	int column;
 	int cLine;
 	int cColumn;
+	Type type;
 }
 {
   "try" {line=token.beginLine; column=token.beginColumn;}
@@ -3052,7 +3083,14 @@
   			")"
   			 
   			catchBlock = Block()
-  			{ catchs = add(catchs, new CatchClause(cLine, cColumn, token.endLine, token.endColumn, exceptModifier.modifiers, exceptModifier.annotations, exceptTypes, exceptId, catchBlock)); exceptTypes = new LinkedList(); }
+  			{
+  			   if (exceptTypes.size() > 1) {
+  			        type = new UnionType(exceptTypes);
+  			   } else {
+  			        type = (Type)exceptTypes.get(0);
+  			   }
+  			   catchs = add(catchs, new CatchClause(cLine, cColumn, token.endLine, token.endColumn, exceptModifier.modifiers, exceptModifier.annotations, type, exceptId, catchBlock));
+  			   exceptTypes = new LinkedList(); }
   		)*
   		[ "finally" finallyBlock = Block() ]
   	|
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/visitors/PositionTestVisitor.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/visitors/PositionTestVisitor.java
index f359215..a99e682 100644
--- a/javaparser-testing/src/test/java/com/github/javaparser/bdd/visitors/PositionTestVisitor.java
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/visitors/PositionTestVisitor.java
@@ -345,6 +345,11 @@
         super.visit(n, arg);
     }
 
+    @Override public void visit(final IntersectionType n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
     @Override public void visit(final ReturnStmt n, final Object arg) {
         doTest(n);
         super.visit(n, arg);
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/parsing_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/parsing_scenarios.story
index b4d124f..894ece2 100644
--- a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/parsing_scenarios.story
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/parsing_scenarios.story
@@ -256,7 +256,6 @@
 Then method 2 class 1 is not a default method
 Then all nodes refer to their parent
 
-
 Scenario: A lambda expression inside a conditional expression is parsed by the Java Parser
 
 Given a CompilationUnit
@@ -282,3 +281,38 @@
 Then the end line is 2
 Then the end column is 29
 
+
+Scenario: simple cast on lambda expression can be parsed
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    static final Comparator<ChronoLocalDate> DATE_ORDER =
+        (Comparator<ChronoLocalDate>) (date1, date2) -> {
+            return Long.compare(date1.toEpochDay(), date2.toEpochDay());
+        };
+}
+Then all nodes refer to their parent
+
+
+Scenario: a combined cast on lambda expression can be parsed
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    static final Comparator<ChronoLocalDate> DATE_ORDER =
+        (Comparator<ChronoLocalDate> & Serializable) (date1, date2) -> {
+            return Long.compare(date1.toEpochDay(), date2.toEpochDay());
+        };
+}
+Then all nodes refer to their parent
+
+
+Scenario: a combined cast on a literal can be parsed
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    static int a = (Comparator<ChronoLocalDate> & Serializable) 1;
+}
+Then all nodes refer to their parent
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/visitor_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/visitor_scenarios.story
index c7f4775..0c87c62 100644
--- a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/visitor_scenarios.story
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/visitor_scenarios.story
@@ -73,5 +73,5 @@
 Given a VoidVisitorAdapter with a visit method that asserts sensible line positions
 When the "JavaConcepts.java" is parsed
 When the CompilationUnit is visited by the PositionTestVisitor
-Then the total number of nodes visited is 1326
+Then the total number of nodes visited is 1334