code: package com.quui.tm2;
  
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertFalse;
  
  import java.math.BigInteger;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  import org.junit.Test;
  
  import com.quui.tm2.ImmutableAnnotation;
  
  public final class AnnotationTest {
      @Test
      public void string() {
          /*
           * We rely on a transformability of the value object to and from String
           * objects, this works for the typical values that implement comparable:
           */
          Float f = 3.2f;
          assertEquals(f, new Float(f.toString()));
          Double d = 3.009;
          assertEquals(d, new Double(d.toString()));
          BigInteger b = BigInteger.valueOf(55);
          assertEquals(b, new BigInteger(b.toString()));
          String s = "Hi";
          assertEquals(s, new String(s.toString()));
      }
  
      /**
       * Equal in value, start and end.
       */
      @Test
      public void equals() {
          ImmutableAnnotation<String> s1 = ImmutableAnnotation.getInstance(null,
                  "Test", 0, 1);
          ImmutableAnnotation<String> s2 = ImmutableAnnotation.getInstance(null, 
                  "Test", 0, 1);
          assertEquals("Equal annotations are not equal!", s1, s2);
      }
  
      /**
       * Different start index.
       */
      @Test
      public void nonEqual1() {
          ImmutableAnnotation<String> s1 = ImmutableAnnotation.getInstance(null,
                  "Test", 0, 1);
          ImmutableAnnotation<String> s2 = ImmutableAnnotation.getInstance(null,
                  "Test", 1, 1);
          assertFalse("Unequal annotations are equal!", s1.equals(s2));
      }
  
      /**
       * Different end index.
       */
      @Test
      public void nonEqual2() {
          ImmutableAnnotation<String> s1 = ImmutableAnnotation.getInstance(null,
                  "TesT", 0, 1);
          ImmutableAnnotation<String> s2 = ImmutableAnnotation.getInstance(null,
                  "Test", 0, 2);
          assertFalse("Unequal annotations are equal!", s1.equals(s2));
      }
  
      /**
       * Different value.
       */
      @Test
      public void nonEqual3() {
          ImmutableAnnotation<String> s1 = ImmutableAnnotation.getInstance(null,
                  "Tesl", 0, 1);
          ImmutableAnnotation<String> s2 = ImmutableAnnotation.getInstance(null,
                  "Test", 0, 1);
          assertFalse("Unequal annotations are equal!", s1.equals(s2));
      }
  
      /**
       * Different value type.
       */
      @Test
      public void notComparable() {
          ImmutableAnnotation<String> s1 = ImmutableAnnotation.getInstance(null,
                  "Test", 0, 1);
          ImmutableAnnotation<Integer> s2 = ImmutableAnnotation.getInstance(null,
                  1, 0, 1);
          assertFalse("Unequal annotations are equal!", s1.equals(s2));
      }
  
      /**
       * Equal elements in a set are not duplicated (tests hashCode).
       */
      @Test
      public void set() {
          Set<ImmutableAnnotation<String>> set = new HashSet<ImmutableAnnotation<String>>();
          set.add(ImmutableAnnotation.getInstance(null, "Test", 0, 1));
          set.add(ImmutableAnnotation.getInstance(null, "Test", 0, 1));
          assertEquals("Set contains duplicate entries;", 1, set.size());
      }
  
      /**
       * Sorting order using Collections.sort()
       */
      @Test
      // TODO Also test sorted collections, as they work differently
      public void sort() {
          List<ImmutableAnnotation<String>> list = new ArrayList<ImmutableAnnotation<String>>();
          /* We create in the reverse order: */
          ImmutableAnnotation<String> a0 = ImmutableAnnotation.getInstance(null,
                  "Test2", 0, 1);
          ImmutableAnnotation<String> a1 = ImmutableAnnotation.getInstance(null,
                  "Test1", 1, 1);
          ImmutableAnnotation<String> a2 = ImmutableAnnotation.getInstance(null,
                  "Test1", 0, 2);
          ImmutableAnnotation<String> a3 = ImmutableAnnotation.getInstance(null,
                  "Test1", 0, 1);
          list.add(a0);
          list.add(a1);
          list.add(a2);
          list.add(a3);
          Collections.sort(list);
          String message = "List not sorted correctly;";
          assertEquals(message, a3, list.get(0));
          assertEquals(message, a2, list.get(1));
          assertEquals(message, a1, list.get(2));
          assertEquals(message, a0, list.get(3));
      }
  }
  