code: @Override
  	public double calculateExpectedAgreement() {
  		Map<Object, int[]> annotationsPerCategory
  				= CodingAnnotationStudy.countAnnotationsPerCategory(study);
  		BigDecimal result = BigDecimal.ZERO;
  		for (Object category : study.getCategories()) {
  			int[] annotationCounts = annotationsPerCategory.get(category);
  			for (int m = 0; m < study.getRaterCount(); m++)
  				for (int n = m + 1; n < study.getRaterCount(); n++)
  					result = result.add(new BigDecimal(annotationCounts[m])
  							.multiply(new BigDecimal(annotationCounts[n])));
  		}
  		result = result.multiply(new BigDecimal(2));
  		result = result.divide(new BigDecimal(study.getRaterCount())
  				.multiply(new BigDecimal(study.getRaterCount() - 1))
  				.multiply(new BigDecimal(study.getItemCount()).pow(2)),
  				MathContext.DECIMAL128);
  		return result.doubleValue();
  	}
  
  }
docs: Calculates the expected inter-rater agreement that assumes the same
  distribution for all raters and annotations.
  @throws NullPointerException if the annotation study is null.
  @throws ArithmeticException if there are no items in the
  annotation study.