View Javadoc
1   package de.fhdw.wtf.walker.tasks.test;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertTrue;
5   
6   import java.util.ArrayList;
7   import java.util.Collection;
8   import java.util.HashSet;
9   import java.util.Iterator;
10  import java.util.Set;
11  import java.util.concurrent.ExecutionException;
12  
13  import org.junit.Test;
14  
15  import de.fhdw.wtf.common.ast.Attribute;
16  import de.fhdw.wtf.common.ast.GroupElement;
17  import de.fhdw.wtf.common.ast.Model;
18  import de.fhdw.wtf.common.ast.type.ByReferenceState;
19  import de.fhdw.wtf.common.ast.type.ClassType;
20  import de.fhdw.wtf.common.ast.type.ProductElementType;
21  import de.fhdw.wtf.common.ast.type.ProductType;
22  import de.fhdw.wtf.common.ast.type.SumType;
23  import de.fhdw.wtf.common.ast.type.Type;
24  import de.fhdw.wtf.common.ast.type.TypeProxy;
25  import de.fhdw.wtf.common.exception.parser.NoValidTokenStreamException;
26  import de.fhdw.wtf.common.exception.walker.CyclicDependencyException;
27  import de.fhdw.wtf.common.stream.FilteredTokenStream;
28  import de.fhdw.wtf.common.stream.SimpleScannerInput;
29  import de.fhdw.wtf.common.stream.TokenStream;
30  import de.fhdw.wtf.common.task.TaskExecutorFixed;
31  import de.fhdw.wtf.common.task.result.ExceptionalTaskResult;
32  import de.fhdw.wtf.common.task.result.OKTaskResult;
33  import de.fhdw.wtf.common.task.result.TaskResult;
34  import de.fhdw.wtf.common.task.result.visitor.TaskResultVisitor;
35  import de.fhdw.wtf.common.token.DummyToken;
36  import de.fhdw.wtf.dsl.scanner.common.Scanner;
37  import de.fhdw.wtf.dsl.scanner.modelScanner.ModelDslScanner;
38  import de.fhdw.wtf.parser.Parser;
39  import de.fhdw.wtf.walker.tasks.CyclicInheritanceCheck;
40  import de.fhdw.wtf.walker.tasks.PrototypesTask;
41  import de.fhdw.wtf.walker.tasks.SubtypesFillTask;
42  import de.fhdw.wtf.walker.tasks.SupertypesCleanInheritanceTask;
43  import de.fhdw.wtf.walker.tasks.SupertypesFillTask;
44  import de.fhdw.wtf.walker.tasks.TypeReferencer;
45  import de.fhdw.wtf.walker.walker.HelperUtils;
46  import de.fhdw.wtf.walker.walker.SimpleWalkerTask;
47  
48  /**
49   * Tests {@link de.fhdw.wtf.walker.tasks.SupertypesCleanInheritanceTask}.
50   */
51  public class TestSupertypesCleanInheritanceTask {
52  	
53  	/**
54  	 * Entsprechende Task laufen und erzeugen das Model.
55  	 * 
56  	 * @param input
57  	 *            SimpleScannerInput
58  	 * @return Model
59  	 * @throws CyclicDependencyException
60  	 *             CyclicDependencyException
61  	 * @throws InterruptedException
62  	 *             InterruptedException
63  	 * @throws ExecutionException
64  	 *             ExecutionException
65  	 * @throws NoValidTokenStreamException
66  	 *             NoValidTokenStreamException
67  	 */
68  	private Model getModel(final SimpleScannerInput input) throws CyclicDependencyException, InterruptedException,
69  			ExecutionException, NoValidTokenStreamException {
70  		final TokenStream output = FilteredTokenStream.create();
71  		final Scanner scanner = ModelDslScanner.create();
72  		scanner.scan(input, output);
73  		final Parser parser = Parser.create(output);
74  		Model model = null;
75  		model = parser.parse();
76  		assertEquals(0, parser.getExceptions().size());
77  		
78  		final TaskExecutorFixed taskmanager = TaskExecutorFixed.create();
79  		final TypeReferencer referencer = TypeReferencer.create(model, taskmanager);
80  		final SimpleWalkerTask prototypesTask = PrototypesTask.create(model, taskmanager);
81  		final SimpleWalkerTask subtypesFillTask = SubtypesFillTask.create(model, taskmanager);
82  		final SimpleWalkerTask cyclicInheritance = CyclicInheritanceCheck.create(model, taskmanager);
83  		final SupertypesFillTask supertypesFillTask = SupertypesFillTask.create(model, taskmanager);
84  		final SupertypesCleanInheritanceTask supertypesCleanInheritanceTask =
85  				SupertypesCleanInheritanceTask.create(model, taskmanager, supertypesFillTask);
86  		cyclicInheritance.addDependency(referencer);
87  		subtypesFillTask.addDependency(cyclicInheritance);
88  		prototypesTask.addDependency(subtypesFillTask);
89  		supertypesFillTask.addDependency(prototypesTask);
90  		supertypesCleanInheritanceTask.addDependency(supertypesFillTask);
91  		taskmanager.startAllKnownTasks();
92  		
93  		final Collection<OKTaskResult> okResult = new ArrayList<>();
94  		final Collection<ExceptionalTaskResult> failResult = new ArrayList<>();
95  		final Collection<TaskResult> results = taskmanager.getResultsAndShutdown();
96  		for (final TaskResult current : results) {
97  			current.accept(new TaskResultVisitor() {
98  				
99  				@Override
100 				public void handleOkTaskResult(final OKTaskResult result) {
101 					okResult.add(result);
102 				}
103 				
104 				@Override
105 				public void handleExceptionalTaskResult(final ExceptionalTaskResult result) {
106 					failResult.add(result);
107 				}
108 			});
109 		}
110 		
111 		assertEquals(6, okResult.size());
112 		assertEquals(0, failResult.size());
113 		
114 		return model;
115 	}
116 	
117 	/**
118 	 * Group:group=[]; .
119 	 * 
120 	 * @throws Exception
121 	 *             Exception
122 	 */
123 	@Test
124 	public void testEmptyModel() throws Exception {
125 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[];");
126 		final Model model = this.getModel(input);
127 		
128 		assertEquals(0, model.getAnything().getSuperTypes().size());
129 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
130 		
131 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
132 		assertEquals(
133 				model.getAnything().getPrototype(),
134 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
135 		
136 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
137 		assertEquals(
138 				model.getAnything().getPrototype(),
139 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
140 	}
141 	
142 	/**
143 	 * Group:group=[Class:class={Attribute:String;};]; .
144 	 * 
145 	 * @throws Exception
146 	 *             Exception
147 	 */
148 	@Test
149 	public void testModelWithoutSum() throws Exception {
150 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[Class:class={Attribute:String;};];");
151 		final Model model = this.getModel(input);
152 		
153 		assertEquals(0, model.getAnything().getSuperTypes().size());
154 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
155 		
156 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
157 		assertEquals(
158 				model.getAnything().getPrototype(),
159 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
160 		
161 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
162 		assertEquals(
163 				model.getAnything().getPrototype(),
164 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
165 	}
166 	
167 	/**
168 	 * Group:group=[Class:class={Attribute1:{String,Integer}; Attribute2:{String};};]; .
169 	 * 
170 	 * @throws Exception
171 	 *             Exception
172 	 */
173 	@Test
174 	public void testNormalContainsInheritance() throws Exception {
175 		final SimpleScannerInput input =
176 				new SimpleScannerInput("Group:group=[Class:class={Attribute1:{String,Integer,Class}; "
177 						+ "Attribute2:{String,Integer};};];");
178 		final Model model = this.getModel(input);
179 		
180 		assertEquals(0, model.getAnything().getSuperTypes().size());
181 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
182 		
183 		final ClassType clss = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
184 		final Iterator<Attribute> attrIterator = clss.getAttributes().iterator();
185 		final Attribute attr1 = attrIterator.next();
186 		final Attribute attr2 = attrIterator.next();
187 		
188 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
189 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
190 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
191 		assertTrue(attr1Type == model.getAnything().getPrototype());
192 		assertEquals(0, supertypesAttr1.size());
193 		
194 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
195 		final Collection<Type> supertypesAttr2 =
196 				((SumType) ((SumType) attr2.getAttrType()).getPrototype()).getSuperTypes();
197 		assertEquals(1, supertypesAttr2.size());
198 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
199 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr2Iterator.next()));
200 		
201 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
202 		assertEquals(
203 				attr2.getAttrType().getPrototype(),
204 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
205 		
206 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
207 		assertEquals(
208 				attr2.getAttrType().getPrototype(),
209 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
210 	}
211 	
212 	/**
213 	 * Group:group=[Class:class={Attribute1:{String,Integer}; Attribute2:{String};}; Class2:class={};]; .
214 	 * 
215 	 * @throws Exception
216 	 *             Exception
217 	 */
218 	@Test
219 	public void testNormalContainsInheritance2() throws Exception {
220 		final SimpleScannerInput input =
221 				new SimpleScannerInput("Group:group=[Class:class={Attribute1:{String,Integer,Class}; "
222 						+ "Attribute2:{String,Integer};};" + "Class2:class={};];");
223 		final Model model = this.getModel(input);
224 		
225 		assertEquals(0, model.getAnything().getSuperTypes().size());
226 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
227 		
228 		final ClassType clss = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
229 		final Iterator<Attribute> attrIterator = clss.getAttributes().iterator();
230 		final Attribute attr1 = attrIterator.next();
231 		final Attribute attr2 = attrIterator.next();
232 		
233 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
234 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
235 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
236 		assertEquals(1, supertypesAttr1.size());
237 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
238 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
239 		
240 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
241 		final Collection<Type> supertypesAttr2 =
242 				((SumType) ((SumType) attr2.getAttrType()).getPrototype()).getSuperTypes();
243 		assertEquals(1, supertypesAttr2.size());
244 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
245 		assertEquals(attr1Type, superTypesAttr2Iterator.next());
246 		
247 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
248 		assertEquals(
249 				attr2.getAttrType().getPrototype(),
250 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
251 		
252 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
253 		assertEquals(
254 				attr2.getAttrType().getPrototype(),
255 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
256 	}
257 	
258 	/**
259 	 * Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{B,C};}; B:class=A+{}; C:class=A+{};
260 	 * Class:class={};]; .
261 	 * 
262 	 * @throws Exception
263 	 *             Exception
264 	 */
265 	@Test
266 	public void testContainsInheritanceOverClassInheritanceAndSumSupertypeIsAnClass() throws Exception {
267 		final SimpleScannerInput input =
268 				new SimpleScannerInput("Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{B,C};}; "
269 						+ "B:class=A+{}; C:class=A+{}; Class:class={};];");
270 		final Model model = this.getModel(input);
271 		
272 		assertEquals(0, model.getAnything().getSuperTypes().size());
273 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
274 		
275 		final ClassType clss = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
276 		final Iterator<Attribute> attrIterator = clss.getAttributes().iterator();
277 		final Attribute attr1 = attrIterator.next();
278 		final Attribute attr2 = attrIterator.next();
279 		
280 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
281 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
282 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
283 		assertEquals(1, supertypesAttr1.size());
284 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
285 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
286 		
287 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
288 		final Collection<Type> supertypesAttr2 =
289 				((SumType) ((SumType) attr2.getAttrType()).getPrototype()).getSuperTypes();
290 		assertEquals(1, supertypesAttr2.size());
291 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
292 		assertEquals(clss, HelperUtils.getReferencedType(superTypesAttr2Iterator.next()));
293 		
294 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
295 		assertEquals(
296 				attr1Type,
297 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
298 		
299 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
300 		assertEquals(
301 				attr1Type,
302 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
303 	}
304 	
305 	/**
306 	 * Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{String,C};}; B:class=A+{}; C:class=A+{};
307 	 * Class:class={};]; .
308 	 * 
309 	 * @throws Exception
310 	 *             Exception
311 	 */
312 	@Test
313 	public void testContainsInheritanceOverClassInheritance2() throws Exception {
314 		final SimpleScannerInput input =
315 				new SimpleScannerInput("Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{String,C};}; "
316 						+ "B:class=A+{}; C:class=A+{}; Class:class={};];");
317 		final Model model = this.getModel(input);
318 		
319 		assertEquals(0, model.getAnything().getSuperTypes().size());
320 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
321 		
322 		final ClassType clss = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
323 		final Iterator<Attribute> attrIterator = clss.getAttributes().iterator();
324 		final Attribute attr1 = attrIterator.next();
325 		final Attribute attr2 = attrIterator.next();
326 		
327 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
328 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
329 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
330 		assertEquals(1, supertypesAttr1.size());
331 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
332 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
333 		
334 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
335 		final Collection<Type> supertypesAttr2 =
336 				((SumType) ((SumType) attr2.getAttrType()).getPrototype()).getSuperTypes();
337 		assertEquals(1, supertypesAttr2.size());
338 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
339 		assertEquals(attr1Type, superTypesAttr2Iterator.next());
340 		
341 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
342 		assertEquals(
343 				attr1Type,
344 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
345 		
346 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
347 		assertEquals(
348 				attr2.getAttrType().getPrototype(),
349 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
350 	}
351 	
352 	/**
353 	 * Group:group=[A:class={Attribute1:{A,B,C}; Attribute2:{A,B}; Attribute3:{B,C}; Attribute4:{A,C};}; B:class=A+{};
354 	 * C:class=A+{}; Class:class={};]; .
355 	 * 
356 	 * @throws Exception
357 	 *             Exception
358 	 */
359 	@Test
360 	public void testNormalContainsInheritance3() throws Exception {
361 		final SimpleScannerInput input =
362 				new SimpleScannerInput("Group:group=[A:class={Attribute1:{A,B,C}; Attribute2:{A,B}; Attribute3:{B,C}; "
363 						+ "Attribute4:{A,C};}; B:class={}; C:class={}; Class:class={};];");
364 		final Model model = this.getModel(input);
365 		
366 		assertEquals(0, model.getAnything().getSuperTypes().size());
367 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
368 		
369 		final ClassType clss = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
370 		final Iterator<Attribute> attrIterator = clss.getAttributes().iterator();
371 		final Attribute attr1 = attrIterator.next();
372 		final Attribute attr2 = attrIterator.next();
373 		final Attribute attr3 = attrIterator.next();
374 		final Attribute attr4 = attrIterator.next();
375 		
376 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
377 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
378 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
379 		assertEquals(1, supertypesAttr1.size());
380 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
381 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
382 		
383 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
384 		final Collection<Type> supertypesAttr2 =
385 				((SumType) ((SumType) attr2.getAttrType()).getPrototype()).getSuperTypes();
386 		assertEquals(1, supertypesAttr2.size());
387 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
388 		assertEquals(attr1Type, superTypesAttr2Iterator.next());
389 		
390 		assertEquals(0, ((SumType) attr3.getAttrType()).getSuperTypes().size());
391 		final Collection<Type> supertypesAttr3 =
392 				((SumType) ((SumType) attr3.getAttrType()).getPrototype()).getSuperTypes();
393 		assertEquals(1, supertypesAttr3.size());
394 		final Iterator<Type> superTypesAttr3Iterator = supertypesAttr3.iterator();
395 		assertEquals(attr1Type, superTypesAttr3Iterator.next());
396 		
397 		assertEquals(0, ((SumType) attr4.getAttrType()).getSuperTypes().size());
398 		final Collection<Type> supertypesAttr4 =
399 				((SumType) ((SumType) attr4.getAttrType()).getPrototype()).getSuperTypes();
400 		assertEquals(1, supertypesAttr4.size());
401 		final Iterator<Type> superTypesAttr4Iterator = supertypesAttr4.iterator();
402 		assertEquals(attr1Type, superTypesAttr4Iterator.next());
403 		
404 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
405 		assertEquals(
406 				model.getAnything().getPrototype(),
407 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
408 		
409 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
410 		assertEquals(
411 				model.getAnything().getPrototype(),
412 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
413 	}
414 	
415 	/**
416 	 * Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{C,D,E};}; B:class=A+{}; C:class=A+{};
417 	 * Class:class={}; D:class=B+{}; E:class=B+{};]; .
418 	 * 
419 	 * @throws Exception
420 	 *             Exception
421 	 */
422 	@Test
423 	public void testSumSupertypeIsAnClass() throws Exception {
424 		final SimpleScannerInput input =
425 				new SimpleScannerInput("Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{B,C};}; "
426 						+ "B:class=A+{}; C:class=A+{}; Class:class={};];");
427 		final Model model = this.getModel(input);
428 		
429 		assertEquals(0, model.getAnything().getSuperTypes().size());
430 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
431 		
432 		final ClassType clss = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
433 		final Iterator<Attribute> attrIterator = clss.getAttributes().iterator();
434 		final Attribute attr1 = attrIterator.next();
435 		final Attribute attr2 = attrIterator.next();
436 		
437 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
438 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
439 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
440 		assertEquals(1, supertypesAttr1.size());
441 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
442 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
443 		
444 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
445 		final Collection<Type> supertypesAttr2 =
446 				((SumType) ((SumType) attr2.getAttrType()).getPrototype()).getSuperTypes();
447 		assertEquals(1, supertypesAttr2.size());
448 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
449 		assertEquals(clss, HelperUtils.getReferencedType(superTypesAttr2Iterator.next()));
450 		
451 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
452 		assertEquals(
453 				attr1Type,
454 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
455 		
456 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
457 		assertEquals(
458 				attr1Type,
459 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
460 	}
461 	
462 	/**
463 	 * Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{B,C};}; B:class=A+{}; C:class=A+{};
464 	 * D:class=A+{}; Class:class={};]; .
465 	 * 
466 	 * @throws Exception
467 	 *             Exception
468 	 */
469 	@Test
470 	public void testSumSupertypeIsAnClass2() throws Exception {
471 		final SimpleScannerInput input =
472 				new SimpleScannerInput("Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{B,C};}; "
473 						+ "B:class=A+{}; C:class=A+{}; D:class=A+{}; Class:class={};];");
474 		final Model model = this.getModel(input);
475 		
476 		assertEquals(0, model.getAnything().getSuperTypes().size());
477 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
478 		
479 		final ClassType clss = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
480 		final Iterator<Attribute> attrIterator = clss.getAttributes().iterator();
481 		final Attribute attr1 = attrIterator.next();
482 		final Attribute attr2 = attrIterator.next();
483 		
484 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
485 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
486 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
487 		assertEquals(1, supertypesAttr1.size());
488 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
489 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
490 		
491 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
492 		final Collection<Type> supertypesAttr2 =
493 				((SumType) ((SumType) attr2.getAttrType()).getPrototype()).getSuperTypes();
494 		assertEquals(1, supertypesAttr2.size());
495 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
496 		assertEquals(clss, HelperUtils.getReferencedType(superTypesAttr2Iterator.next()));
497 		
498 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
499 		assertEquals(
500 				attr1Type,
501 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
502 		
503 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
504 		assertEquals(
505 				attr1Type,
506 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
507 	}
508 	
509 	/**
510 	 * Group:group=[A:class={ Attribute1:{B,C};}; B:class=A+{}; C:class=A+{}; Class:class={};]; .
511 	 * 
512 	 * @throws Exception
513 	 *             Exception
514 	 */
515 	@Test
516 	public void testSumSupertypeIsAnClass3() throws Exception {
517 		final SimpleScannerInput input =
518 				new SimpleScannerInput("Group:group=[A:class={ Attribute1:{B,C};}; "
519 						+ "B:class=A+{}; C:class=A+{}; Class:class={};];");
520 		final Model model = this.getModel(input);
521 		
522 		assertEquals(0, model.getAnything().getSuperTypes().size());
523 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
524 		
525 		final ClassType clss = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
526 		final Iterator<Attribute> attrIterator = clss.getAttributes().iterator();
527 		final Attribute attr1 = attrIterator.next();
528 		
529 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
530 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
531 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
532 		assertEquals(1, supertypesAttr1.size());
533 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
534 		assertEquals(clss, HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
535 		
536 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
537 		assertEquals(
538 				model.getAnything().getPrototype(),
539 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
540 		
541 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
542 		assertEquals(
543 				model.getAnything().getPrototype(),
544 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
545 	}
546 	
547 	/**
548 	 * Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{String,A}; Attribute3:{B,C};}; B:class=A+{};
549 	 * C:class=A+{}; Class:class={};]; .
550 	 * 
551 	 * @throws Exception
552 	 *             Exception
553 	 */
554 	@Test
555 	public void testTransitiveInheritance() throws Exception {
556 		final SimpleScannerInput input =
557 				new SimpleScannerInput("Group:group=[A:class={Attribute1:{String,Integer,A}; Attribute2:{String,A}; "
558 						+ "Attribute3:{B,C};}; B:class=A+{}; C:class=A+{}; Class:class={};];");
559 		final Model model = this.getModel(input);
560 		
561 		assertEquals(0, model.getAnything().getSuperTypes().size());
562 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
563 		
564 		final ClassType clss = (ClassType) model.getGroups().iterator().next().getGroupElements().iterator().next();
565 		final Iterator<Attribute> attrIterator = clss.getAttributes().iterator();
566 		final Attribute attr1 = attrIterator.next();
567 		final Attribute attr2 = attrIterator.next();
568 		final Attribute attr3 = attrIterator.next();
569 		
570 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
571 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
572 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
573 		assertEquals(1, supertypesAttr1.size());
574 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
575 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
576 		
577 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
578 		final Type attr2Type = ((SumType) attr2.getAttrType()).getPrototype();
579 		final Collection<Type> supertypesAttr2 = attr2Type.getSuperTypes();
580 		assertEquals(1, supertypesAttr2.size());
581 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
582 		assertEquals(attr1Type, superTypesAttr2Iterator.next());
583 		
584 		assertEquals(0, ((SumType) attr3.getAttrType()).getSuperTypes().size());
585 		final Collection<Type> supertypesAttr3 =
586 				((SumType) ((SumType) attr3.getAttrType()).getPrototype()).getSuperTypes();
587 		assertEquals(1, supertypesAttr3.size());
588 		final Iterator<Type> superTypesAttr3Iterator = supertypesAttr3.iterator();
589 		assertEquals(clss, HelperUtils.getReferencedType(superTypesAttr3Iterator.next()));
590 		
591 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
592 		assertEquals(
593 				attr1Type,
594 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
595 		
596 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
597 		assertEquals(
598 				attr2Type,
599 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
600 	}
601 	
602 	/**
603 	 * Group:group=[A:class={Attribute1:{}; Attribute2:{String,A}; Attribute3:{Integer,String};}; B:class=A+{};
604 	 * C:class=A+{}; Class:class={};]; .
605 	 * 
606 	 * @throws Exception
607 	 *             Exception
608 	 */
609 	@Test
610 	public void testEmptySum() throws Exception {
611 		final SimpleScannerInput input =
612 				new SimpleScannerInput(" Group:group=[A:class={Attribute1:{}; Attribute2:{String,A}; "
613 						+ "Attribute3:{Integer,String};}; B:class=A+{}; C:class=A+{}; Class:class={};];");
614 		final Model model = this.getModel(input);
615 		
616 		assertEquals(0, model.getAnything().getSuperTypes().size());
617 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
618 		
619 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
620 		
621 		final ClassType clssA = (ClassType) iterator.next();
622 		final ClassType clssB = (ClassType) iterator.next();
623 		final ClassType clssC = (ClassType) iterator.next();
624 		final ClassType clssClass = (ClassType) iterator.next();
625 		
626 		final Iterator<Attribute> attrIterator = clssA.getAttributes().iterator();
627 		final Attribute attr1 = attrIterator.next();
628 		final Attribute attr2 = attrIterator.next();
629 		final Attribute attr3 = attrIterator.next();
630 		
631 		final Type attr2Type = ((SumType) attr2.getAttrType()).getPrototype();
632 		final Type attr3Type = ((SumType) attr3.getAttrType()).getPrototype();
633 		
634 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
635 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
636 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
637 		assertEquals(4, supertypesAttr1.size());
638 		final Set<Type> actualSupertypes = new HashSet<>();
639 		for (final Type type : supertypesAttr1) {
640 			actualSupertypes.add(HelperUtils.getReferencedType(type));
641 		}
642 		final Set<Type> expectedSupertypes1 = new HashSet<>();
643 		expectedSupertypes1.add(clssC);
644 		expectedSupertypes1.add(clssB);
645 		expectedSupertypes1.add(clssClass);
646 		expectedSupertypes1.add(attr3Type);
647 		assertEquals(expectedSupertypes1, actualSupertypes);
648 		
649 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
650 		final Collection<Type> supertypesAttr2 = attr2Type.getSuperTypes();
651 		assertEquals(1, supertypesAttr2.size());
652 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
653 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr2Iterator.next()));
654 		
655 		assertEquals(0, ((SumType) attr3.getAttrType()).getSuperTypes().size());
656 		final Collection<Type> supertypesAttr3 =
657 				((SumType) ((SumType) attr3.getAttrType()).getPrototype()).getSuperTypes();
658 		assertEquals(1, supertypesAttr3.size());
659 		final Iterator<Type> superTypesAttr3Iterator = supertypesAttr3.iterator();
660 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr3Iterator.next()));
661 		
662 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
663 		assertEquals(
664 				attr3Type,
665 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
666 		
667 		final Collection<Type> expectedSupertypes = new ArrayList<>();
668 		expectedSupertypes.add(attr3Type);
669 		expectedSupertypes.add(attr2Type);
670 		
671 		this.checkSupertypes(expectedSupertypes, model.getString().getPrototype().getSuperTypes());
672 	}
673 	
674 	/**
675 	 * Group:group=[A:class={Attribute1:{}; Attribute2:{String,A,Anything}; Attribute3:{Integer,String};}; B:class=A+{};
676 	 * C:class=A+{}; Class:class={};]; .
677 	 * 
678 	 * @throws Exception
679 	 *             Exception
680 	 */
681 	@Test
682 	public void testEmptySum2() throws Exception {
683 		final SimpleScannerInput input =
684 				new SimpleScannerInput(" Group:group=[A:class={Attribute1:{}; Attribute2:{String,A,Anything}; "
685 						+ "Attribute3:{Integer,String};}; B:class=A+{}; C:class=A+{}; Class:class={};];");
686 		final Model model = this.getModel(input);
687 		
688 		assertEquals(0, model.getAnything().getSuperTypes().size());
689 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
690 		
691 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
692 		
693 		final ClassType clssA = (ClassType) iterator.next();
694 		final ClassType clssB = (ClassType) iterator.next();
695 		final ClassType clssC = (ClassType) iterator.next();
696 		final ClassType clssClass = (ClassType) iterator.next();
697 		
698 		final Iterator<Attribute> attrIterator = clssA.getAttributes().iterator();
699 		final Attribute attr1 = attrIterator.next();
700 		final Attribute attr2 = attrIterator.next();
701 		final Attribute attr3 = attrIterator.next();
702 		
703 		final Type attr3Type = ((SumType) attr3.getAttrType()).getPrototype();
704 		
705 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
706 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
707 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
708 		assertEquals(4, supertypesAttr1.size());
709 		final Set<Type> actualSupertypes = new HashSet<>();
710 		for (final Type type : supertypesAttr1) {
711 			actualSupertypes.add(HelperUtils.getReferencedType(type));
712 		}
713 		final Set<Type> expectedSupertypes = new HashSet<>();
714 		expectedSupertypes.add(clssC);
715 		expectedSupertypes.add(clssB);
716 		expectedSupertypes.add(clssClass);
717 		expectedSupertypes.add(attr3Type);
718 		assertEquals(expectedSupertypes, actualSupertypes);
719 		
720 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
721 		final Collection<Type> supertypesAttr2 =
722 				((SumType) ((SumType) attr2.getAttrType()).getPrototype()).getSuperTypes();
723 		assertEquals(0, supertypesAttr2.size());
724 		
725 		assertEquals(0, ((SumType) attr3.getAttrType()).getSuperTypes().size());
726 		final Collection<Type> supertypesAttr3 =
727 				((SumType) ((SumType) attr3.getAttrType()).getPrototype()).getSuperTypes();
728 		assertEquals(1, supertypesAttr3.size());
729 		final Iterator<Type> superTypesAttr3Iterator = supertypesAttr3.iterator();
730 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(superTypesAttr3Iterator.next()));
731 		
732 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
733 		assertEquals(
734 				attr3Type,
735 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
736 		
737 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
738 		assertEquals(
739 				attr3Type,
740 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
741 	}
742 	
743 	/**
744 	 * Group:group=[A:class={Attribute1:{C,D};}; B:class=A+{}; C:class=B+{}; D:class=B+{}; Class:class={};]; .
745 	 * 
746 	 * @throws Exception
747 	 *             Exception
748 	 */
749 	@Test
750 	public void testTransitiveInheritanceAndSumSupertypeIsClass() throws Exception {
751 		final SimpleScannerInput input =
752 				new SimpleScannerInput("Group:group=[A:class={Attribute1:{C,D};}; B:class=A+{}; C:class=B+{}; "
753 						+ "D:class=B+{}; Class:class={};];");
754 		final Model model = this.getModel(input);
755 		
756 		assertEquals(0, model.getAnything().getSuperTypes().size());
757 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
758 		
759 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
760 		final ClassType clssA = (ClassType) iterator.next();
761 		final ClassType clssB = (ClassType) iterator.next();
762 		
763 		final Iterator<Attribute> attrIterator = clssA.getAttributes().iterator();
764 		
765 		final Attribute attr1 = attrIterator.next();
766 		
767 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
768 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
769 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
770 		assertEquals(1, supertypesAttr1.size());
771 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
772 		assertEquals(clssB, HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
773 		
774 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
775 		assertEquals(
776 				model.getAnything().getPrototype(),
777 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
778 		
779 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
780 		assertEquals(
781 				model.getAnything().getPrototype(),
782 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
783 	}
784 	
785 	/**
786 	 * Group:group=[A:class={Attribute1:{B,C}; Attribute2:{D,E,F,G};}; B:class=A+{}; C:class=A+{}; D:class=B+{};
787 	 * E:class=B+{}; F:class=C+{}; G:class=C+{}; Class:class={};]; .
788 	 * 
789 	 * @throws Exception
790 	 *             Exception
791 	 */
792 	@Test
793 	public void testTransitiveInheritanceAndSumSupertypeIsClass2() throws Exception {
794 		final SimpleScannerInput input =
795 				new SimpleScannerInput("Group:group=[A:class={Attribute1:{B,C}; Attribute2:{D,E,F,G};}; B:class=A+{}; "
796 						+ "C:class=A+{}; D:class=B+{}; E:class=B+{}; F:class=C+{}; G:class=C+{}; Class:class={};];");
797 		final Model model = this.getModel(input);
798 		
799 		assertEquals(0, model.getAnything().getSuperTypes().size());
800 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
801 		
802 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
803 		final ClassType clssA = (ClassType) iterator.next();
804 		
805 		final Iterator<Attribute> attrIterator = clssA.getAttributes().iterator();
806 		
807 		final Attribute attr1 = attrIterator.next();
808 		final Attribute attr2 = attrIterator.next();
809 		
810 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
811 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
812 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
813 		assertEquals(1, supertypesAttr1.size());
814 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
815 		assertEquals(clssA, HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
816 		
817 		assertEquals(0, ((SumType) attr2.getAttrType()).getSuperTypes().size());
818 		final Type attr2Type = ((SumType) attr2.getAttrType()).getPrototype();
819 		final Collection<Type> supertypesAttr2 = ((SumType) attr2Type).getSuperTypes();
820 		assertEquals(1, supertypesAttr2.size());
821 		final Iterator<Type> superTypesAttr2Iterator = supertypesAttr2.iterator();
822 		assertEquals(attr1Type, superTypesAttr2Iterator.next());
823 		
824 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
825 		assertEquals(
826 				model.getAnything().getPrototype(),
827 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
828 		
829 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
830 		assertEquals(
831 				model.getAnything().getPrototype(),
832 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
833 	}
834 	
835 	/**
836 	 * Group:group=[A:class={Attribute1:{C,D};}; B:class=A+{}; C:class=B+{}; D:class=B+{}; Class:class={};]; .
837 	 * 
838 	 * @throws Exception
839 	 *             Exception
840 	 */
841 	@Test
842 	public void testTransitiveInheritanceAndSumSupertypeIsClass3() throws Exception {
843 		final SimpleScannerInput input =
844 				new SimpleScannerInput("Group:group=[A:class={Attribute1:{C,D};}; B:class=A+{}; C:class=B+{}; "
845 						+ "D:class=B+{}; Class:class={};];");
846 		final Model model = this.getModel(input);
847 		
848 		assertEquals(0, model.getAnything().getSuperTypes().size());
849 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
850 		
851 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
852 		final ClassType clssA = (ClassType) iterator.next();
853 		final ClassType clssB = (ClassType) iterator.next();
854 		
855 		final Iterator<Attribute> attrIterator = clssA.getAttributes().iterator();
856 		
857 		final Attribute attr1 = attrIterator.next();
858 		
859 		assertEquals(0, ((SumType) attr1.getAttrType()).getSuperTypes().size());
860 		final Type attr1Type = ((SumType) attr1.getAttrType()).getPrototype();
861 		final Collection<Type> supertypesAttr1 = ((SumType) attr1Type).getSuperTypes();
862 		assertEquals(1, supertypesAttr1.size());
863 		final Iterator<Type> superTypesAttr1Iterator = supertypesAttr1.iterator();
864 		assertEquals(clssB, HelperUtils.getReferencedType(superTypesAttr1Iterator.next()));
865 		
866 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
867 		assertEquals(
868 				model.getAnything().getPrototype(),
869 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
870 		
871 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
872 		assertEquals(
873 				model.getAnything().getPrototype(),
874 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
875 	}
876 	
877 	/**
878 	 * Group:group=[A:class={}; B:class=A+{}; C:class=B+{}; D:class=C+{}; ]; .
879 	 * 
880 	 * @throws Exception
881 	 *             Exception
882 	 */
883 	@Test
884 	public void testTransitiveInheritance2() throws Exception {
885 		final SimpleScannerInput input =
886 				new SimpleScannerInput("Group:group=[A:class={}; B:class=A+{}; C:class=B+A+{}; D:class=C+B+{}; ];");
887 		final Model model = this.getModel(input);
888 		
889 		assertEquals(0, model.getAnything().getSuperTypes().size());
890 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
891 		
892 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
893 		final ClassType clssA = (ClassType) iterator.next();
894 		final ClassType clssB = (ClassType) iterator.next();
895 		final ClassType clssC = (ClassType) iterator.next();
896 		final ClassType clssD = (ClassType) iterator.next();
897 		
898 		final Collection<Type> supertypesClassA = clssA.getSuperTypes();
899 		assertEquals(1, supertypesClassA.size());
900 		final Iterator<Type> supertypesClassAIterator = supertypesClassA.iterator();
901 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(supertypesClassAIterator.next()));
902 		
903 		final Collection<Type> supertypesClassB = clssB.getSuperTypes();
904 		assertEquals(1, supertypesClassB.size());
905 		final Iterator<Type> supertypesClassBIterator = supertypesClassB.iterator();
906 		assertEquals(clssA, HelperUtils.getReferencedType(supertypesClassBIterator.next()));
907 		
908 		final Collection<Type> supertypesClassC = clssC.getSuperTypes();
909 		assertEquals(1, supertypesClassC.size());
910 		final Iterator<Type> supertypesClassCIterator = supertypesClassC.iterator();
911 		assertEquals(clssB, HelperUtils.getReferencedType(supertypesClassCIterator.next()));
912 		
913 		final Collection<Type> supertypesClassD = clssD.getSuperTypes();
914 		assertEquals(1, supertypesClassD.size());
915 		final Iterator<Type> supertypesClassDIterator = supertypesClassD.iterator();
916 		assertEquals(clssC, HelperUtils.getReferencedType(supertypesClassDIterator.next()));
917 		
918 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
919 		assertEquals(
920 				model.getAnything().getPrototype(),
921 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
922 		
923 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
924 		assertEquals(
925 				model.getAnything().getPrototype(),
926 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
927 	}
928 	
929 	/**
930 	 * Group:group=[A:class={}; B:class=A+A+{}; ]; .
931 	 * 
932 	 * @throws Exception
933 	 *             Exception
934 	 */
935 	@Test
936 	public void testDuplicateInheritance() throws Exception {
937 		final SimpleScannerInput input = new SimpleScannerInput("Group:group=[A:class={}; B:class=A+A+{};];");
938 		final Model model = this.getModel(input);
939 		
940 		assertEquals(0, model.getAnything().getSuperTypes().size());
941 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
942 		
943 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
944 		final ClassType clssA = (ClassType) iterator.next();
945 		final ClassType clssB = (ClassType) iterator.next();
946 		
947 		final Collection<Type> supertypesClassA = clssA.getSuperTypes();
948 		assertEquals(1, supertypesClassA.size());
949 		final Iterator<Type> supertypesClassAIterator = supertypesClassA.iterator();
950 		assertEquals(model.getAnything().getPrototype(), HelperUtils.getReferencedType(supertypesClassAIterator.next()));
951 		
952 		final Collection<Type> supertypesClassB = clssB.getSuperTypes();
953 		assertEquals(1, supertypesClassB.size());
954 		final Iterator<Type> supertypesClassBIterator = supertypesClassB.iterator();
955 		assertEquals(clssA, HelperUtils.getReferencedType(supertypesClassBIterator.next()));
956 		
957 		assertEquals(1, model.getInteger().getPrototype().getSuperTypes().size());
958 		assertEquals(
959 				model.getAnything().getPrototype(),
960 				HelperUtils.getReferencedType(model.getInteger().getPrototype().getSuperTypes().iterator().next()));
961 		
962 		assertEquals(1, model.getString().getPrototype().getSuperTypes().size());
963 		assertEquals(
964 				model.getAnything().getPrototype(),
965 				HelperUtils.getReferencedType(model.getString().getPrototype().getSuperTypes().iterator().next()));
966 	}
967 	
968 	/**
969 	 * Group:group=[A:class={Attribute1:(name:String, alter: Integer, b:B, clss:Class);}; B:class=A+{}; C:class=B+{};
970 	 * D:class=B+{}; Class:class={};]; .
971 	 * 
972 	 * @throws Exception
973 	 *             Exception
974 	 */
975 	@Test
976 	public void testProductHierarchie() throws Exception {
977 		final SimpleScannerInput input =
978 				new SimpleScannerInput(
979 						"Group:group=[A:class={Attribute1:(name:String, alter: Integer, b:B, clss:Class);}; B:class=A+{}; C:class=B+{}; "
980 								+ "D:class=B+{}; Class:class={};];");
981 		final Model model = this.getModel(input);
982 		
983 		assertEquals(0, model.getAnything().getSuperTypes().size());
984 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
985 		
986 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
987 		final ClassType clssA = (ClassType) iterator.next();
988 		final ClassType clssB = (ClassType) iterator.next();
989 		iterator.next();
990 		iterator.next();
991 		final ClassType clss = (ClassType) iterator.next();
992 		
993 		final Iterator<Attribute> attrIterator = clssA.getAttributes().iterator();
994 		
995 		final Attribute attr1 = attrIterator.next();
996 		
997 		assertEquals(0, attr1.getAttrType().getSuperTypes().size());
998 		final Type attr1Type = attr1.getAttrType().getPrototype();
999 		final Collection<Type> supertypesAttr1 = attr1Type.getSuperTypes();
1000 		
1001 		final Collection<Type> expectedSupertypes = new ArrayList<>();
1002 		final ProductType abstrProductCreated = ProductType.create(DummyToken.getInstance(), DummyToken.getInstance());
1003 		ByReferenceState state = ByReferenceState.create(model.getString(), model.getString().getTypeName());
1004 		TypeProxy typeProxy = TypeProxy.create(DummyToken.getInstance(), state);
1005 		abstrProductCreated.addElement(ProductElementType.create("p$1", typeProxy, DummyToken.getInstance()));
1006 		state = ByReferenceState.create(model.getInteger(), model.getInteger().getTypeName());
1007 		typeProxy = TypeProxy.create(DummyToken.getInstance(), state);
1008 		abstrProductCreated.addElement(ProductElementType.create("p$2", typeProxy, DummyToken.getInstance()));
1009 		state = ByReferenceState.create(clssB, clssB.getName());
1010 		typeProxy = TypeProxy.create(DummyToken.getInstance(), state);
1011 		abstrProductCreated.addElement(ProductElementType.create("p$3", typeProxy, DummyToken.getInstance()));
1012 		final ByReferenceState state2 = ByReferenceState.create(clss, clss.getName());
1013 		final TypeProxy typeProxy2 = TypeProxy.create(DummyToken.getInstance(), state2);
1014 		abstrProductCreated.addElement(ProductElementType.create("p$4", typeProxy2, DummyToken.getInstance()));
1015 		expectedSupertypes.add(abstrProductCreated);
1016 		
1017 		this.checkSupertypes(expectedSupertypes, supertypesAttr1);
1018 		
1019 		assertEquals(1, clssA.getSuperTypes().size());
1020 		assertEquals(1, clssB.getSuperTypes().size());
1021 		assertEquals(1, model.getString().getSuperTypes().size());
1022 		assertEquals(1, model.getInteger().getSuperTypes().size());
1023 		
1024 	}
1025 	
1026 	/**
1027 	 * Group:group=[A:class={Attribute1:(p1:String, p2: Integer, p3:B, p4:Class);}; B:class=A+{}; C:class=B+{};
1028 	 * D:class=B+{}; Class:class={};]; .
1029 	 * 
1030 	 * @throws Exception
1031 	 *             Exception
1032 	 */
1033 	@Test
1034 	public void testProductHierarchie2() throws Exception {
1035 		final SimpleScannerInput input =
1036 				new SimpleScannerInput(
1037 						"Group:group=[A:class={Attribute1:(p1:String, p2: Integer, p3:B, p4:Class);}; B:class=A+{}; C:class=B+{}; "
1038 								+ "D:class=B+{}; Class:class={};];");
1039 		final Model model = this.getModel(input);
1040 		
1041 		assertEquals(0, model.getAnything().getSuperTypes().size());
1042 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
1043 		
1044 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
1045 		final ClassType clssA = (ClassType) iterator.next();
1046 		final ClassType clssB = (ClassType) iterator.next();
1047 		
1048 		final Iterator<Attribute> attrIterator = clssA.getAttributes().iterator();
1049 		
1050 		final Attribute attr1 = attrIterator.next();
1051 		
1052 		assertEquals(0, attr1.getAttrType().getSuperTypes().size());
1053 		final Type attr1Type = attr1.getAttrType().getPrototype();
1054 		final Collection<Type> supertypesAttr1 = attr1Type.getSuperTypes();
1055 		
1056 		final Collection<Type> expectedSupertypes = new ArrayList<>();
1057 		expectedSupertypes.add(((ProductType) attr1Type).getAbstractPrototype());
1058 		
1059 		this.checkSupertypes(expectedSupertypes, supertypesAttr1);
1060 		
1061 		assertEquals(1, clssA.getSuperTypes().size());
1062 		assertEquals(1, clssB.getSuperTypes().size());
1063 		assertEquals(1, model.getString().getSuperTypes().size());
1064 		assertEquals(1, model.getInteger().getSuperTypes().size());
1065 	}
1066 	
1067 	/**
1068 	 * Group:group=[A:class={Attribute1:{(name:String, alter: Integer, b:B, clss:Class),String};}; B:class=A+{};
1069 	 * C:class=B+{}; D:class=B+{}; Class:class={};]; .
1070 	 * 
1071 	 * @throws Exception
1072 	 *             Exception
1073 	 */
1074 	@Test
1075 	public void testProductHierarchie3() throws Exception {
1076 		final SimpleScannerInput input =
1077 				new SimpleScannerInput(
1078 						"Group:group=[A:class={Attribute1:{(name:String, alter: Integer, b:B, clss:Class),String};}; B:class=A+{}; C:class=B+{}; "
1079 								+ "D:class=B+{}; Class:class={};];");
1080 		final Model model = this.getModel(input);
1081 		
1082 		assertEquals(0, model.getAnything().getSuperTypes().size());
1083 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
1084 		
1085 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
1086 		final ClassType clssA = (ClassType) iterator.next();
1087 		final ClassType clssB = (ClassType) iterator.next();
1088 		iterator.next();
1089 		iterator.next();
1090 		final ClassType clss = (ClassType) iterator.next();
1091 		
1092 		final Iterator<Attribute> attrIterator = clssA.getAttributes().iterator();
1093 		
1094 		final Attribute attr1 = attrIterator.next();
1095 		
1096 		// Summe
1097 		assertEquals(0, attr1.getAttrType().getSuperTypes().size());
1098 		final Type attr1Type = attr1.getAttrType().getPrototype();
1099 		final Collection<Type> supertypesAttr1 = attr1Type.getSuperTypes();
1100 		
1101 		Collection<Type> expectedSupertypes = new ArrayList<>();
1102 		expectedSupertypes.add(model.getAnything().getPrototype());
1103 		
1104 		this.checkSupertypes(expectedSupertypes, supertypesAttr1);
1105 		
1106 		// Product
1107 		final SumType sum = (SumType) attr1Type;
1108 		final Iterator<Type> iterator2 = sum.getElements().iterator();
1109 		iterator2.next();
1110 		final ProductType productPrototyp = (ProductType) iterator2.next();
1111 		
1112 		expectedSupertypes = new ArrayList<>();
1113 		final ProductType abstrProductCreated = ProductType.create(DummyToken.getInstance(), DummyToken.getInstance());
1114 		ByReferenceState state = ByReferenceState.create(model.getString(), model.getString().getTypeName());
1115 		TypeProxy typeProxy = TypeProxy.create(DummyToken.getInstance(), state);
1116 		abstrProductCreated.addElement(ProductElementType.create("p$1", typeProxy, DummyToken.getInstance()));
1117 		state = ByReferenceState.create(model.getInteger(), model.getInteger().getTypeName());
1118 		typeProxy = TypeProxy.create(DummyToken.getInstance(), state);
1119 		abstrProductCreated.addElement(ProductElementType.create("p$2", typeProxy, DummyToken.getInstance()));
1120 		state = ByReferenceState.create(clssB, clssB.getName());
1121 		typeProxy = TypeProxy.create(DummyToken.getInstance(), state);
1122 		abstrProductCreated.addElement(ProductElementType.create("p$3", typeProxy, DummyToken.getInstance()));
1123 		final ByReferenceState state2 = ByReferenceState.create(clss, clss.getName());
1124 		final TypeProxy typeProxy2 = TypeProxy.create(DummyToken.getInstance(), state2);
1125 		abstrProductCreated.addElement(ProductElementType.create("p$4", typeProxy2, DummyToken.getInstance()));
1126 		expectedSupertypes.add(abstrProductCreated);
1127 		expectedSupertypes.add(sum);
1128 		
1129 		this.checkSupertypes(expectedSupertypes, productPrototyp.getSuperTypes());
1130 		
1131 		assertEquals(1, clssA.getSuperTypes().size());
1132 		assertEquals(1, model.getString().getSuperTypes().size());
1133 		assertEquals(1, model.getInteger().getSuperTypes().size());
1134 	}
1135 	
1136 	/**
1137 	 * Group:group=[A:class={Attribute1:{(name:String, alter: Integer, b:B, clss:Class),(p1:String, p2: Integer, p3:B,
1138 	 * p4:Class)};}; B:class=A+{}; C:class=B+{}; D:class=B+{}; Class:class={};]; .
1139 	 * 
1140 	 * @throws Exception
1141 	 *             Exception
1142 	 */
1143 	@Test
1144 	public void testProductHierarchie4() throws Exception {
1145 		final SimpleScannerInput input =
1146 				new SimpleScannerInput(
1147 						"Group:group=[A:class={Attribute1:{(name:String, alter: Integer, b:B, clss:Class),(p1:String, p2: Integer, p3:B, p4:Class)};}; B:class=A+{}; C:class=B+{}; "
1148 								+ "D:class=B+{}; Class:class={};];");
1149 		final Model model = this.getModel(input);
1150 		
1151 		assertEquals(0, model.getAnything().getSuperTypes().size());
1152 		assertEquals(0, ((SumType) model.getAnything().getPrototype()).getSuperTypes().size());
1153 		
1154 		final Iterator<GroupElement> iterator = model.getGroups().iterator().next().getGroupElements().iterator();
1155 		final ClassType clssA = (ClassType) iterator.next();
1156 		final ClassType clssB = (ClassType) iterator.next();
1157 		iterator.next();
1158 		iterator.next();
1159 		final ClassType clss = (ClassType) iterator.next();
1160 		
1161 		final Iterator<Attribute> attrIterator = clssA.getAttributes().iterator();
1162 		
1163 		final Attribute attr1 = attrIterator.next();
1164 		
1165 		// Summe
1166 		assertEquals(0, attr1.getAttrType().getSuperTypes().size());
1167 		final Type attr1Type = attr1.getAttrType().getPrototype();
1168 		final Collection<Type> supertypesAttr1 = attr1Type.getSuperTypes();
1169 		
1170 		Collection<Type> expectedSupertypes = new ArrayList<>();
1171 		expectedSupertypes.add(model.getAnything().getPrototype());
1172 		
1173 		this.checkSupertypes(expectedSupertypes, supertypesAttr1);
1174 		
1175 		// Produkte
1176 		final SumType sum = (SumType) attr1Type;
1177 		final Iterator<Type> iterator2 = sum.getElements().iterator();
1178 		final ProductType productPrototyp = (ProductType) iterator2.next();
1179 		final ProductType productPrototyp2 = (ProductType) iterator2.next();
1180 		
1181 		expectedSupertypes = new ArrayList<>();
1182 		final ProductType abstrProductCreated = ProductType.create(DummyToken.getInstance(), DummyToken.getInstance());
1183 		ByReferenceState state = ByReferenceState.create(model.getString(), model.getString().getTypeName());
1184 		TypeProxy typeProxy = TypeProxy.create(DummyToken.getInstance(), state);
1185 		abstrProductCreated.addElement(ProductElementType.create("p$1", typeProxy, DummyToken.getInstance()));
1186 		state = ByReferenceState.create(model.getInteger(), model.getInteger().getTypeName());
1187 		typeProxy = TypeProxy.create(DummyToken.getInstance(), state);
1188 		abstrProductCreated.addElement(ProductElementType.create("p$2", typeProxy, DummyToken.getInstance()));
1189 		state = ByReferenceState.create(clssB, clssB.getName());
1190 		typeProxy = TypeProxy.create(DummyToken.getInstance(), state);
1191 		abstrProductCreated.addElement(ProductElementType.create("p$3", typeProxy, DummyToken.getInstance()));
1192 		final ByReferenceState state2 = ByReferenceState.create(clss, clss.getName());
1193 		final TypeProxy typeProxy2 = TypeProxy.create(DummyToken.getInstance(), state2);
1194 		abstrProductCreated.addElement(ProductElementType.create("p$4", typeProxy2, DummyToken.getInstance()));
1195 		expectedSupertypes.add(abstrProductCreated);
1196 		expectedSupertypes.add(sum);
1197 		
1198 		this.checkSupertypes(expectedSupertypes, productPrototyp.getSuperTypes());
1199 		
1200 		expectedSupertypes = new ArrayList<>();
1201 		expectedSupertypes.add(sum);
1202 		expectedSupertypes.add(abstrProductCreated);
1203 		
1204 		this.checkSupertypes(expectedSupertypes, productPrototyp2.getSuperTypes());
1205 		
1206 		assertEquals(1, clssA.getSuperTypes().size());
1207 		assertEquals(1, model.getString().getSuperTypes().size());
1208 		assertEquals(1, model.getInteger().getSuperTypes().size());
1209 	}
1210 	
1211 	/**
1212 	 * Assert Equality of expectedSupertypes and supertypes.
1213 	 * 
1214 	 * @param expectedSupertypes
1215 	 *            expectedSupertypes
1216 	 * @param supertypes
1217 	 *            supertypes
1218 	 */
1219 	private void checkSupertypes(final Collection<Type> expectedSupertypes, final Collection<Type> supertypes) {
1220 		assertEquals(expectedSupertypes.size(), supertypes.size());
1221 		for (final Type type : supertypes) {
1222 			assertTrue(expectedSupertypes.remove(HelperUtils.getReferencedType(type)));
1223 		}
1224 	}
1225 	
1226 }