View Javadoc
1   package de.fhdw.wtf.common.ast.type.test;
2   
3   import java.util.ArrayList;
4   import java.util.Iterator;
5   import java.util.List;
6   
7   import junit.framework.TestCase;
8   
9   import org.junit.Test;
10  
11  import de.fhdw.wtf.common.ast.Group;
12  import de.fhdw.wtf.common.ast.Model;
13  import de.fhdw.wtf.common.ast.UnqualifiedName;
14  import de.fhdw.wtf.common.ast.type.AtomicType;
15  import de.fhdw.wtf.common.ast.type.ByNameState;
16  import de.fhdw.wtf.common.ast.type.ClassType;
17  import de.fhdw.wtf.common.ast.type.CompositeType;
18  import de.fhdw.wtf.common.ast.type.ListType;
19  import de.fhdw.wtf.common.ast.type.MapType;
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.ThrownType;
24  import de.fhdw.wtf.common.ast.type.Type;
25  import de.fhdw.wtf.common.ast.type.TypeProxy;
26  import de.fhdw.wtf.common.ast.visitor.CompositeTypeVisitorReturn;
27  import de.fhdw.wtf.common.ast.visitor.TypeVisitorReturn;
28  import de.fhdw.wtf.common.exception.ast.ASTException;
29  import de.fhdw.wtf.common.exception.parser.SumIsAnythingException;
30  import de.fhdw.wtf.common.token.DummyToken;
31  import de.fhdw.wtf.common.token.IdentifierToken;
32  import de.fhdw.wtf.common.token.Position;
33  import de.fhdw.wtf.common.token.Token;
34  import de.fhdw.wtf.tooling.SyntaxCheck;
35  
36  /**
37   * Tests for Method standardizeElements in {@link de.fhdw.wtf.common.exception.parser.SumType}.
38   */
39  public class StandardizeSumsTest extends TestCase {
40  	
41  	/**
42  	 * A > B und A > C. {A,B,C} => {A}
43  	 * 
44  	 * @throws Exception
45  	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
46  	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
47  	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
48  	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
49  	 *             {@link java.util.concurrent.ExecutionException}
50  	 */
51  	@Test
52  	public void testClass1() throws Exception {
53  		final String input =
54  				"Group:group=[Klasse:class={(); summe:{A,B,C};}; A:class={();}; B:class=A+{()=A();}; C:class=A+{()=A();};];";
55  		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
56  		final Group group = model.getGroups().iterator().next();
57  		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
58  		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
59  		
60  		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
61  			
62  			@Override
63  			public List<Type> handle(final AtomicType atomicType) {
64  				return new ArrayList<>();
65  			}
66  			
67  			@Override
68  			public List<Type> handle(final CompositeType compositeType) {
69  				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
70  					
71  					@Override
72  					public List<Type> handle(final ListType list) {
73  						return new ArrayList<>();
74  					}
75  					
76  					@Override
77  					public List<Type> handle(final MapType map) {
78  						return new ArrayList<>();
79  					}
80  					
81  					@Override
82  					public List<Type> handle(final ProductType product) {
83  						return new ArrayList<>();
84  					}
85  					
86  					@Override
87  					public List<Type> handle(final SumType sum2) {
88  						return sum2.getElements();
89  					}
90  					
91  					@Override
92  					public List<Type> handle(final ThrownType thrownType) {
93  						return new ArrayList<>();
94  					}
95  				});
96  			}
97  			
98  			@Override
99  			public List<Type> handle(final TypeProxy typeProxy) {
100 				return new ArrayList<>();
101 			}
102 		});
103 		
104 		assertEquals(1, standardizeElements.size());
105 		assertEquals(sum.getElements().iterator().next(), standardizeElements.iterator().next());
106 	}
107 	
108 	/**
109 	 * A > B, A > C und C > D. {A,B,C,D} => {A}
110 	 * 
111 	 * @throws Exception
112 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
113 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
114 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
115 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
116 	 *             {@link java.util.concurrent.ExecutionException}
117 	 */
118 	@Test
119 	public void testClass2() throws Exception {
120 		final String input =
121 				"Group:group=[Klasse:class={(); summe:{A,B,C,D};}; A:class={();}; "
122 						+ "B:class=A+{()=A();}; C:class=A+{()=A();}; D:class=C+{()=C();};];";
123 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
124 		final Group group = model.getGroups().iterator().next();
125 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
126 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
127 		
128 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
129 			
130 			@Override
131 			public List<Type> handle(final AtomicType atomicType) {
132 				return new ArrayList<>();
133 			}
134 			
135 			@Override
136 			public List<Type> handle(final CompositeType compositeType) {
137 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
138 					
139 					@Override
140 					public List<Type> handle(final ListType list) {
141 						return new ArrayList<>();
142 					}
143 					
144 					@Override
145 					public List<Type> handle(final MapType map) {
146 						return new ArrayList<>();
147 					}
148 					
149 					@Override
150 					public List<Type> handle(final ProductType product) {
151 						return new ArrayList<>();
152 					}
153 					
154 					@Override
155 					public List<Type> handle(final SumType sum2) {
156 						return sum2.getElements();
157 					}
158 					
159 					@Override
160 					public List<Type> handle(final ThrownType thrownType) {
161 						return new ArrayList<>();
162 					}
163 				});
164 			}
165 			
166 			@Override
167 			public List<Type> handle(final TypeProxy typeProxy) {
168 				return new ArrayList<>();
169 			}
170 		});
171 		
172 		assertEquals(1, standardizeElements.size());
173 		assertEquals(sum.getElements().iterator().next(), standardizeElements.iterator().next());
174 	}
175 	
176 	/**
177 	 * A > B, A > C und C > D. {A,B,C,D,E} => {A,E}
178 	 * 
179 	 * @throws Exception
180 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
181 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
182 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
183 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
184 	 *             {@link java.util.concurrent.ExecutionException}
185 	 */
186 	@Test
187 	public void testClass3() throws Exception {
188 		final String input =
189 				"Group:group=[Klasse:class={(); summe:{A,B,C,D,E};}; A:class={();};"
190 						+ " B:class=A+{()=A();}; C:class=A+{()=A();}; D:class=C+{()=C();};  E:class={();};];";
191 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
192 		final Group group = model.getGroups().iterator().next();
193 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
194 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
195 		
196 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
197 			
198 			@Override
199 			public List<Type> handle(final AtomicType atomicType) {
200 				return new ArrayList<>();
201 			}
202 			
203 			@Override
204 			public List<Type> handle(final CompositeType compositeType) {
205 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
206 					
207 					@Override
208 					public List<Type> handle(final ListType list) {
209 						return new ArrayList<>();
210 					}
211 					
212 					@Override
213 					public List<Type> handle(final MapType map) {
214 						return new ArrayList<>();
215 					}
216 					
217 					@Override
218 					public List<Type> handle(final ProductType product) {
219 						return new ArrayList<>();
220 					}
221 					
222 					@Override
223 					public List<Type> handle(final SumType sum2) {
224 						return sum2.getElements();
225 					}
226 					
227 					@Override
228 					public List<Type> handle(final ThrownType thrownType) {
229 						return new ArrayList<>();
230 					}
231 				});
232 			}
233 			
234 			@Override
235 			public List<Type> handle(final TypeProxy typeProxy) {
236 				return new ArrayList<>();
237 			}
238 		});
239 		
240 		assertEquals(2, standardizeElements.size());
241 		assertEquals(sum.getElements().iterator().next(), standardizeElements.iterator().next());
242 	}
243 	
244 	/**
245 	 * D > B, D > C und B > A. {A,B,C,D} => {D}
246 	 * 
247 	 * @throws Exception
248 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
249 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
250 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
251 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
252 	 *             {@link java.util.concurrent.ExecutionException}
253 	 */
254 	@Test
255 	public void testClass4() throws Exception {
256 		final String input =
257 				"Group:group=[Klasse:class={(); summe:{A,B,C,D};}; A:class=B+{()=B();};"
258 						+ " B:class=D+{()=D();}; C:class=D+{()=D();}; D:class={();};];";
259 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
260 		final Group group = model.getGroups().iterator().next();
261 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
262 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
263 		
264 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
265 			
266 			@Override
267 			public List<Type> handle(final AtomicType atomicType) {
268 				return new ArrayList<>();
269 			}
270 			
271 			@Override
272 			public List<Type> handle(final CompositeType compositeType) {
273 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
274 					
275 					@Override
276 					public List<Type> handle(final ListType list) {
277 						return new ArrayList<>();
278 					}
279 					
280 					@Override
281 					public List<Type> handle(final MapType map) {
282 						return new ArrayList<>();
283 					}
284 					
285 					@Override
286 					public List<Type> handle(final ProductType product) {
287 						return new ArrayList<>();
288 					}
289 					
290 					@Override
291 					public List<Type> handle(final SumType sum2) {
292 						return sum2.getElements();
293 					}
294 					
295 					@Override
296 					public List<Type> handle(final ThrownType thrownType) {
297 						return new ArrayList<>();
298 					}
299 				});
300 			}
301 			
302 			@Override
303 			public List<Type> handle(final TypeProxy typeProxy) {
304 				return new ArrayList<>();
305 			}
306 		});
307 		
308 		assertEquals(1, standardizeElements.size());
309 		assertEquals(sum.getElements().get(3), standardizeElements.iterator().next());
310 	}
311 	
312 	/**
313 	 * D > B, D > C und B > A. {B**,A,B,A*,C,D,D*} => {B**,D,A*,D*}
314 	 * 
315 	 * @throws Exception
316 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
317 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
318 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
319 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
320 	 *             {@link java.util.concurrent.ExecutionException}
321 	 */
322 	@Test
323 	public void testClassAndList1() throws Exception {
324 		final String input =
325 				"Group:group=[Klasse:class={(); summe:{B**,A,B,A*,C,D,D*};}; "
326 						+ "A:class=B+{()=B();}; B:class=D+{()=D();}; C:class=D+{()=D();}; D:class={();};];";
327 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
328 		final Group group = model.getGroups().iterator().next();
329 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
330 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
331 		
332 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
333 			
334 			@Override
335 			public List<Type> handle(final AtomicType atomicType) {
336 				return new ArrayList<>();
337 			}
338 			
339 			@Override
340 			public List<Type> handle(final CompositeType compositeType) {
341 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
342 					
343 					@Override
344 					public List<Type> handle(final ListType list) {
345 						return new ArrayList<>();
346 					}
347 					
348 					@Override
349 					public List<Type> handle(final MapType map) {
350 						return new ArrayList<>();
351 					}
352 					
353 					@Override
354 					public List<Type> handle(final ProductType product) {
355 						return new ArrayList<>();
356 					}
357 					
358 					@Override
359 					public List<Type> handle(final SumType sum2) {
360 						return sum2.getElements();
361 					}
362 					
363 					@Override
364 					public List<Type> handle(final ThrownType thrownType) {
365 						return new ArrayList<>();
366 					}
367 				});
368 			}
369 			
370 			@Override
371 			public List<Type> handle(final TypeProxy typeProxy) {
372 				return new ArrayList<>();
373 			}
374 		});
375 		
376 		assertEquals(4, standardizeElements.size());
377 		final Iterator<Type> iterator = standardizeElements.iterator();
378 		// D
379 		assertEquals(sum.getElements().get(5), iterator.next());
380 		// A*
381 		assertEquals(sum.getElements().get(3), iterator.next());
382 		// D*
383 		assertEquals(sum.getElements().get(6), iterator.next());
384 		// B**
385 		assertEquals(sum.getElements().get(0), iterator.next());
386 	}
387 	
388 	/**
389 	 * A > B. {A*,B*} => {A*,B*}
390 	 * 
391 	 * @throws Exception
392 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
393 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
394 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
395 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
396 	 *             {@link java.util.concurrent.ExecutionException}
397 	 */
398 	@Test
399 	public void testList1() throws Exception {
400 		final String input = "Group:group=[Klasse:class={(); summe:{A*,B*};}; A:class={();}; B:class=A+{()=A();};];";
401 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
402 		final Group group = model.getGroups().iterator().next();
403 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
404 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
405 		
406 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
407 			
408 			@Override
409 			public List<Type> handle(final AtomicType atomicType) {
410 				return new ArrayList<>();
411 			}
412 			
413 			@Override
414 			public List<Type> handle(final CompositeType compositeType) {
415 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
416 					
417 					@Override
418 					public List<Type> handle(final ListType list) {
419 						return new ArrayList<>();
420 					}
421 					
422 					@Override
423 					public List<Type> handle(final MapType map) {
424 						return new ArrayList<>();
425 					}
426 					
427 					@Override
428 					public List<Type> handle(final ProductType product) {
429 						return new ArrayList<>();
430 					}
431 					
432 					@Override
433 					public List<Type> handle(final SumType sum2) {
434 						return sum2.getElements();
435 					}
436 					
437 					@Override
438 					public List<Type> handle(final ThrownType thrownType) {
439 						return new ArrayList<>();
440 					}
441 				});
442 			}
443 			
444 			@Override
445 			public List<Type> handle(final TypeProxy typeProxy) {
446 				return new ArrayList<>();
447 			}
448 		});
449 		
450 		assertEquals(2, standardizeElements.size());
451 	}
452 	
453 	/**
454 	 * A > B und A > C. {{A,B},C} => {A}
455 	 * 
456 	 * @throws Exception
457 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
458 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
459 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
460 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
461 	 *             {@link java.util.concurrent.ExecutionException}
462 	 */
463 	@Test
464 	public void testSum1() throws Exception {
465 		final String input =
466 				"Group:group=[Klasse:class={(); summe:{{A,B},C};}; A:class={();}; B:class=A+{()=A();}; C:class=A+{()=A();};];";
467 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
468 		final Group group = model.getGroups().iterator().next();
469 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
470 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
471 		
472 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
473 			
474 			@Override
475 			public List<Type> handle(final AtomicType atomicType) {
476 				return new ArrayList<>();
477 			}
478 			
479 			@Override
480 			public List<Type> handle(final CompositeType compositeType) {
481 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
482 					
483 					@Override
484 					public List<Type> handle(final ListType list) {
485 						return new ArrayList<>();
486 					}
487 					
488 					@Override
489 					public List<Type> handle(final MapType map) {
490 						return new ArrayList<>();
491 					}
492 					
493 					@Override
494 					public List<Type> handle(final ProductType product) {
495 						return new ArrayList<>();
496 					}
497 					
498 					@Override
499 					public List<Type> handle(final SumType sum2) {
500 						return sum2.getElements();
501 					}
502 					
503 					@Override
504 					public List<Type> handle(final ThrownType thrownType) {
505 						return new ArrayList<>();
506 					}
507 				});
508 			}
509 			
510 			@Override
511 			public List<Type> handle(final TypeProxy typeProxy) {
512 				return new ArrayList<>();
513 			}
514 		});
515 		
516 		assertEquals(1, standardizeElements.size());
517 		assertEquals(
518 				((SumType) sum.getElements().iterator().next()).getElements().iterator().next(),
519 				standardizeElements.iterator().next());
520 	}
521 	
522 	/**
523 	 * A > B und A > C. {{A,B,{A*,B*}},C,C*} => {A,A*,B*,C*}
524 	 * 
525 	 * @throws Exception
526 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
527 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
528 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
529 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
530 	 *             {@link java.util.concurrent.ExecutionException}
531 	 */
532 	@Test
533 	public void testSum2() throws Exception {
534 		final String input =
535 				"Group:group=[Klasse:class={(); summe:{{A,B,{A*,B*}},C,C*};}; A:class={();};"
536 						+ " B:class=A+{()=A();}; C:class=A+{()=A();};];";
537 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
538 		final Group group = model.getGroups().iterator().next();
539 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
540 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
541 		
542 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
543 			
544 			@Override
545 			public List<Type> handle(final AtomicType atomicType) {
546 				return new ArrayList<>();
547 			}
548 			
549 			@Override
550 			public List<Type> handle(final CompositeType compositeType) {
551 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
552 					
553 					@Override
554 					public List<Type> handle(final ListType list) {
555 						return new ArrayList<>();
556 					}
557 					
558 					@Override
559 					public List<Type> handle(final MapType map) {
560 						return new ArrayList<>();
561 					}
562 					
563 					@Override
564 					public List<Type> handle(final ProductType product) {
565 						return new ArrayList<>();
566 					}
567 					
568 					@Override
569 					public List<Type> handle(final SumType sum2) {
570 						return sum2.getElements();
571 					}
572 					
573 					@Override
574 					public List<Type> handle(final ThrownType thrownType) {
575 						return new ArrayList<>();
576 					}
577 				});
578 			}
579 			
580 			@Override
581 			public List<Type> handle(final TypeProxy typeProxy) {
582 				return new ArrayList<>();
583 			}
584 		});
585 		
586 		assertEquals(4, standardizeElements.size());
587 		
588 		final Iterator<Type> iterator1 = standardizeElements.iterator();
589 		final Iterator<Type> iterator0 = sum.getElements().iterator();
590 		final Iterator<Type> iterator2 = ((SumType) iterator0.next()).getElements().iterator();
591 		
592 		final Type a = iterator2.next();
593 		iterator2.next();
594 		final Iterator<Type> iterator3 = ((SumType) iterator2.next()).getElements().iterator();
595 		final Type listA = iterator3.next();
596 		final Type listB = iterator3.next();
597 		iterator0.next();
598 		final Type listC = iterator0.next();
599 		
600 		// A
601 		assertEquals(a, iterator1.next());
602 		// A*
603 		assertEquals(listA, iterator1.next());
604 		// B*
605 		assertEquals(listB, iterator1.next());
606 		// C*
607 		assertEquals(listC, iterator1.next());
608 	}
609 	
610 	/**
611 	 * A > B und A > C. {A,B,C,C*,A*,{B*,A*},(name:String,alter:Integer),[String -> Integer]} => {A,A*,B*,C*,[String ->
612 	 * Integer],(name:String,alter:Integer)}
613 	 * 
614 	 * @throws Exception
615 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
616 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
617 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
618 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
619 	 *             {@link java.util.concurrent.ExecutionException}
620 	 */
621 	@Test
622 	public void testClassProductMapListSum1() throws Exception {
623 		final String input =
624 				"Group:group=[Klasse:class={(); summe:{A,B,C,C*,A*,{B*,A*},"
625 						+ "(name:String,alter:Integer),[String -> Integer]};}; A:class={();}; B:class=A+{()=A();}; C:class=A+{()=A();};];";
626 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
627 		final Group group = model.getGroups().iterator().next();
628 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
629 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
630 		
631 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
632 			
633 			@Override
634 			public List<Type> handle(final AtomicType atomicType) {
635 				return new ArrayList<>();
636 			}
637 			
638 			@Override
639 			public List<Type> handle(final CompositeType compositeType) {
640 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
641 					
642 					@Override
643 					public List<Type> handle(final ListType list) {
644 						return new ArrayList<>();
645 					}
646 					
647 					@Override
648 					public List<Type> handle(final MapType map) {
649 						return new ArrayList<>();
650 					}
651 					
652 					@Override
653 					public List<Type> handle(final ProductType product) {
654 						return new ArrayList<>();
655 					}
656 					
657 					@Override
658 					public List<Type> handle(final SumType sum2) {
659 						return sum2.getElements();
660 					}
661 					
662 					@Override
663 					public List<Type> handle(final ThrownType thrownType) {
664 						return new ArrayList<>();
665 					}
666 				});
667 			}
668 			
669 			@Override
670 			public List<Type> handle(final TypeProxy typeProxy) {
671 				return new ArrayList<>();
672 			}
673 		});
674 		
675 		assertEquals(6, standardizeElements.size());
676 		// A
677 		assertEquals(sum.getElements().get(0), standardizeElements.get(0));
678 		// A*
679 		assertEquals(sum.getElements().get(4), standardizeElements.get(1));
680 		// B*
681 		assertEquals(((SumType) sum.getElements().get(5)).getElements().get(0), standardizeElements.get(2));
682 		// C*
683 		assertEquals(sum.getElements().get(3), standardizeElements.get(3));
684 		// [String -> Integer]
685 		assertEquals(sum.getElements().get(7), standardizeElements.get(4));
686 		// (name:String,alter:Integer)
687 		assertEquals(sum.getElements().get(6), standardizeElements.get(5));
688 	}
689 	
690 	/**
691 	 * {[String->Integer],[String->Integer]} => {[String->Integer]}.
692 	 * 
693 	 * @throws Exception
694 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
695 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
696 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
697 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
698 	 *             {@link java.util.concurrent.ExecutionException}
699 	 */
700 	@Test
701 	public void testMap1() throws Exception {
702 		final String input = "Group:group=[Klasse:class={(); summe:{[String -> Integer],[String -> Integer]};};];";
703 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
704 		final Group group = model.getGroups().iterator().next();
705 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
706 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
707 		
708 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
709 			
710 			@Override
711 			public List<Type> handle(final AtomicType atomicType) {
712 				return new ArrayList<>();
713 			}
714 			
715 			@Override
716 			public List<Type> handle(final CompositeType compositeType) {
717 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
718 					
719 					@Override
720 					public List<Type> handle(final ListType list) {
721 						return new ArrayList<>();
722 					}
723 					
724 					@Override
725 					public List<Type> handle(final MapType map) {
726 						return new ArrayList<>();
727 					}
728 					
729 					@Override
730 					public List<Type> handle(final ProductType product) {
731 						return new ArrayList<>();
732 					}
733 					
734 					@Override
735 					public List<Type> handle(final SumType sum2) {
736 						return sum2.getElements();
737 					}
738 					
739 					@Override
740 					public List<Type> handle(final ThrownType thrownType) {
741 						return new ArrayList<>();
742 					}
743 				});
744 			}
745 			
746 			@Override
747 			public List<Type> handle(final TypeProxy typeProxy) {
748 				return new ArrayList<>();
749 			}
750 		});
751 		
752 		assertEquals(1, standardizeElements.size());
753 		assertEquals(sum.getElements().get(0), standardizeElements.iterator().next());
754 	}
755 	
756 	/**
757 	 * A > B. {[A->Integer],[B->Integer]} => {[A->Integer],[B->Integer]}
758 	 * 
759 	 * @throws Exception
760 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
761 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
762 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
763 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
764 	 *             {@link java.util.concurrent.ExecutionException}
765 	 */
766 	@Test
767 	public void testMap2() throws Exception {
768 		final String input =
769 				"Group:group=[Klasse:class={(); summe: {[A->Integer],[B->Integer]};}; "
770 						+ "A:class={();}; B:class=A+{()=A();};];";
771 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
772 		final Group group = model.getGroups().iterator().next();
773 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
774 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
775 		
776 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
777 			
778 			@Override
779 			public List<Type> handle(final AtomicType atomicType) {
780 				return new ArrayList<>();
781 			}
782 			
783 			@Override
784 			public List<Type> handle(final CompositeType compositeType) {
785 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
786 					
787 					@Override
788 					public List<Type> handle(final ListType list) {
789 						return new ArrayList<>();
790 					}
791 					
792 					@Override
793 					public List<Type> handle(final MapType map) {
794 						return new ArrayList<>();
795 					}
796 					
797 					@Override
798 					public List<Type> handle(final ProductType product) {
799 						return new ArrayList<>();
800 					}
801 					
802 					@Override
803 					public List<Type> handle(final SumType sum2) {
804 						return sum2.getElements();
805 					}
806 					
807 					@Override
808 					public List<Type> handle(final ThrownType thrownType) {
809 						return new ArrayList<>();
810 					}
811 				});
812 			}
813 			
814 			@Override
815 			public List<Type> handle(final TypeProxy typeProxy) {
816 				return new ArrayList<>();
817 			}
818 		});
819 		
820 		assertEquals(2, standardizeElements.size());
821 	}
822 	
823 	/**
824 	 * A > B. {[Integer->A],[Integer->B]} => {[Integer->A],[Integer->B]}
825 	 * 
826 	 * @throws Exception
827 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
828 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
829 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
830 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
831 	 *             {@link java.util.concurrent.ExecutionException}
832 	 */
833 	@Test
834 	public void testMap3() throws Exception {
835 		final String input =
836 				"Group:group=[Klasse:class={(); summe: {[Integer->A],[Integer->B]};}; "
837 						+ "A:class={();}; B:class=A+{()=A();};];";
838 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
839 		final Group group = model.getGroups().iterator().next();
840 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
841 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
842 		
843 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
844 			
845 			@Override
846 			public List<Type> handle(final AtomicType atomicType) {
847 				return new ArrayList<>();
848 			}
849 			
850 			@Override
851 			public List<Type> handle(final CompositeType compositeType) {
852 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
853 					
854 					@Override
855 					public List<Type> handle(final ListType list) {
856 						return new ArrayList<>();
857 					}
858 					
859 					@Override
860 					public List<Type> handle(final MapType map) {
861 						return new ArrayList<>();
862 					}
863 					
864 					@Override
865 					public List<Type> handle(final ProductType product) {
866 						return new ArrayList<>();
867 					}
868 					
869 					@Override
870 					public List<Type> handle(final SumType sum2) {
871 						return sum2.getElements();
872 					}
873 					
874 					@Override
875 					public List<Type> handle(final ThrownType thrownType) {
876 						return new ArrayList<>();
877 					}
878 				});
879 			}
880 			
881 			@Override
882 			public List<Type> handle(final TypeProxy typeProxy) {
883 				return new ArrayList<>();
884 			}
885 		});
886 		
887 		assertEquals(2, standardizeElements.size());
888 	}
889 	
890 	/**
891 	 * A > B. {[B->A],[A->B]} => {[B->A],[A->B]}
892 	 * 
893 	 * @throws Exception
894 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
895 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
896 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
897 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
898 	 *             {@link java.util.concurrent.ExecutionException}
899 	 */
900 	@Test
901 	public void testMap4() throws Exception {
902 		final String input =
903 				"Group:group=[Klasse:class={(); summe: {[B->A],[A->B]};}; A:class={();}; B:class=A+{()=A();};];";
904 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
905 		final Group group = model.getGroups().iterator().next();
906 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
907 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
908 		
909 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
910 			
911 			@Override
912 			public List<Type> handle(final AtomicType atomicType) {
913 				return new ArrayList<>();
914 			}
915 			
916 			@Override
917 			public List<Type> handle(final CompositeType compositeType) {
918 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
919 					
920 					@Override
921 					public List<Type> handle(final ListType list) {
922 						return new ArrayList<>();
923 					}
924 					
925 					@Override
926 					public List<Type> handle(final MapType map) {
927 						return new ArrayList<>();
928 					}
929 					
930 					@Override
931 					public List<Type> handle(final ProductType product) {
932 						return new ArrayList<>();
933 					}
934 					
935 					@Override
936 					public List<Type> handle(final SumType sum2) {
937 						return sum2.getElements();
938 					}
939 					
940 					@Override
941 					public List<Type> handle(final ThrownType thrownType) {
942 						return new ArrayList<>();
943 					}
944 				});
945 			}
946 			
947 			@Override
948 			public List<Type> handle(final TypeProxy typeProxy) {
949 				return new ArrayList<>();
950 			}
951 		});
952 		
953 		assertEquals(2, standardizeElements.size());
954 	}
955 	
956 	/**
957 	 * A > B. {[B->A],[A->Integer]} => {[B->A],[A->Integer]}
958 	 * 
959 	 * @throws Exception
960 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
961 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
962 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
963 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
964 	 *             {@link java.util.concurrent.ExecutionException}
965 	 */
966 	@Test
967 	public void testMap5() throws Exception {
968 		final String input =
969 				"Group:group=[Klasse:class={(); summe: {[B->A],[A->Integer]};}; A:class={();}; B:class=A+{()=A();};];";
970 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
971 		final Group group = model.getGroups().iterator().next();
972 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
973 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
974 		
975 		final List<Type> standardizeElements = sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
976 			
977 			@Override
978 			public List<Type> handle(final AtomicType atomicType) {
979 				return new ArrayList<>();
980 			}
981 			
982 			@Override
983 			public List<Type> handle(final CompositeType compositeType) {
984 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
985 					
986 					@Override
987 					public List<Type> handle(final ListType list) {
988 						return new ArrayList<>();
989 					}
990 					
991 					@Override
992 					public List<Type> handle(final MapType map) {
993 						return new ArrayList<>();
994 					}
995 					
996 					@Override
997 					public List<Type> handle(final ProductType product) {
998 						return new ArrayList<>();
999 					}
1000 					
1001 					@Override
1002 					public List<Type> handle(final SumType sum2) {
1003 						return sum2.getElements();
1004 					}
1005 					
1006 					@Override
1007 					public List<Type> handle(final ThrownType thrownType) {
1008 						return new ArrayList<>();
1009 					}
1010 				});
1011 			}
1012 			
1013 			@Override
1014 			public List<Type> handle(final TypeProxy typeProxy) {
1015 				return new ArrayList<>();
1016 			}
1017 		});
1018 		
1019 		assertEquals(2, standardizeElements.size());
1020 	}
1021 	
1022 	/**
1023 	 * A > B. {Anything,A,B} => Summe "Anything"
1024 	 * 
1025 	 * @throws Exception
1026 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
1027 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
1028 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
1029 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
1030 	 *             {@link java.util.concurrent.ExecutionException}
1031 	 */
1032 	@Test
1033 	public void testAnything1() throws Exception {
1034 		final String input =
1035 				"Group:group=[Klasse:class={(); summe: {Anything,A,B};}; A:class={();}; B:class=A+{()=A();};];";
1036 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
1037 		final Group group = model.getGroups().iterator().next();
1038 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
1039 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
1040 		try {
1041 			sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
1042 				
1043 				@Override
1044 				public List<Type> handle(final AtomicType atomicType) {
1045 					return new ArrayList<>();
1046 				}
1047 				
1048 				@Override
1049 				public List<Type> handle(final CompositeType compositeType) {
1050 					return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
1051 						
1052 						@Override
1053 						public List<Type> handle(final ListType list) {
1054 							return new ArrayList<>();
1055 						}
1056 						
1057 						@Override
1058 						public List<Type> handle(final MapType map) {
1059 							return new ArrayList<>();
1060 						}
1061 						
1062 						@Override
1063 						public List<Type> handle(final ProductType product) {
1064 							return new ArrayList<>();
1065 						}
1066 						
1067 						@Override
1068 						public List<Type> handle(final SumType sum2) {
1069 							return sum2.getElements();
1070 						}
1071 						
1072 						@Override
1073 						public List<Type> handle(final ThrownType thrownType) {
1074 							return new ArrayList<>();
1075 						}
1076 					});
1077 				}
1078 				
1079 				@Override
1080 				public List<Type> handle(final TypeProxy typeProxy) {
1081 					return new ArrayList<>();
1082 				}
1083 			});
1084 			
1085 			fail();
1086 		} catch (final SumIsAnythingException e) {
1087 			// Nothing
1088 		}
1089 	}
1090 	
1091 	/**
1092 	 * A > B. {{Anything,C},A,B} => Summe "Anything"
1093 	 * 
1094 	 * @throws Exception
1095 	 *             {@link de.fhdw.wtf.common.exception.parser.SumIsAnythingException},
1096 	 *             {@link de.fhdw.wtf.common.exception.editor.MultipleCheckExceptions},
1097 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicDependencyException}, {@link InterruptedException},
1098 	 *             {@link de.fhdw.wtf.common.exception.walker.CyclicPartDefinitionException},
1099 	 *             {@link java.util.concurrent.ExecutionException}
1100 	 */
1101 	@Test
1102 	public void testAnything2() throws Exception {
1103 		final String input =
1104 				"Group:group=[Klasse:class={(); summe: {{Anything,C},A,B};};"
1105 						+ " A:class={();}; B:class=A+{()=A();}; C:class={();};];";
1106 		final Model model = SyntaxCheck.getInstance().getModelFromString(input);
1107 		final Group group = model.getGroups().iterator().next();
1108 		final ClassType klasse = (ClassType) group.getGroupElements().iterator().next();
1109 		final SumType sum = (SumType) klasse.getAttributes().iterator().next().getAttrType();
1110 		try {
1111 			sum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
1112 				
1113 				@Override
1114 				public List<Type> handle(final AtomicType atomicType) {
1115 					return new ArrayList<>();
1116 				}
1117 				
1118 				@Override
1119 				public List<Type> handle(final CompositeType compositeType) {
1120 					return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
1121 						
1122 						@Override
1123 						public List<Type> handle(final ListType list) {
1124 							return new ArrayList<>();
1125 						}
1126 						
1127 						@Override
1128 						public List<Type> handle(final MapType map) {
1129 							return new ArrayList<>();
1130 						}
1131 						
1132 						@Override
1133 						public List<Type> handle(final ProductType product) {
1134 							return new ArrayList<>();
1135 						}
1136 						
1137 						@Override
1138 						public List<Type> handle(final SumType sum2) {
1139 							return sum2.getElements();
1140 						}
1141 						
1142 						@Override
1143 						public List<Type> handle(final ThrownType thrownType) {
1144 							return new ArrayList<>();
1145 						}
1146 					});
1147 				}
1148 				
1149 				@Override
1150 				public List<Type> handle(final TypeProxy typeProxy) {
1151 					return new ArrayList<>();
1152 				}
1153 			});
1154 			fail();
1155 		} catch (final SumIsAnythingException e) {
1156 			// Nothing
1157 		}
1158 	}
1159 	
1160 	/**
1161 	 * {A!}! => Result: A!.
1162 	 * 
1163 	 * @throws SumIsAnythingException
1164 	 *             If it contains Anything throw specified Exception
1165 	 */
1166 	@Test
1167 	public void testThrownSumContainsThrownType() throws SumIsAnythingException {
1168 		
1169 		final Token dummyToken = DummyToken.getInstance();
1170 		final Position dummyPosition = DummyToken.getDummyPosition();
1171 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1172 		
1173 		// Prepare Actual
1174 		final SumType actualSum = SumType.create(dummyToken);
1175 		final ThrownType actualThrownType =
1176 				ThrownType.create(
1177 						dummyToken,
1178 						TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1179 		
1180 		actualSum.add(actualThrownType);
1181 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1182 		
1183 		final Type standardizedType = thrownType.standardize();
1184 		
1185 		// Prepare Expected
1186 		final ThrownType expectedThrownType =
1187 				ThrownType.create(
1188 						dummyToken,
1189 						TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1190 		
1191 		// Test
1192 		assertEquals(standardizedType, expectedThrownType);
1193 	}
1194 	
1195 	/**
1196 	 * {A!} => Result: A!.
1197 	 * 
1198 	 * @throws SumIsAnythingException
1199 	 *             If it contains Anything throw specified Exception
1200 	 */
1201 	@Test
1202 	public void testSumContainsThrownType() throws SumIsAnythingException {
1203 		
1204 		final Token dummyToken = DummyToken.getInstance();
1205 		final Position dummyPosition = DummyToken.getDummyPosition();
1206 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1207 		
1208 		// Prepare Actual
1209 		final SumType actualSum = SumType.create(dummyToken);
1210 		final ThrownType actualThrownType =
1211 				ThrownType.create(
1212 						dummyToken,
1213 						TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1214 		
1215 		actualSum.add(actualThrownType);
1216 		
1217 		final List<Type> standardizeElements = actualSum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
1218 			
1219 			@Override
1220 			public List<Type> handle(final AtomicType atomicType) {
1221 				return new ArrayList<>();
1222 			}
1223 			
1224 			@Override
1225 			public List<Type> handle(final CompositeType compositeType) {
1226 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
1227 					
1228 					@Override
1229 					public List<Type> handle(final ListType list) {
1230 						return new ArrayList<>();
1231 					}
1232 					
1233 					@Override
1234 					public List<Type> handle(final MapType map) {
1235 						return new ArrayList<>();
1236 					}
1237 					
1238 					@Override
1239 					public List<Type> handle(final ProductType product) {
1240 						return new ArrayList<>();
1241 					}
1242 					
1243 					@Override
1244 					public List<Type> handle(final SumType sum2) {
1245 						return sum2.getElements();
1246 					}
1247 					
1248 					@Override
1249 					public List<Type> handle(final ThrownType thrownType) {
1250 						return new ArrayList<>();
1251 					}
1252 				});
1253 			}
1254 			
1255 			@Override
1256 			public List<Type> handle(final TypeProxy typeProxy) {
1257 				return new ArrayList<>();
1258 			}
1259 		});
1260 		
1261 		// Prepare Expected
1262 		final ThrownType expectedThrownType =
1263 				ThrownType.create(
1264 						dummyToken,
1265 						TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1266 		
1267 		// Test
1268 		assertEquals(1, standardizeElements.size());
1269 		final Type first = standardizeElements.get(0);
1270 		assertEquals(first, expectedThrownType);
1271 	}
1272 	
1273 	/**
1274 	 * {A}! => Result: A!.
1275 	 * 
1276 	 * @throws SumIsAnythingException
1277 	 *             If it contains Anything throw specified Exception
1278 	 */
1279 	@Test
1280 	public void testThrownSumContainsNormalType() throws SumIsAnythingException {
1281 		
1282 		final Token dummyToken = DummyToken.getInstance();
1283 		final Position dummyPosition = DummyToken.getDummyPosition();
1284 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1285 		
1286 		// Prepare Actual
1287 		final SumType actualSum = SumType.create(dummyToken);
1288 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1289 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1290 		
1291 		final Type standardizedType = thrownType.standardize();
1292 		
1293 		// Prepare Expected
1294 		final ThrownType expectedThrownType =
1295 				ThrownType.create(
1296 						dummyToken,
1297 						TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1298 		
1299 		// Test
1300 		assertEquals(standardizedType, expectedThrownType);
1301 	}
1302 	
1303 	/**
1304 	 * {A,B}! => Result: {A!,B!}.
1305 	 * 
1306 	 * @throws SumIsAnythingException
1307 	 *             If it contains Anything throw specified Exception
1308 	 */
1309 	@Test
1310 	public void testThrownSumContainsNormalTypes() throws SumIsAnythingException {
1311 		
1312 		final Token dummyToken = DummyToken.getInstance();
1313 		final Position dummyPosition = DummyToken.getDummyPosition();
1314 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1315 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1316 		
1317 		// Prepare Actual
1318 		final SumType actualSum = SumType.create(dummyToken);
1319 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1320 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
1321 		
1322 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1323 		
1324 		final Type standardizedType = thrownType.standardize();
1325 		
1326 		// Prepare Expected
1327 		final SumType expectedSum = SumType.create(dummyToken);
1328 		expectedSum.add(ThrownType.create(
1329 				dummyToken,
1330 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1331 		expectedSum.add(ThrownType.create(
1332 				dummyToken,
1333 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1334 		
1335 		// Test
1336 		assertTrue(standardizedType instanceof SumType);
1337 		final SumType sum = (SumType) standardizedType;
1338 		assertEquals(2, sum.getElements().size());
1339 		assertEquals(2, expectedSum.getElements().size());
1340 		this.assertEqualsOnlists(sum.getElements(), expectedSum.getElements());
1341 	}
1342 	
1343 	/**
1344 	 * {A!,B}! => Result: {A!,B!}.
1345 	 * 
1346 	 * @throws SumIsAnythingException
1347 	 *             If it contains Anything throw specified Exception
1348 	 */
1349 	@Test
1350 	public void testThrownSumContainsOneThrownTypeFirstAndOneNormalThrownTypes() throws SumIsAnythingException {
1351 		
1352 		final Token dummyToken = DummyToken.getInstance();
1353 		final Position dummyPosition = DummyToken.getDummyPosition();
1354 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1355 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1356 		
1357 		// Prepare Actual
1358 		final SumType actualSum = SumType.create(dummyToken);
1359 		actualSum.add(ThrownType.create(
1360 				dummyToken,
1361 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1362 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
1363 		
1364 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1365 		
1366 		final Type standardizedType = thrownType.standardize();
1367 		
1368 		// Prepare Expected
1369 		final SumType expectedSum = SumType.create(dummyToken);
1370 		expectedSum.add(ThrownType.create(
1371 				dummyToken,
1372 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1373 		expectedSum.add(ThrownType.create(
1374 				dummyToken,
1375 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1376 		
1377 		// Test
1378 		assertTrue(standardizedType instanceof SumType);
1379 		final SumType sum = (SumType) standardizedType;
1380 		assertEquals(2, sum.getElements().size());
1381 		assertEquals(2, expectedSum.getElements().size());
1382 		this.assertEqualsOnlists(sum.getElements(), expectedSum.getElements());
1383 	}
1384 	
1385 	/**
1386 	 * {A,B!}! => Result: {A!,B!}.
1387 	 * 
1388 	 * @throws SumIsAnythingException
1389 	 *             If it contains Anything throw specified Exception
1390 	 */
1391 	@Test
1392 	public void testThrownSumContainsOneThrownTypeSecondAndOneNormalThrownTypes() throws SumIsAnythingException {
1393 		
1394 		final Token dummyToken = DummyToken.getInstance();
1395 		final Position dummyPosition = DummyToken.getDummyPosition();
1396 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1397 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1398 		
1399 		// Prepare Actual
1400 		final SumType actualSum = SumType.create(dummyToken);
1401 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1402 		actualSum.add(ThrownType.create(
1403 				dummyToken,
1404 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1405 		
1406 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1407 		
1408 		final Type standardizedType = thrownType.standardize();
1409 		
1410 		// Prepare Expected
1411 		final SumType expectedSum = SumType.create(dummyToken);
1412 		expectedSum.add(ThrownType.create(
1413 				dummyToken,
1414 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1415 		expectedSum.add(ThrownType.create(
1416 				dummyToken,
1417 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1418 		
1419 		// Test
1420 		assertTrue(standardizedType instanceof SumType);
1421 		final SumType sum = (SumType) standardizedType;
1422 		assertEquals(2, sum.getElements().size());
1423 		assertEquals(2, expectedSum.getElements().size());
1424 		this.assertEqualsOnlists(sum.getElements(), expectedSum.getElements());
1425 	}
1426 	
1427 	/**
1428 	 * {B!,A}! => Result: {A!,B!}.
1429 	 * 
1430 	 * @throws SumIsAnythingException
1431 	 *             If it contains Anything throw specified Exception
1432 	 */
1433 	@Test
1434 	public void testThrownSumContainsOneThrownTypeSecondAndOneNormalThrownTypesAndDifferentOrder()
1435 			throws SumIsAnythingException {
1436 		
1437 		final Token dummyToken = DummyToken.getInstance();
1438 		final Position dummyPosition = DummyToken.getDummyPosition();
1439 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1440 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1441 		
1442 		// Prepare Actual
1443 		final SumType actualSum = SumType.create(dummyToken);
1444 		actualSum.add(ThrownType.create(
1445 				dummyToken,
1446 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1447 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1448 		
1449 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1450 		
1451 		final Type standardizedType = thrownType.standardize();
1452 		
1453 		// Prepare Expected
1454 		final SumType expectedSum = SumType.create(dummyToken);
1455 		expectedSum.add(ThrownType.create(
1456 				dummyToken,
1457 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1458 		expectedSum.add(ThrownType.create(
1459 				dummyToken,
1460 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1461 		
1462 		// Test
1463 		assertTrue(standardizedType instanceof SumType);
1464 		final SumType sum = (SumType) standardizedType;
1465 		assertEquals(2, sum.getElements().size());
1466 		assertEquals(2, expectedSum.getElements().size());
1467 		this.assertEqualsOnlists(sum.getElements(), expectedSum.getElements());
1468 	}
1469 	
1470 	/**
1471 	 * {A!,B!}! => Result: {A!,B!}.
1472 	 * 
1473 	 * @throws SumIsAnythingException
1474 	 *             If it contains Anything throw specified Exception
1475 	 */
1476 	@Test
1477 	public void testThrownSumContainsThrownTypes() throws SumIsAnythingException {
1478 		
1479 		final Token dummyToken = DummyToken.getInstance();
1480 		final Position dummyPosition = DummyToken.getDummyPosition();
1481 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1482 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1483 		
1484 		// Prepare Actual
1485 		final SumType actualSum = SumType.create(dummyToken);
1486 		actualSum.add(ThrownType.create(
1487 				dummyToken,
1488 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1489 		actualSum.add(ThrownType.create(
1490 				dummyToken,
1491 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1492 		
1493 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1494 		
1495 		final Type standardizedType = thrownType.standardize();
1496 		
1497 		// Prepare Expected
1498 		final SumType expectedSum = SumType.create(dummyToken);
1499 		expectedSum.add(ThrownType.create(
1500 				dummyToken,
1501 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1502 		expectedSum.add(ThrownType.create(
1503 				dummyToken,
1504 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1505 		
1506 		// Test
1507 		assertTrue(standardizedType instanceof SumType);
1508 		final SumType sum = (SumType) standardizedType;
1509 		assertEquals(2, sum.getElements().size());
1510 		assertEquals(2, expectedSum.getElements().size());
1511 		this.assertEqualsOnlists(sum.getElements(), expectedSum.getElements());
1512 	}
1513 	
1514 	/**
1515 	 * {A!,B} => Result: {B,A!}.
1516 	 * 
1517 	 * @throws SumIsAnythingException
1518 	 *             If it contains Anything throw specified Exception
1519 	 */
1520 	@Test
1521 	public void testSumContainsOneThrownTypeFirst() throws SumIsAnythingException {
1522 		
1523 		final Token dummyToken = DummyToken.getInstance();
1524 		final Position dummyPosition = DummyToken.getDummyPosition();
1525 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1526 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1527 		
1528 		// Prepare Actual
1529 		final SumType actualSum = SumType.create(dummyToken);
1530 		actualSum.add(ThrownType.create(
1531 				dummyToken,
1532 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1533 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
1534 		
1535 		final List<Type> standardizeElements = actualSum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
1536 			
1537 			@Override
1538 			public List<Type> handle(final AtomicType atomicType) {
1539 				return new ArrayList<>();
1540 			}
1541 			
1542 			@Override
1543 			public List<Type> handle(final CompositeType compositeType) {
1544 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
1545 					
1546 					@Override
1547 					public List<Type> handle(final ListType list) {
1548 						return new ArrayList<>();
1549 					}
1550 					
1551 					@Override
1552 					public List<Type> handle(final MapType map) {
1553 						return new ArrayList<>();
1554 					}
1555 					
1556 					@Override
1557 					public List<Type> handle(final ProductType product) {
1558 						return new ArrayList<>();
1559 					}
1560 					
1561 					@Override
1562 					public List<Type> handle(final SumType sum2) {
1563 						return sum2.getElements();
1564 					}
1565 					
1566 					@Override
1567 					public List<Type> handle(final ThrownType thrownType) {
1568 						return new ArrayList<>();
1569 					}
1570 				});
1571 			}
1572 			
1573 			@Override
1574 			public List<Type> handle(final TypeProxy typeProxy) {
1575 				return new ArrayList<>();
1576 			}
1577 		});
1578 		
1579 		// Prepare Expected
1580 		final SumType expectedSum = SumType.create(dummyToken);
1581 		expectedSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
1582 		expectedSum.add(ThrownType.create(
1583 				dummyToken,
1584 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1585 		
1586 		// Test
1587 		assertEquals(2, standardizeElements.size());
1588 		assertEquals(2, expectedSum.getElements().size());
1589 		this.assertEqualsOnlists(standardizeElements, expectedSum.getElements());
1590 	}
1591 	
1592 	/**
1593 	 * {A,B!} => Result: {A,B!}.
1594 	 * 
1595 	 * @throws SumIsAnythingException
1596 	 *             If it contains Anything throw specified Exception
1597 	 */
1598 	@Test
1599 	public void testSumContainsOneThrownTypeSecond() throws SumIsAnythingException {
1600 		
1601 		final Token dummyToken = DummyToken.getInstance();
1602 		final Position dummyPosition = DummyToken.getDummyPosition();
1603 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1604 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1605 		
1606 		// Prepare Actual
1607 		final SumType actualSum = SumType.create(dummyToken);
1608 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1609 		actualSum.add(ThrownType.create(
1610 				dummyToken,
1611 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1612 		
1613 		final List<Type> standardizeElements = actualSum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
1614 			
1615 			@Override
1616 			public List<Type> handle(final AtomicType atomicType) {
1617 				return new ArrayList<>();
1618 			}
1619 			
1620 			@Override
1621 			public List<Type> handle(final CompositeType compositeType) {
1622 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
1623 					
1624 					@Override
1625 					public List<Type> handle(final ListType list) {
1626 						return new ArrayList<>();
1627 					}
1628 					
1629 					@Override
1630 					public List<Type> handle(final MapType map) {
1631 						return new ArrayList<>();
1632 					}
1633 					
1634 					@Override
1635 					public List<Type> handle(final ProductType product) {
1636 						return new ArrayList<>();
1637 					}
1638 					
1639 					@Override
1640 					public List<Type> handle(final SumType sum2) {
1641 						return sum2.getElements();
1642 					}
1643 					
1644 					@Override
1645 					public List<Type> handle(final ThrownType thrownType) {
1646 						return new ArrayList<>();
1647 					}
1648 				});
1649 			}
1650 			
1651 			@Override
1652 			public List<Type> handle(final TypeProxy typeProxy) {
1653 				return new ArrayList<>();
1654 			}
1655 		});
1656 		
1657 		// Prepare Expected
1658 		final SumType expectedSum = SumType.create(dummyToken);
1659 		expectedSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
1660 		expectedSum.add(ThrownType.create(
1661 				dummyToken,
1662 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1663 		
1664 		// Test
1665 		assertEquals(2, standardizeElements.size());
1666 		assertEquals(2, expectedSum.getElements().size());
1667 		this.assertEqualsOnlists(standardizeElements, expectedSum.getElements());
1668 	}
1669 	
1670 	/**
1671 	 * {A!,B!} => Result: {A!,B!}.
1672 	 * 
1673 	 * @throws SumIsAnythingException
1674 	 *             If it contains Anything throw specified Exception
1675 	 */
1676 	@Test
1677 	public void testSumContainsTwoThrownTypes() throws SumIsAnythingException {
1678 		
1679 		final Token dummyToken = DummyToken.getInstance();
1680 		final Position dummyPosition = DummyToken.getDummyPosition();
1681 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1682 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1683 		
1684 		// Prepare Actual
1685 		final SumType actualSum = SumType.create(dummyToken);
1686 		actualSum.add(ThrownType.create(
1687 				dummyToken,
1688 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1689 		actualSum.add(ThrownType.create(
1690 				dummyToken,
1691 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1692 		
1693 		final List<Type> standardizeElements = actualSum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
1694 			
1695 			@Override
1696 			public List<Type> handle(final AtomicType atomicType) {
1697 				return new ArrayList<>();
1698 			}
1699 			
1700 			@Override
1701 			public List<Type> handle(final CompositeType compositeType) {
1702 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
1703 					
1704 					@Override
1705 					public List<Type> handle(final ListType list) {
1706 						return new ArrayList<>();
1707 					}
1708 					
1709 					@Override
1710 					public List<Type> handle(final MapType map) {
1711 						return new ArrayList<>();
1712 					}
1713 					
1714 					@Override
1715 					public List<Type> handle(final ProductType product) {
1716 						return new ArrayList<>();
1717 					}
1718 					
1719 					@Override
1720 					public List<Type> handle(final SumType sum2) {
1721 						return sum2.getElements();
1722 					}
1723 					
1724 					@Override
1725 					public List<Type> handle(final ThrownType thrownType) {
1726 						return new ArrayList<>();
1727 					}
1728 				});
1729 			}
1730 			
1731 			@Override
1732 			public List<Type> handle(final TypeProxy typeProxy) {
1733 				return new ArrayList<>();
1734 			}
1735 		});
1736 		
1737 		// Prepare Expected
1738 		final SumType expectedSum = SumType.create(dummyToken);
1739 		expectedSum.add(ThrownType.create(
1740 				dummyToken,
1741 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1742 		expectedSum.add(ThrownType.create(
1743 				dummyToken,
1744 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1745 		
1746 		// Test
1747 		assertEquals(2, standardizeElements.size());
1748 		assertEquals(2, expectedSum.getElements().size());
1749 		this.assertEqualsOnlists(standardizeElements, expectedSum.getElements());
1750 	}
1751 	
1752 	/**
1753 	 * {A!,B!,A!} => Result: {A!,B!}.
1754 	 * 
1755 	 * @throws SumIsAnythingException
1756 	 *             If it contains Anything throw specified Exception
1757 	 */
1758 	@Test
1759 	public void testDoubleThrownElements() throws SumIsAnythingException {
1760 		
1761 		final Token dummyToken = DummyToken.getInstance();
1762 		final Position dummyPosition = DummyToken.getDummyPosition();
1763 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1764 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1765 		
1766 		// Prepare Actual
1767 		final SumType actualSum = SumType.create(dummyToken);
1768 		actualSum.add(ThrownType.create(
1769 				dummyToken,
1770 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1771 		actualSum.add(ThrownType.create(
1772 				dummyToken,
1773 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1774 		actualSum.add(ThrownType.create(
1775 				dummyToken,
1776 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1777 		
1778 		final List<Type> standardizeElements = actualSum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
1779 			
1780 			@Override
1781 			public List<Type> handle(final AtomicType atomicType) {
1782 				return new ArrayList<>();
1783 			}
1784 			
1785 			@Override
1786 			public List<Type> handle(final CompositeType compositeType) {
1787 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
1788 					
1789 					@Override
1790 					public List<Type> handle(final ListType list) {
1791 						return new ArrayList<>();
1792 					}
1793 					
1794 					@Override
1795 					public List<Type> handle(final MapType map) {
1796 						return new ArrayList<>();
1797 					}
1798 					
1799 					@Override
1800 					public List<Type> handle(final ProductType product) {
1801 						return new ArrayList<>();
1802 					}
1803 					
1804 					@Override
1805 					public List<Type> handle(final SumType sum2) {
1806 						return sum2.getElements();
1807 					}
1808 					
1809 					@Override
1810 					public List<Type> handle(final ThrownType thrownType) {
1811 						return new ArrayList<>();
1812 					}
1813 				});
1814 			}
1815 			
1816 			@Override
1817 			public List<Type> handle(final TypeProxy typeProxy) {
1818 				return new ArrayList<>();
1819 			}
1820 		});
1821 		
1822 		// Prepare Expected
1823 		final SumType expectedSum = SumType.create(dummyToken);
1824 		expectedSum.add(ThrownType.create(
1825 				dummyToken,
1826 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1827 		expectedSum.add(ThrownType.create(
1828 				dummyToken,
1829 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1830 		
1831 		// Test
1832 		assertEquals(2, standardizeElements.size());
1833 		assertEquals(2, expectedSum.getElements().size());
1834 		this.assertEqualsOnlists(standardizeElements, expectedSum.getElements());
1835 		
1836 	}
1837 	
1838 	/**
1839 	 * {A!,B!,C}! => Result: {A!,B!,C!}.
1840 	 * 
1841 	 * @throws SumIsAnythingException
1842 	 *             If it contains Anything throw specified Exception
1843 	 */
1844 	@Test
1845 	public void testThrownSumContainingThrownTypesAndNormalType() throws SumIsAnythingException {
1846 		
1847 		final Token dummyToken = DummyToken.getInstance();
1848 		final Position dummyPosition = DummyToken.getDummyPosition();
1849 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
1850 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
1851 		final IdentifierToken c = IdentifierToken.create("C", dummyPosition);
1852 		
1853 		// Prepare Actual
1854 		final SumType actualSum = SumType.create(dummyToken);
1855 		actualSum.add(ThrownType.create(
1856 				dummyToken,
1857 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1858 		actualSum.add(ThrownType.create(
1859 				dummyToken,
1860 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1861 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(c))));
1862 		
1863 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1864 		
1865 		final Type standardizedType = thrownType.standardize();
1866 		
1867 		// Prepare Expected
1868 		final SumType expectedSum = SumType.create(dummyToken);
1869 		expectedSum.add(ThrownType.create(
1870 				dummyToken,
1871 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a)))));
1872 		expectedSum.add(ThrownType.create(
1873 				dummyToken,
1874 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
1875 		expectedSum.add(ThrownType.create(
1876 				dummyToken,
1877 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(c)))));
1878 		
1879 		// Test
1880 		assertTrue(standardizedType instanceof SumType);
1881 		final SumType sum = (SumType) standardizedType;
1882 		assertEquals(3, sum.getElements().size());
1883 		assertEquals(3, expectedSum.getElements().size());
1884 		this.assertEqualsOnlists(sum.getElements(), expectedSum.getElements());
1885 	}
1886 	
1887 	/**
1888 	 * {(x:String, y:Integer)}! => Result: Error.
1889 	 * 
1890 	 * @throws SumIsAnythingException
1891 	 *             If it contains Anything throw specified Exception
1892 	 */
1893 	@Test
1894 	public void testThrownSumContainingProductType() throws SumIsAnythingException {
1895 		
1896 		final Token dummyToken = DummyToken.getInstance();
1897 		final Position dummyPosition = DummyToken.getDummyPosition();
1898 		final IdentifierToken string = IdentifierToken.create("String", dummyPosition);
1899 		final IdentifierToken integer = IdentifierToken.create("Integer", dummyPosition);
1900 		
1901 		// Prepare Actual
1902 		final SumType actualSum = SumType.create(dummyToken);
1903 		final ProductType actualProduct = ProductType.create(dummyToken);
1904 		actualProduct.addElement(ProductElementType.create(
1905 				"x",
1906 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(string))),
1907 				dummyToken));
1908 		actualProduct.addElement(ProductElementType.create(
1909 				"y",
1910 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(integer))),
1911 				dummyToken));
1912 		actualSum.add(actualProduct);
1913 		
1914 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1915 		
1916 		try {
1917 			thrownType.standardize();
1918 			
1919 			assertFalse(true);
1920 		} catch (final ASTException e) {
1921 			assertTrue(true);
1922 			assertEquals("A product can not be thrown.", e.getMessage());
1923 		}
1924 	}
1925 	
1926 	/**
1927 	 * {(x:String, y:Integer),(a:Integer,b:String)}! => Result: Error.
1928 	 * 
1929 	 * @throws SumIsAnythingException
1930 	 *             If it contains Anything throw specified Exception
1931 	 */
1932 	@Test
1933 	public void testThrownSumContainingProductTypes() throws SumIsAnythingException {
1934 		
1935 		final Token dummyToken = DummyToken.getInstance();
1936 		final Position dummyPosition = DummyToken.getDummyPosition();
1937 		final IdentifierToken string = IdentifierToken.create("String", dummyPosition);
1938 		final IdentifierToken integer = IdentifierToken.create("Integer", dummyPosition);
1939 		
1940 		// Prepare Actual
1941 		final SumType actualSum = SumType.create(dummyToken);
1942 		final ProductType actualFirstProduct = ProductType.create(dummyToken);
1943 		actualFirstProduct.addElement(ProductElementType.create(
1944 				"x",
1945 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(string))),
1946 				dummyToken));
1947 		actualFirstProduct.addElement(ProductElementType.create(
1948 				"y",
1949 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(integer))),
1950 				dummyToken));
1951 		actualSum.add(actualFirstProduct);
1952 		final ProductType actualSecondProduct = ProductType.create(dummyToken);
1953 		actualSecondProduct.addElement(ProductElementType.create(
1954 				"a",
1955 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(integer))),
1956 				dummyToken));
1957 		actualSecondProduct.addElement(ProductElementType.create(
1958 				"b",
1959 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(string))),
1960 				dummyToken));
1961 		actualSum.add(actualSecondProduct);
1962 		
1963 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1964 		
1965 		try {
1966 			thrownType.standardize();
1967 			
1968 			assertFalse(true);
1969 		} catch (final ASTException e) {
1970 			assertTrue(true);
1971 			assertEquals("A product can not be thrown.", e.getMessage());
1972 		}
1973 	}
1974 	
1975 	/**
1976 	 * {C*}! => Result: Error.
1977 	 * 
1978 	 * @throws SumIsAnythingException
1979 	 *             If it contains Anything throw specified Exception
1980 	 */
1981 	@Test
1982 	public void testThrownSumContainingList() throws SumIsAnythingException {
1983 		
1984 		final Token dummyToken = DummyToken.getInstance();
1985 		final Position dummyPosition = DummyToken.getDummyPosition();
1986 		final IdentifierToken c = IdentifierToken.create("C", dummyPosition);
1987 		
1988 		// Prepare Actual
1989 		final SumType actualSum = SumType.create(dummyToken);
1990 		final ListType actualList =
1991 				ListType.create(dummyToken, TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(c))));
1992 		actualSum.add(actualList);
1993 		
1994 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
1995 		
1996 		try {
1997 			thrownType.standardize();
1998 			
1999 			assertFalse(true);
2000 		} catch (final ASTException e) {
2001 			assertTrue(true);
2002 			assertEquals("A list can not be thrown.", e.getMessage());
2003 		}
2004 	}
2005 	
2006 	/**
2007 	 * {C*, A*}! => Result: Error.
2008 	 * 
2009 	 * @throws SumIsAnythingException
2010 	 *             If it contains Anything throw specified Exception
2011 	 */
2012 	@Test
2013 	public void testThrownSumContainingLists() throws SumIsAnythingException {
2014 		
2015 		final Token dummyToken = DummyToken.getInstance();
2016 		final Position dummyPosition = DummyToken.getDummyPosition();
2017 		final IdentifierToken c = IdentifierToken.create("C", dummyPosition);
2018 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
2019 		
2020 		// Prepare Actual
2021 		final SumType actualSum = SumType.create(dummyToken);
2022 		final ListType actualFirstList =
2023 				ListType.create(dummyToken, TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(c))));
2024 		actualSum.add(actualFirstList);
2025 		final ListType actualSecondList =
2026 				ListType.create(dummyToken, TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
2027 		actualSum.add(actualSecondList);
2028 		
2029 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
2030 		
2031 		try {
2032 			thrownType.standardize();
2033 			
2034 			assertFalse(true);
2035 		} catch (final ASTException e) {
2036 			assertTrue(true);
2037 			assertEquals("A list can not be thrown.", e.getMessage());
2038 		}
2039 	}
2040 	
2041 	/**
2042 	 * {B!,B,B,B!} => Result: {B,B!}.
2043 	 * 
2044 	 * @throws SumIsAnythingException
2045 	 *             If it contains Anything throw specified Exception
2046 	 */
2047 	@Test
2048 	public void testSumTypesManyTimes() throws SumIsAnythingException {
2049 		
2050 		final Token dummyToken = DummyToken.getInstance();
2051 		final Position dummyPosition = DummyToken.getDummyPosition();
2052 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
2053 		
2054 		// Prepare Actual
2055 		final SumType actualSum = SumType.create(dummyToken);
2056 		actualSum.add(ThrownType.create(
2057 				dummyToken,
2058 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
2059 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
2060 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
2061 		actualSum.add(ThrownType.create(
2062 				dummyToken,
2063 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
2064 		
2065 		final List<Type> standardizeElements = actualSum.standardize().accept(new TypeVisitorReturn<List<Type>>() {
2066 			
2067 			@Override
2068 			public List<Type> handle(final AtomicType atomicType) {
2069 				return new ArrayList<>();
2070 			}
2071 			
2072 			@Override
2073 			public List<Type> handle(final CompositeType compositeType) {
2074 				return compositeType.accept(new CompositeTypeVisitorReturn<List<Type>>() {
2075 					
2076 					@Override
2077 					public List<Type> handle(final ListType list) {
2078 						return new ArrayList<>();
2079 					}
2080 					
2081 					@Override
2082 					public List<Type> handle(final MapType map) {
2083 						return new ArrayList<>();
2084 					}
2085 					
2086 					@Override
2087 					public List<Type> handle(final ProductType product) {
2088 						return new ArrayList<>();
2089 					}
2090 					
2091 					@Override
2092 					public List<Type> handle(final SumType sum2) {
2093 						return sum2.getElements();
2094 					}
2095 					
2096 					@Override
2097 					public List<Type> handle(final ThrownType thrownType) {
2098 						return new ArrayList<>();
2099 					}
2100 				});
2101 			}
2102 			
2103 			@Override
2104 			public List<Type> handle(final TypeProxy typeProxy) {
2105 				return new ArrayList<>();
2106 			}
2107 		});
2108 		
2109 		// Prepare Expected
2110 		final SumType expectedSum = SumType.create(dummyToken);
2111 		expectedSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
2112 		expectedSum.add(ThrownType.create(
2113 				dummyToken,
2114 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
2115 		
2116 		// Test
2117 		assertEquals(2, standardizeElements.size());
2118 		assertEquals(2, expectedSum.getElements().size());
2119 		this.assertEqualsOnlists(standardizeElements, expectedSum.getElements());
2120 	}
2121 	
2122 	/**
2123 	 * {B!,B,B,B!}! => Result: {B!}.
2124 	 * 
2125 	 * @throws SumIsAnythingException
2126 	 *             If it contains Anything throw specified Exception
2127 	 */
2128 	@Test
2129 	public void testThrownSumTypesManyTimes() throws SumIsAnythingException {
2130 		
2131 		final Token dummyToken = DummyToken.getInstance();
2132 		final Position dummyPosition = DummyToken.getDummyPosition();
2133 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
2134 		
2135 		// Prepare Actual
2136 		final SumType actualSum = SumType.create(dummyToken);
2137 		actualSum.add(ThrownType.create(
2138 				dummyToken,
2139 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
2140 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
2141 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
2142 		actualSum.add(ThrownType.create(
2143 				dummyToken,
2144 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
2145 		
2146 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
2147 		
2148 		final Type actualType = thrownType.standardize();
2149 		
2150 		// Prepare Expected
2151 		final SumType expectedSum = SumType.create(dummyToken);
2152 		expectedSum.add(ThrownType.create(
2153 				dummyToken,
2154 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
2155 		
2156 		// Test
2157 		assertTrue(actualType instanceof SumType);
2158 		final SumType standardizedSum = (SumType) actualType;
2159 		assertEquals(1, standardizedSum.getElements().size());
2160 		assertEquals(1, expectedSum.getElements().size());
2161 		this.assertEqualsOnlists(standardizedSum.getElements(), expectedSum.getElements());
2162 	}
2163 	
2164 	/**
2165 	 * {A*,(x:String,b:String),B!,B,B,B!,[A->Integer]}! => Result: Error
2166 	 * 
2167 	 * @throws SumIsAnythingException
2168 	 *             If it contains Anything throw specified Exception
2169 	 */
2170 	@Test
2171 	public void testThrownSumContainingDifferentTypes() throws SumIsAnythingException {
2172 		
2173 		final Token dummyToken = DummyToken.getInstance();
2174 		final Position dummyPosition = DummyToken.getDummyPosition();
2175 		final IdentifierToken c = IdentifierToken.create("C", dummyPosition);
2176 		final IdentifierToken a = IdentifierToken.create("A", dummyPosition);
2177 		final IdentifierToken string = IdentifierToken.create("String", dummyPosition);
2178 		final IdentifierToken integer = IdentifierToken.create("Integer", dummyPosition);
2179 		final IdentifierToken b = IdentifierToken.create("B", dummyPosition);
2180 		
2181 		// Prepare Actual
2182 		final SumType actualSum = SumType.create(dummyToken);
2183 		
2184 		final ListType actualFirstList =
2185 				ListType.create(dummyToken, TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))));
2186 		actualSum.add(actualFirstList);
2187 		
2188 		final ProductType actualSecondProduct = ProductType.create(dummyToken);
2189 		actualSecondProduct.addElement(ProductElementType.create(
2190 				"x",
2191 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(string))),
2192 				dummyToken));
2193 		actualSecondProduct.addElement(ProductElementType.create(
2194 				"b",
2195 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(string))),
2196 				dummyToken));
2197 		actualSum.add(actualSecondProduct);
2198 		
2199 		actualSum.add(ThrownType.create(
2200 				dummyToken,
2201 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
2202 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
2203 		actualSum.add(TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b))));
2204 		actualSum.add(ThrownType.create(
2205 				dummyToken,
2206 				TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(b)))));
2207 		
2208 		final MapType actualFirstMap =
2209 				MapType.create(
2210 						dummyToken,
2211 						TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(a))),
2212 						TypeProxy.create(dummyToken, ByNameState.create(UnqualifiedName.create(integer))));
2213 		actualSum.add(actualFirstMap);
2214 		
2215 		final ThrownType thrownType = ThrownType.create(DummyToken.getInstance(), actualSum, DummyToken.getInstance());
2216 		
2217 		try {
2218 			thrownType.standardize();
2219 			
2220 			assertFalse(true);
2221 		} catch (final ASTException e) {
2222 			assertTrue(true);
2223 			assertEquals("A list can not be thrown.", e.getMessage());
2224 		}
2225 	}
2226 	
2227 	/**
2228 	 * Check if the two Lists of types are the same.
2229 	 * 
2230 	 * @param expected
2231 	 *            the first List with the elements, who are expected.
2232 	 * @param actual
2233 	 *            the list with the elements, who are actual there.
2234 	 */
2235 	private void assertEqualsOnlists(final List<Type> expected, final List<Type> actual) {
2236 		
2237 		assertEquals(expected.size(), actual.size());
2238 		
2239 		for (int i = 0; i < expected.size(); i++) {
2240 			final Type currentExpected = expected.get(i);
2241 			final Type currentActual = actual.get(i);
2242 			
2243 			assertEquals(currentExpected, currentActual);
2244 		}
2245 	}
2246 }