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