/**
  * Returns data for annotations attached to current representation
  *
  * @param array $pa_options Optional array of options. Supported options are:
  *			checkAccess = array of access codes to filter count by. Only annotations with an access value set to one of the specified values will be returned
  *			start =
  *			max = 
  *			labelsOnly =
  * @return array List of annotations attached to the current representation, key'ed on annotation_id. Value is an array will all values; annotation labels are returned in the current locale.
  */
 public function getAnnotations($pa_options = null)
 {
     if (!($vn_representation_id = $this->getPrimaryKey())) {
         return null;
     }
     if (!is_array($pa_options)) {
         $pa_options = array();
     }
     if (!($o_coder = $this->getAnnotationPropertyCoderInstance($this->getAnnotationType()))) {
         // does not support annotations
         return null;
     }
     $o_db = $this->getDb();
     $vs_access_sql = '';
     if (is_array($pa_options['checkAccess']) && sizeof($pa_options['checkAccess'])) {
         $vs_access_sql = ' AND cra.access IN (' . join(',', $pa_options['checkAccess']) . ')';
     }
     $qr_annotations = $o_db->query("\n \t\t\tSELECT \tcra.annotation_id, cra.locale_id, cra.props, cra.representation_id, cra.user_id, cra.type_code, cra.access, cra.status\n \t\t\tFROM ca_representation_annotations cra\n \t\t\tWHERE\n \t\t\t\tcra.representation_id = ? {$vs_access_sql}\n \t\t", (int) $vn_representation_id);
     $vs_sort_by_property = $this->getAnnotationSortProperty();
     $va_annotations = array();
     $vn_start = caGetOption('start', $pa_options, 0, array('castTo' => 'int'));
     $vn_max = caGetOption('max', $pa_options, 100, array('castTo' => 'int'));
     $va_annotation_ids = array();
     while ($qr_annotations->nextRow()) {
         $va_tmp = $qr_annotations->getRow();
         $va_annotation_ids[] = $va_tmp['annotation_id'];
         unset($va_tmp['props']);
         $o_coder->setPropertyValues($qr_annotations->getVars('props'));
         foreach ($o_coder->getPropertyList() as $vs_property) {
             $va_tmp[$vs_property] = $o_coder->getProperty($vs_property);
             $va_tmp[$vs_property . '_raw'] = $o_coder->getProperty($vs_property, true);
             //if ($va_tmp[$vs_property] == $va_tmp[$vs_property.'_raw']) { unset($va_tmp[$vs_property.'_raw']); }
         }
         if (!($vs_sort_key = $va_tmp[$vs_sort_by_property])) {
             $vs_sort_key = '_default_';
         }
         $va_annotations[$vs_sort_key][$va_tmp['annotation_id']] = $va_tmp;
     }
     if (!sizeof($va_annotation_ids)) {
         return array();
     }
     ksort($va_annotations, SORT_NUMERIC);
     // get annotation labels
     $qr_annotations = caMakeSearchResult('ca_representation_annotations', $va_annotation_ids);
     $va_labels = $va_annotation_classes = array();
     // Check if "class" element is configurwed, exists and is a list element
     if ($vs_class_element = $this->getAppConfig()->get('annotation_class_element')) {
         $t_anno = new ca_representation_annotations();
         if (!$t_anno->hasElement($vs_class_element)) {
             $vs_class_element = null;
         } elseif ($t_anno->_getElementDatatype($vs_class_element) != __CA_ATTRIBUTE_VALUE_LIST__) {
             // not a list element
             $vs_class_element = null;
         }
     }
     while ($qr_annotations->nextHit()) {
         $va_labels[$vn_annotation_id = $qr_annotations->get('ca_representation_annotations.annotation_id')][$qr_annotations->get('ca_representation_annotation_labels.locale_id')][] = $qr_annotations->get('ca_representation_annotations.preferred_labels.name');
         if ($vs_class_element) {
             $va_annotation_classes[$vn_annotation_id] = $qr_annotations->get("ca_representation_annotations.{$vs_class_element}", array('returnAsArray' => true));
         }
     }
     $va_labels_for_locale = caExtractValuesByUserLocale($va_labels);
     $va_annotation_classes_flattened = array();
     foreach ($va_annotation_classes as $vn_annotation_id => $va_classes) {
         $va_annotation_classes_flattened[$vn_annotation_id] = array_shift($va_classes);
     }
     $va_key = array();
     if ($qr_list_items = caMakeSearchResult('ca_list_items', array_values($va_annotation_classes_flattened))) {
         while ($qr_list_items->nextHit()) {
             $va_key[$qr_list_items->get('item_id')] = array('name' => $qr_list_items->get('ca_list_items.preferred_labels.name_plural'), 'idno' => $qr_list_items->get('ca_list_items.idno'), 'color' => $qr_list_items->get('ca_list_items.color'));
         }
     }
     $va_sorted_annotations = array();
     foreach ($va_annotations as $vs_key => $va_values) {
         foreach ($va_values as $va_val) {
             $vs_label = is_array($va_labels_for_locale[$va_val['annotation_id']]) ? array_shift($va_labels_for_locale[$va_val['annotation_id']]) : '';
             $va_val['labels'] = $va_labels[$va_val['annotation_id']] ? $va_labels[$va_val['annotation_id']] : array();
             $va_val['label'] = $vs_label;
             $va_val['key'] = $va_key[$va_annotation_classes_flattened[$va_val['annotation_id']]];
             $va_sorted_annotations[$va_val['annotation_id']] = $va_val;
         }
     }
     if ($vn_start > 0 || $vn_max > 0) {
         if ($vn_max > 0) {
             $va_sorted_annotations = array_slice($va_sorted_annotations, $vn_start, $vn_max);
         } else {
             $va_sorted_annotations = array_slice($va_sorted_annotations, $vn_start);
         }
     }
     return $va_sorted_annotations;
 }