// Path: dkpro-statistics-agreement/src/main/java/org/dkpro/statistics/agreement/AnnotationStudy.java
// public abstract class AnnotationStudy
//     implements IAnnotationStudy
// {
//     private static final long serialVersionUID = -3596722258510421730L;
//     
//     protected List<String> raters;
//     protected Set<Object> categories;
// 
//     protected AnnotationStudy()
//     {
//         raters = new ArrayList<String>();
//         categories = new LinkedHashSet<Object>();
//     }
// 
//     /**
//      * Add a rater with the given name. Returns the index of the newly added rater which is required
//      * to identify the rater in {@link IAnnotationUnit}. The first rater receives index 0. Note that
//      * adding names for the raters is optional.
//      */
//     public int addRater(final String name)
//     {
//         raters.add(name);
//         return (raters.size() - 1);
//     }
// 
//     /** Find the index of the rater with the given name. */
//     public int findRater(final String name)
//     {
//         return raters.indexOf(name);
//     }
// 
//     @Override
//     public int getRaterCount()
//     {
//         return raters.size();
//     }
// 
//     /**
//      * Adds the given category to the set of possible annotation labels. This method is only
//      * required of a category has not been used by any rater of within the annotation study.
//      * 
//      * @throws NullPointerException
//      *             if the specified category is null.
//      */
//     public void addCategory(final Object category)
//     {
//         categories.add(category);
//     }
// 
//     @Override
//     public Iterable<Object> getCategories()
//     {
//         return categories;
//     }
// 
//     /*
//      * public Object[] getCategoryArray() { Object[] result = null; int idx = 0; for (Object
//      * category : getCategories()) { if (result == null) result = new Object[categories.size()];
//      * result[idx++] = category; } return result; }
//      */
// 
//     @Override
//     public int getCategoryCount()
//     {
//         return categories.size();
//     }
// 
//     @Override
//     public boolean isDichotomous()
//     {
//         return (categories.size() == 2);
//     }
// }
// 
// Path: dkpro-statistics-agreement/src/main/java/org/dkpro/statistics/agreement/AnnotationUnit.java
// public class AnnotationUnit
//     implements IAnnotationUnit
// {
//     private static final long serialVersionUID = 4277733312128063453L;
//     
//     protected int raterIdx;
//     protected Object category;
// 
//     /**
//      * Initializes the annotation unit with the given category as the annotation by the rater with
//      * the specified index.
//      */
//     public AnnotationUnit(int raterIdx, final Object category)
//     {
//         this.raterIdx = raterIdx;
//         this.category = category;
//     }
// 
//     @Override
//     public int getRaterIdx()
//     {
//         return raterIdx;
//     }
// 
//     @Override
//     public Object getCategory()
//     {
//         return category;
//     }
// 
//     @Override
//     public String toString()
//     {
//         return raterIdx + "<" + category + ">";
//     }
// }
// 
// Path: dkpro-statistics-agreement/src/main/java/org/dkpro/statistics/agreement/IAnnotationUnit.java
// public interface IAnnotationUnit
//     extends Serializable
// {
//     /**
//      * Returns the index of the rater who coded this unit (in case of a coding study) or defined the
//      * boundaries of this unit (in case of a unitizing study). The first rater has index 0.
//      */
//     public int getRaterIdx();
// 
//     /**
//      * Returns the category assigned to this unit by one of the raters. The category might be null
//      * if, and only if, the unit represents a missing value (in case of a coding study) or a gap (in
//      * case of a unitizing study).
//      */
//     public Object getCategory();
// }


import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.dkpro.statistics.agreement.AnnotationStudy;
import org.dkpro.statistics.agreement.AnnotationUnit;
import org.dkpro.statistics.agreement.IAnnotationUnit;

    /**
     * Returns a two dimensional map of category pairs and their co-occurrence frequencies for the
     * given annotation item.
     */
    // Category x Category -> #
    public static Map<Object, Map<Object, Double>> countCategoryCoincidence(
            final ICodingAnnotationItem item)
    {
        Map<Object, Map<Object, Double>> result = new HashMap<Object, Map<Object, Double>>();
        for (IAnnotationUnit unit1 : item.getUnits()) {
            for (IAnnotationUnit unit2 : item.getUnits()) {
                if (unit1 == unit2) {
                    continue;
                }

                Object category1 = unit1.getCategory();
                Object category2 = unit2.getCategory();
                if (category1 == null || category2 == null) {
                    continue;
                }

                Map<Object, Double> cat1 = result.get(category1);
                if (cat1 == null) {
                    cat1 = new HashMap<Object, Double>();
                    result.put(category1, cat1);
                }

                Double value = cat1.get(category2);
                if (value == null) {
// Path: dkpro-statistics-agreement/src/main/java/org/dkpro/statistics/agreement/AnnotationStudy.java
// public abstract class AnnotationStudy
//     implements IAnnotationStudy
// {
//     private static final long serialVersionUID = -3596722258510421730L;
//     
//     protected List<String> raters;
//     protected Set<Object> categories;
// 
//     protected AnnotationStudy()
//     {
//         raters = new ArrayList<String>();
//         categories = new LinkedHashSet<Object>();
//     }
// 
//     /**
//      * Add a rater with the given name. Returns the index of the newly added rater which is required
//      * to identify the rater in {@link IAnnotationUnit}. The first rater receives index 0. Note that
//      * adding names for the raters is optional.
//      */
//     public int addRater(final String name)
//     {
//         raters.add(name);
//         return (raters.size() - 1);
//     }
// 
//     /** Find the index of the rater with the given name. */
//     public int findRater(final String name)
//     {
//         return raters.indexOf(name);
//     }
// 
//     @Override
//     public int getRaterCount()
//     {
//         return raters.size();
//     }
// 
//     /**
//      * Adds the given category to the set of possible annotation labels. This method is only
//      * required of a category has not been used by any rater of within the annotation study.
//      * 
//      * @throws NullPointerException
//      *             if the specified category is null.
//      */
//     public void addCategory(final Object category)
//     {
//         categories.add(category);
//     }
// 
//     @Override
//     public Iterable<Object> getCategories()
//     {
//         return categories;
//     }
// 
//     /*
//      * public Object[] getCategoryArray() { Object[] result = null; int idx = 0; for (Object
//      * category : getCategories()) { if (result == null) result = new Object[categories.size()];
//      * result[idx++] = category; } return result; }
//      */
// 
//     @Override
//     public int getCategoryCount()
//     {
//         return categories.size();
//     }
// 
//     @Override
//     public boolean isDichotomous()
//     {
//         return (categories.size() == 2);
//     }
// }
// 
// Path: dkpro-statistics-agreement/src/main/java/org/dkpro/statistics/agreement/AnnotationUnit.java
// public class AnnotationUnit
//     implements IAnnotationUnit
// {
//     private static final long serialVersionUID = 4277733312128063453L;
//     
//     protected int raterIdx;
//     protected Object category;
// 
//     /**
//      * Initializes the annotation unit with the given category as the annotation by the rater with
//      * the specified index.
//      */
//     public AnnotationUnit(int raterIdx, final Object category)
//     {
//         this.raterIdx = raterIdx;
//         this.category = category;
//     }
// 
//     @Override
//     public int getRaterIdx()
//     {
//         return raterIdx;
//     }
// 
//     @Override
//     public Object getCategory()
//     {
//         return category;
//     }
// 
//     @Override
//     public String toString()
//     {
//         return raterIdx + "<" + category + ">";
//     }
// }
// 
// Path: dkpro-statistics-agreement/src/main/java/org/dkpro/statistics/agreement/IAnnotationUnit.java
// public interface IAnnotationUnit
//     extends Serializable
// {
//     /**
//      * Returns the index of the rater who coded this unit (in case of a coding study) or defined the
//      * boundaries of this unit (in case of a unitizing study). The first rater has index 0.
//      */
//     public int getRaterIdx();
// 
//     /**
//      * Returns the category assigned to this unit by one of the raters. The category might be null
//      * if, and only if, the unit represents a missing value (in case of a coding study) or a gap (in
//      * case of a unitizing study).
//      */
//     public Object getCategory();
// }


// Path: dkpro-statistics-agreement/src/main/java/org/dkpro/statistics/agreement/coding/CodingAnnotationStudy.java
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.dkpro.statistics.agreement.AnnotationStudy;
import org.dkpro.statistics.agreement.AnnotationUnit;
import org.dkpro.statistics.agreement.IAnnotationUnit;


    /**
     * Returns a two dimensional map of category pairs and their co-occurrence frequencies for the
     * given annotation item.
     */
    // Category x Category -> #
    public static Map<Object, Map<Object, Double>> countCategoryCoincidence(
            final ICodingAnnotationItem item)
    {
        Map<Object, Map<Object, Double>> result = new HashMap<Object, Map<Object, Double>>();
        for (IAnnotationUnit unit1 : item.getUnits()) {
            for (IAnnotationUnit unit2 : item.getUnits()) {
                if (unit1 == unit2) {
                    continue;
                }

                Object category1 = unit1.getCategory();
                Object category2 = unit2.getCategory();
                if (category1 == null || category2 == null) {
                    continue;
                }

                Map<Object, Double> cat1 = result.get(category1);
                if (cat1 == null) {
                    cat1 = new HashMap<Object, Double>();
                    result.put(category1, cat1);
                }

                Double value = cat1.get(category2);
                if (value == null) {
                    cat1.put(category2, 1.0);