code: package cgm.util.generator;
  
  import static org.junit.Assert.*;
  
  import java.util.HashSet;
  import java.util.Set;
  
  import org.junit.Test;
  
  import cgm.CGM;
  import cgm.Context;
  import cgm.Refinement;
  import cgm.util.generator.RandomCGMGenerator;
  import cgm.util.generator.WorstCaseCGMGenerator;
  
  public class WorstCaseCGMGeneratorTest {
  	WorstCaseCGMGenerator cgmFactory = new WorstCaseCGMGenerator();
  	
  	@Test
  	public void shouldCreateASingleTask() {
  		CGM cgm = cgmFactory.generateCGM(1, 2);
  
  		assertTrue(cgm.getRoot().myType() == Refinement.TASK);
  		assertEquals(1, countTreeLevels(cgm.getRoot(), 0));
  	}
  
  	@Test
  	public void shouldCreateASingleGoalWithASingleTask() {
  		CGM cgm = cgmFactory.generateCGM(2, 2);
  
  		assertTrue(cgm.getRoot().myType() == Refinement.GOAL);
  
  		for (Refinement dep : cgm.getRoot().getDependencies()) {
  			assertTrue(dep.myType() == Refinement.TASK);
  		}
  		assertEquals(2, countTreeLevels(cgm.getRoot(), 0));
  	}
  
  	@Test
  	public void shouldCreateASingleCGMWithTwoLevels() {
  
  		CGM cgm = cgmFactory.generateCGM(3, 2);
  
  		assertEquals(3, countRefinements(cgm.getRoot()));
  		assertEquals(2, countTreeLevels(cgm.getRoot(), 0));
  	}
  
  	@Test
  	public void shouldCreateLargerCGMs() {
  
  		for (int i = 1; i < 100; i++) {
  			CGM cgm = cgmFactory.generateCGM(3 * i, 1);
  			assertEquals(3 * i, countRefinements(cgm.getRoot()));
  		}
  	}
  
  	@Test
  	public void shouldCreateAVeryLargeCGM() {
  
  		CGM cgm = cgmFactory.generateCGM(4095, 1);
  		assertEquals(4095, countRefinements(cgm.getRoot()));
  		assertEquals(12, countTreeLevels(cgm.getRoot(), 0));
  	}
  
  	@Test
  	public void shouldCreateCGMWithManyContexts() {
  
  		CGM cgm = cgmFactory.generateCGM(1000, 30);
  
  		assertEquals(30, collectContexts(cgm.getRoot()).size()); 	
  	}
  	
  	private Set<Context> collectContexts(Refinement root) {
  		HashSet<Context> contextSet = new HashSet<Context>();
  
  		contextSet.addAll(root.getApplicableContext());
  		for (Refinement dep : root.getDependencies()) {
  			contextSet.addAll(collectContexts(dep));
  		}
  		contextSet.remove(null);
  		return contextSet;
  	}
  
  	private int countRefinements(Refinement refinement) {
  		int amount = 1;
  
  		for (Refinement dep : refinement.getDependencies()) {
  			amount = amount + countRefinements(dep);
  		}
  		return amount;
  	}
  
  	private int countTreeLevels(Refinement refinement, int currentLevel) {
  		int amount = 1;
  		int maxLevels = 0;
  
  		for (Refinement dep : refinement.getDependencies()) {
  			int levelsBelow = countTreeLevels(dep, currentLevel++);
  			if (maxLevels < levelsBelow)
  				maxLevels = levelsBelow;
  		}
  
  		return amount + maxLevels;
  	}
  
  }
  