changeset 0:124ef8f3b22d

initial
author Dirk Wintergruen <dwinter@mpiwg-berlin.mpg.de>
date Fri, 27 Mar 2015 19:21:42 +0100
parents
children 06cb81c6eeec 1c73c660c2f2
files ISMIBioFilter/ISMIBioFilter.css ISMIBioFilter/ISMIBioFilter.info ISMIBioFilter/ISMIBioFilter.module ISMIBioFilter/ISMIObject-aliases.tpl.php ISMIBioFilter/ISMIPersons.inc ISMIBioFilter/ISMITitlesOfPerson.tpl.php ISMIBioFilter/ISMIWitnesses-list.tpl.php ISMIBioFilter/LICENSE.txt ISMIBioFilter/README.txt ISMIBioFilter/bio2ismi.txt importFromOpenMind/.DS_Store importFromOpenMind/.project importFromOpenMind/.pydevproject importFromOpenMind/converter/addDRI.py importFromOpenMind/importer/__init__.py importFromOpenMind/importer/filterISMI.py ismi_ext/ismi_ext.info ismi_ext/ismi_ext.module openmindattribute/LICENSE.txt openmindattribute/link-rtl.css openmindattribute/link.css openmindattribute/link.devel_generate.inc openmindattribute/link.diff.inc openmindattribute/link.migrate.inc openmindattribute/openmindattribute.info openmindattribute/openmindattribute.install openmindattribute/openmindattribute.module openmindattribute/openmindattribute.module~ openmindattribute/templates/openmindattribute-item-thumbnail.tpl.php openmindattribute/templates/openmindattribute_ALIAS.tpl.php openmindattribute/templates/openmindattribute_CODEX.tpl.php openmindattribute/templates/openmindattribute_MPIWG_viewer.tpl.php openmindattribute/templates/openmindattribute_PERSON.tpl.php openmindattribute/templates/openmindattribute_TEXT.tpl.php openmindattribute/templates/openmindattribute_WITNESS.tpl.php openmindattribute/templates/openmindattribute_ahlwardt.tpl.php openmindattribute/templates/openmindattribute_default.tpl.php openmindattribute/templates/openmindattribute_diva_link.tpl.php openmindattribute/templates/openmindattribute_full_title.tpl.php openmindattribute/templates/openmindattribute_full_title_translit_romanization.tpl.php openmindattribute/templates/openmindattribute_identifier.tpl.php openmindattribute/templates/openmindattribute_name.tpl.php openmindattribute/templates/openmindattribute_name_translit_romanization.tpl.php openmindattribute/templates/openmindattribute_reference_format.tpl.php openmindattribute/tests/link.attribute.test openmindattribute/tests/link.crud.test openmindattribute/tests/link.crud_browser.test openmindattribute/tests/link.test openmindattribute/tests/link.token.test openmindattribute/tests/link.validate.test openmindattribute/views/link.views.inc openmindattribute/views/link_views_handler_argument_target.inc openmindattribute/views/link_views_handler_filter_protocol.inc relation_processor/FeedsProcessor.inc relation_processor/FeedsRelationProcessor.inc relation_processor/FeedsRelationProcessor.inc~ relation_processor/nodes.inc relation_processor/relation_processor.info relation_processor/relation_processor.module transformBEA/.project transformBEA/.pydevproject
diffstat 59 files changed, 9841 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISMIBioFilter/ISMIBioFilter.css	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,7 @@
+p.style1 {
+	font-size: 15px;
+	font-weight: bold;
+}
+span.SpellE {
+	padding-left: 0.2em;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISMIBioFilter/ISMIBioFilter.info	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,14 @@
+name = ISMIBio filter
+description = Allows filters the content of the biographies
+package = "Input filters"
+core = 7.x
+
+; Information added by drupal.org packaging script on 2012-11-26
+version = "7.x-1.1"
+core = "7.x"
+;project = "markdown"
+;datestamp = "1353934650"
+
+
+stylesheets[all][] = ISMIBioFilter.css
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISMIBioFilter/ISMIBioFilter.module	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,659 @@
+<?php
+
+/**
+ * @file
+ * Provides a Markdown input filter.
+ */
+
+
+
+
+function ISMIBioFilter_menu(){
+  $items['showBio/%'] = array(
+      'title'              => 'View',
+      'description' => 'show an object.',
+      'page callback' => 'ISMIBioFilter_showBio_page',
+      'access arguments'   => array('access content'),
+      'page arguments'     => array(1),
+
+      'access arguments'   => array('access content'),
+      'type' => MENU_LOCAL_TASK,
+
+  );
+
+  $items['showEntity/%'] = array(
+      'title'              => 'View',
+      'description' => 'show an object.',
+      'page callback' => 'ISMIBioFilter_showEntity_page',
+      'access arguments'   => array('access content'),
+      'page arguments'     => array(1),
+
+      'access arguments'   => array('access content'),
+      'type' => MENU_LOCAL_TASK,
+
+  );
+
+
+  return $items;
+
+
+}
+
+
+function ISMIBioFilter_showEntity_page($keys){
+  #$results = db_query("SELECT * FROM {field_data_field_id} n where field_id_value  ='" . $keys . "'  and bundle = 'openmind_entity' ");
+  #$results = db_query("SELECT * FROM {field_data_field_id} n where field_id_value  ='" . $keys . "' ");
+
+  $query = new EntityFieldQuery;
+  $query->entityCondition('entity_type', 'node')
+  ->entityCondition('bundle', 'openmind_entity')
+  ->fieldCondition('field_id', 'value',$value = $keys);
+  $results = $query->execute();
+
+  if (isset($results['node'])){
+    $nids = array_keys($results['node']);
+
+    foreach ($nids as $nid){
+
+      drupal_goto("node/" . $nid);
+    }
+  } else {
+    drupal_goto("/unknownEntity");
+  }
+
+}
+
+function ISMIBioFilter_showBio_page($keys){
+  ##$results = db_query("SELECT * FROM {field_data_field_original_url} n where field_original_url_value  ='" . $keys . "'");
+
+  # zerlege den string
+  $paths = explode("/",$keys);
+  #gebraucht wird nur der letzte teil
+
+  $fn = $paths[sizeof(paths)-1];
+  dpm($fn);
+  dpm($keys);
+  drupal_goto($fn);
+  #foreach ($results as $result){
+  #	drupal_goto("node/" . $result->entity_id);
+  #}
+}
+/**
+ * Implements hook_help().
+ */
+function ISMIBioFilter_help($path, $arg) {
+  switch ($path) {
+    case 'admin/help#ISMIBioFilter':
+      return t('<p> Filters the original biographies to make the Drupal compatible.</p>');
+  }
+}
+
+/**
+ * Implements hook_filter_info().
+ */
+function ISMIBioFilter_filter_info() {
+  $filters['filter_ISMIBioFilter'] = array(
+      'title' => t('ISMIBioFilter'),
+      'description' => t('Filter for the Biographies from the Springer Website'),
+      'process callback' => '_filter_ISMIBioFilter',
+      'settings callback' => '_filter_ISMIBioFilter_settings',
+      'tips callback'  => '_filter_ISMIBioFilter_tips',
+  );
+
+  return $filters;
+}
+
+
+function _ISMIBioFilter_getSources($rel){
+  $vals = array();
+  $relNode = relation_load($rel->rid);
+  $eps = relation_get_endpoints($relNode);
+  foreach($eps as $ep){
+
+    $vals[]=array_shift(array_values($ep));
+
+  }
+
+  return $vals;
+}
+
+function _ISMIBioFilter_getTargets($rel){
+  $vals = array();
+  $relNode = relation_load($rel->rid);
+  $eps = relation_get_endpoints($relNode);
+  foreach($eps as $ep){
+
+    $ar = array_values($ep);
+    array_shift($ar);
+    $vals[]=array_shift($ar);
+  }
+
+  return $vals;
+}
+
+
+/**
+ * Returns the ISMIBioFilter input filter tips.
+ * @TODO: make it easier for translators.
+ */
+function _filter_ISMIBioFilter_tips($format, $long = FALSE) {
+  if ($long) {
+    return t('no tip');
+  }
+  else {
+    return t('no tip');
+  }
+}
+
+/**
+ * Implements hook_block_view().
+ */
+function ISMIBioFilter_block_view($delta = '') {
+  $block = array();
+  switch ($delta) {
+    case 'ISMIBioFilter_help':
+      $block['title'] = t('ISMIBio filter tips');
+      $block['content'] = _ISMIBioFilter_help_block();
+      break;
+
+
+    case 'ISMIObjects_main':
+      // main info for an object
+
+      $node = menu_get_object();
+
+      //node hat keine objektype dann mache nichts
+      if (!isset($node->field_oc)){
+        break;
+      }
+
+      $tid = $node->field_oc[LANGUAGE_NONE][0]['tid'];
+      $taxonomy = taxonomy_term_load($tid)->name;
+
+      switch($taxonomy){
+
+        case 'PERSON':
+          $ov = $node->field_ov[LANGUAGE_NONE][0]['value'];
+          $nov = $node->field_nov[LANGUAGE_NONE][0]['value'];
+          $block['title'] =  t('Person');
+          //$block['content']= theme('ISMIPersons_main',array('node' => $node));
+
+          $rows[] = array("Name",$ov);
+          $rows[] = array("Normalisiert",$nov);
+
+          $block['content']=theme('table', array('header' => null, 'rows' => $rows));
+
+
+          //is_prime_alias_name_of,invOf_is_prime_alias_name_of, invOf_is_alias_name_of ,is_alias_name_of
+          $rels = relation_query("node",$node->nid)->execute();
+          $prime_alias = "";
+          $aliases = array();
+
+          foreach($rels as $rel){
+
+            switch($rel->relation_type){
+              case "is_prime_alias_name_of":
+                $prime_alias = _ISMIBioFilter_getSources($rel);
+                break;
+
+              case "is_alias_name_of":
+                $aliases = _ISMIBioFilter_getSources($rel);
+                break;
+            }
+          }
+
+          $block['content'] .= theme("ISMIObject_aliases",array("prime_alias"=>$prime_alias,"aliases"=>$aliases));
+          break;
+
+        case  'TEXT':
+          $ov = $node->field_ov[LANGUAGE_NONE][0]['value'];
+          $nov = $node->field_nov[LANGUAGE_NONE][0]['value'];
+          $block['title'] =  t('Text');
+          //$block['content']= theme('ISMIPersons_main',array('node' => $node));
+
+          $rows[] = array("Title",$ov);
+          $rows[] = array("Normalisiert",$nov);
+
+          $block['content']=theme('table', array('header' => null, 'rows' => $rows));
+          $rels = relation_query("node",$node->nid)->execute();
+          $prime_alias = "";
+          $aliases = array();
+
+          foreach($rels as $rel){
+
+            switch($rel->relation_type){
+              case "is_prime_alias_name_of":
+                $prime_alias = _ISMIBioFilter_getSources($rel);
+                break;
+
+              case "is_alias_name_of":
+                $aliases = array_merge($aliases,_ISMIBioFilter_getSources($rel));
+                break;
+            }
+          }
+
+          $block['content'] .= theme("ISMIObject_aliases",array("prime_alias"=>$prime_alias,"aliases"=>$aliases));
+
+      }
+
+      break;
+
+    case 'ISMIObjects_titles':
+
+      $node = menu_get_object();
+      //node hat keine objektype dann mache nichts
+      if (!isset($node->field_oc)){
+        break;
+      }
+
+
+      $tid = $node->field_oc[LANGUAGE_NONE][0]['tid'];
+      $taxonomy = taxonomy_term_load($tid)->name;
+
+      switch($taxonomy){
+
+        case 'PERSON':
+          $rels = relation_query("node",$node->nid)->execute();
+
+          foreach($rels as $rel){
+
+            if ($rel->relation_type=="was_created_by"){
+              $relNode = relation_load($rel->rid);
+              $targets = relation_get_endpoints($relNode);
+              foreach($targets as $target){
+
+                $titles[]=array_shift(array_values($target));
+
+
+
+
+              }
+            }
+          }
+
+          $block['title'] = t('Titles');
+          $block['content']= theme('ISMIPersons_titles',array('titles' => $titles));
+
+      }
+      break;
+
+    case 'ISMIText_witnesses':
+      $node = menu_get_object();
+      //node hat keine objektype dann mache nichts
+      if (!isset($node->field_oc)){
+        break;
+      }
+
+
+      $tid = $node->field_oc[LANGUAGE_NONE][0]['tid'];
+      $taxonomy = taxonomy_term_load($tid)->name;
+
+      switch($taxonomy){
+
+        case 'TEXT':
+          $rels = relation_query("node",$node->nid)->execute();
+          $titles=array();
+          foreach($rels as $rel){
+
+            if ($rel->relation_type=="is_exemplar_of"){
+              $titles = array_merge($titles,_ISMIBioFilter_getSources($rel));
+
+            }
+          }
+
+          _ISMIBioFilter_enrich($titles);
+
+          $block['title'] = t('Witnesses');
+          //$block['content']= theme('ISMIWitnesses_list',array('witnesses' => $titles));
+
+          // create table
+          $rows=array();
+
+          foreach ($titles as $witness){
+
+          $rows[]=array(
+          l($witness->field_nov[LANGUAGE_NONE][0]['value'],$witness->nid),
+          l($witness->codex->field_nov[LANGUAGE_NONE][0]['value'],$witness->codex->nid),
+          l($witness->collection->field_nov[LANGUAGE_NONE][0]['value'],$witness->collection->nid),
+          l($witness->repository->field_nov[LANGUAGE_NONE][0]['value'],$witness->repository->nid),
+          l($witness->place->field_nov[LANGUAGE_NONE][0]['value'],$witness->place->nid)
+          );
+          }
+
+          $header = array("witness","codex","collection","repository","place");
+          $block['content'] = array(
+              '#theme' => 'table',
+              '#header' => $header,
+              '#rows' => $rows,
+          );
+          #$block['content'] = theme("table",array('header'=>null,'rows'=>$rows));
+      }
+      break;
+
+
+    case 'ISMIPersons_bea':
+      $node = menu_get_object();
+      //node hat keine objektype dann mache nichts
+      if (!isset($node->field_oc)){
+        break;
+      }
+
+      $tid = $node->field_oc[LANGUAGE_NONE][0]['tid'];
+      $taxonomy = taxonomy_term_load($tid)->name;
+      switch($taxonomy){
+
+        case 'PERSON':
+
+
+
+          $author_id = $node->field_id[LANGUAGE_NONE][0]['value'];
+
+
+          $query = new EntityFieldQuery;
+          $query->entityCondition('entity_type', 'node')
+          ->entityCondition('bundle', 'biography')
+          ->fieldCondition('field_id', 'value',$value = $author_id);
+          $results = $query->execute();
+
+          if (isset($results['node'])){
+            $nids = array_keys($results['node']);
+
+            foreach ($nids as $nid){
+
+              $body = entity_load_single("node", $nid)->body[LANGUAGE_NONE][0]['value'];
+
+              $block['title'] = t('BEA');
+              $block['content']= $body;
+            }
+          }
+      }
+      break;
+
+
+    case  'ISMIObjects_relations':
+      $node = menu_get_object();
+      $author_id = $node->field_id[LANGUAGE_NONE][0]['value'];
+
+
+      $rels = relation_query("node",$node->nid)->execute();
+
+      $block['content'] = ISMIBioFilter_RelationsFormat("node",$node,$rels);
+
+      break;
+  }
+
+  return $block;
+}
+
+/**
+ * Implements hook_block_info().
+ */
+function ISMIBioFilter_block_info() {
+  $blocks = array();
+  $blocks['ISMIBioFilter_help'] = array(
+      'info' => t('ISMI Bio filter tips'),
+  );
+  $blocks['ISMIObjects_main'] = array(
+      'info' => t('ISMI Main information of an object'),
+  );
+
+  $blocks['ISMIObjects_titles'] = array(
+      'info' => t('ISMI Titles related to an object'),
+  );
+
+  $blocks['ISMIPersons_bea'] = array(
+      'info' => t('ISMI Bea Entry of Person'),
+  );
+
+  $blocks['ISMIObjects_relations'] = array(
+      'info' => t('ISMI all relations'),
+  );
+
+  $blocks['ISMIText_witnesses'] = array(
+      'info' => t('ISMI witnesses'),
+  );
+
+  return $blocks;
+}
+
+/**
+ * Provides content for the ISMIBioFilter help block.
+ */
+function _ISMIBioFilter_help_block() {
+  return '<pre>' . t('Replaces external links to authors in the text to links to nodes in this website. ') . '</pre>';
+}
+
+/**
+ *
+ * Filter process callback.
+ */
+function _filter_ISMIBioFilter($text, $format) {
+  if (!empty($text)) {
+
+    $params = drupal_get_query_parameters();
+
+    $text=preg_replace('/href="([^>]+?_BEA.htm)"\>/', 'href="$1">', $text);
+
+    $text=preg_replace('#</span>\n#',"</span>",$text); #remove returns nach span otherwise this gives an extra space
+
+    $text=preg_replace('#style="[^"]+#',"",$text); #remove all style information
+
+
+  }
+
+  return $text;
+}
+
+/**
+ * Filter settings callback. Just provides a version overview.
+ */
+function _filter_ISMIBioFilter_settings($form, &$form_state, $filter, $format, $defaults) {
+  module_load_include('php', 'ISMIBioFilter', 'ISMIBioFilter');
+
+  $settings['ISMIBioFilter_wrapper'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('ISMIBioFilter'),
+  );
+  $links = array('NO LINK',
+      /*'Markdown PHP Version: <a href="http://michelf.com/projects/php-ISMIBioFilter/">' . MARKDOWN_VERSION . '</a>',
+       'Markdown Extra Version: <a href="http://michelf.com/projects/php-ISMIBioFilter/">' . MARKDOWNEXTRA_VERSION . '</a>',*/
+  );
+  $settings['ISMIBioFilter_wrapper']['ISMIBioFilter_status'] = array(
+      '#title' => t('Versions'),
+      '#type' => 'item',
+      '#markup' => theme('item_list', array('items' => $links)),
+  );
+
+  return $settings;
+}
+
+
+/* add id to url */
+
+function ISMIBioFilter_addIDs(){
+  $txt = file_get_contents(drupal_get_path("module", "ISMIBioFilter") . "/bio2ismi.txt");
+  $lines = explode("\n",$txt);
+  foreach ($lines as $line){
+    $content = explode(" ",$line);
+    $id = $content[0];
+	$origPath=$content[sizeof($content)-1];
+    $path = explode("/",$origPath);
+    $url = $path[sizeof($path)-1];
+
+
+    $nodePath = explode("/",drupal_lookup_path("source",$url));
+    #$nodePath = explode("/",drupal_lookup_path("source",str_replace(".htm","",$url)));
+
+    $nodeId = $nodePath[sizeof($nodePath)-1];
+
+    if ($nodeId != ""){
+      $node = node_load($nodeId);
+
+      $node->field_id[LANGUAGE_NONE][0]['value']=$id;
+      dpm($node);
+
+      node_save($node);
+    }
+  }
+
+
+}
+
+
+function ISMIBioFilter_field_formatter_info(){
+  return array(
+      // This formatter shows the obejct with fullmetadata
+      'ISMIBioFilter_entityLink' => array(
+          'label' => t('Entity Link Formatter'),
+          'field types' => array('text'),
+      ),
+  );
+}
+
+function ISMIBioFilter_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+  $element = array();
+
+  #TODO make this configurable
+  $text ="Show data entry";
+
+  switch ($instance['label']){
+    case 'author_id':
+      $text = "More about the author";
+  }
+
+  switch ($display['type']) {
+    // This formatter simply outputs the field as text and with a color.
+    case 'ISMIBioFilter_entityLink':
+      foreach ($items as $delta => $item) {
+        if ($item['value']!=""){
+
+          $element[$delta]['#markup'] = l($text,"showEntity/" . $item['value']);
+
+        }
+      }
+      break;
+
+  }
+  return $element;
+}
+
+
+
+function ISMIBioFilter_theme(){
+
+  return array(
+      'ISMIObject_aliases'  => array(
+          'variables' => array($prime_alias=null,$aliases=null),
+          'template' => 'ISMIObject-aliases',
+      ),
+
+      'ISMIPersons_titles'  => array(
+          'variables' => array('titles' => NULL),
+          'template' => 'ISMITitlesOfPerson',
+      ),
+
+      'ISMIWitnesses_list'  => array(
+          'variables' => array('witnesses' => NULL),
+          'template' => 'ISMIWitnesses-list',
+      ),
+  );
+}
+
+function ISMIBioFilter_RelationsFormat($entity_type,$entity,$rels){
+  $ret ="";
+  $sentences = array();
+
+
+  foreach ($rels as $item) {
+    list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
+    $relation = (object) relation_load($item->rid);
+
+    $relation_type = relation_type_load($relation->relation_type);
+
+    $subject = entity_label($entity_type, $entity) . ' '; // Subject of the sentence.
+    $subject_is_source = ($relation->endpoints[LANGUAGE_NONE]['0']['entity_id']) == $id ? TRUE : FALSE;
+    $count = 0; // For comma separation of objects.
+    $duplicate = FALSE; // To make sure duplicates of $entity get included in object list.
+    $objects = ''; // Comma separated list of entities that are the object of the sentence.
+    // Gramatical predicate of teh sentence.
+    $predicate = $relation_type->directional ? $relation_type->reverse_label : $relation_type->label;
+
+    foreach ($relation->endpoints[LANGUAGE_NONE] as $endpoint) {
+      // Add all entities that aren't this entity to the sentence $objects.
+      // Check for duplicates of the $subject first.
+      if ($endpoint['entity_type'] == $entity_type && $endpoint['entity_id'] == $id && $duplicate == FALSE) {
+        $duplicate = TRUE;
+        // Use the forward label as sentence predicate if r_index == 0.
+        // (only makes a difference if relation is directional).
+        if ($endpoint['r_index'] == 0) {
+          $predicate = ' ' . $relation_type->label;
+        }
+      }
+      else {
+        // If the relation is directional and the subject isn't the source,
+        // we want to list the source without any siblings. If it is
+        // directional and the subject is a source, list all targets.
+        // If non-directional, list everything as normal.
+        if (!$relation_type->directional || $subject_is_source || $endpoint['r_index'] == 0) {
+          $object_entities = entity_load($endpoint['entity_type'], array($endpoint['entity_id']));
+          $object_entity = reset($object_entities);
+          $object_label = entity_label($endpoint['entity_type'], $object_entity);
+          $object_uri = entity_uri($endpoint['entity_type'], $object_entity);
+          // Just add a space before the first element, comma and space before further ones.
+          $objects .= $count ? ', ' : ' ';
+          $count += 1;
+          $objects .= l($object_label, $object_uri['path']);
+
+          $ret .=theme('item_list',array('items' => array(".." . $predicate . $objects)));
+        }
+      }
+
+
+    }
+
+
+
+
+  }
+
+  return $ret;
+}
+
+function _ISMIBioFilter_non_indentical($tars,$nid){
+  $ret=array();
+  foreach($tars as $tar){
+    if($tar->nid!=$nid){
+      $ret[]=$tar;
+    }
+  }
+  return $ret;
+}
+function _ISMIBioFilter_enrich(&$titles){
+  foreach($titles as $title){
+  $title->codex=_ISMIBioFilter_find_unique_entity("is_part_of",$title->nid);
+  $title->collection=_ISMIBioFilter_find_unique_entity("is_part_of",$title->codex->nid);
+  $title->repository=_ISMIBioFilter_find_unique_entity("is_part_of",$title->collection->nid);
+  $title->place=_ISMIBioFilter_find_unique_entity("is_in",$title->repository->nid);
+
+  }
+}
+
+
+
+
+
+function _ISMIBioFilter_find_unique_entity($rel_type,$nid){
+  $rels = relation_query("node",$nid)->execute();
+  $is_in_place=array();
+  foreach($rels as $rel){
+    if ($rel->relation_type==$rel_type){
+      $reps = _ISMIBioFilter_getTargets($rel);
+      $is_in_place = array_merge($is_in_place,_ISMIBioFilter_non_indentical($reps,$nid));
+    }
+
+  }
+  return $is_in_place[0];
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISMIBioFilter/ISMIObject-aliases.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,16 @@
+<!--  prime_alias=null,$aliases=null),-->
+<h3>Aliases</h3>
+<ul>
+<?php foreach ($prime_alias as $alias):?>
+<li>
+<?php  print $alias->field_ov[LANGUAGE_NONE][0]['value']; ?>
+</li>
+<?php endforeach;?>
+
+<?php foreach ($aliases as $alias):?>
+<li>
+<?php  print $alias->field_ov[LANGUAGE_NONE][0]['value']; ?>
+</li>
+<?php endforeach;?>
+</ul>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISMIBioFilter/ISMITitlesOfPerson.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,5 @@
+<?php foreach ($titles as $title): ?>
+<hr/>
+
+<a href="../node/<?php print $title->nid ?>"><?php print $title->field_nov[LANGUAGE_NONE][0]['value']?></a>
+<?php endforeach;?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISMIBioFilter/ISMIWitnesses-list.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,18 @@
+<table>
+<?php foreach ($witnesses as $witness): ?>
+<tr>
+<td>
+<a href="../node/<?php print $witness->nid ?>"><?php print $witness->field_nov[LANGUAGE_NONE][0]['value']?></a>
+</td>
+<td>
+<a href="../node/<?php print $witness->codex->nid ?>"><?php print $witness->codex->field_nov[LANGUAGE_NONE][0]['value']?></a>
+</td><td>
+<a href="../node/<?php print $witness->collection->nid ?>"><?php print $witness->collection->field_nov[LANGUAGE_NONE][0]['value']?></a>
+</td><td>
+<a href="../node/<?php print $witness->repository->nid ?>"><?php print $witness->repository->field_nov[LANGUAGE_NONE][0]['value']?></a>
+</td><td>
+<a href="../node/<?php print $witness->place->nid ?>"><?php print $witness->place->field_nov[LANGUAGE_NONE][0]['value']?></a>
+</td>
+</tr>
+<?php endforeach;?>
+</table>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISMIBioFilter/LICENSE.txt	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISMIBioFilter/README.txt	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,1 @@
+Module to filter the original BEA htmls
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISMIBioFilter/bio2ismi.txt	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,163 @@
+455     http://islamsci.mcgill.ca/RASI/BEA/Qadizade_al-Rumi_BEA.htm
+856     http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Majdi_BEA.htm
+1080    http://islamsci.mcgill.ca/RASI/BEA/Ulugh_Beg_BEA.htm
+1645    http://islamsci.mcgill.ca/RASI/BEA/Jurjani_BEA.htm
+1960    http://islamsci.mcgill.ca/RASI/BEA/Abd_al-Wajid_BEA.htm
+2827    http://islamsci.mcgill.ca/RASI/BEA/Kashi_BEA.htm
+5490    http://islamsci.mcgill.ca/RASI/BEA/Qushji_BEA.htm
+5769    http://islamsci.mcgill.ca/RASI/BEA/Cholgi_BEA.htm
+6876    http://islamsci.mcgill.ca/RASI/BEA/Kamal_al-Din_al-Turkmani_BEA.htm
+7437    http://islamsci.mcgill.ca/RASI/BEA/Jaghmini_BEA.htm
+7627    http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Banna%27_BEA.htm
+7866    http://islamsci.mcgill.ca/RASI/BEA/Sadr_al-Sharia_al-Thani_BEA.htm
+8098    http://islamsci.mcgill.ca/RASI/BEA/Wabkanawi_BEA.htm
+9904    http://islamsci.mcgill.ca/RASI/BEA/Khafri_BEA.htm
+10017   http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Shatir_BEA.htm
+10695   http://islamsci.mcgill.ca/RASI/BEA/Khalili_BEA.htm
+12547   http://islamsci.mcgill.ca/RASI/BEA/Taqi_al-Din_BEA.htm
+13385   http://islamsci.mcgill.ca/RASI/BEA/Lari_BEA.htm
+15293   http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Ha%27im_BEA.htm
+15498   http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Kammad_BEA.htm
+16712   http://islamsci.mcgill.ca/RASI/BEA/Amili_BEA.htm
+17903   http://islamsci.mcgill.ca/RASI/BEA/Zacut_BEA.htm
+19264   http://islamsci.mcgill.ca/RASI/BEA/Chioniades_BEA.htm
+19818   http://islamsci.mcgill.ca/RASI/BEA/Suyuti_BEA.htm
+19999   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Abi_al-Fath_al-Sufi_BEA.htm
+21049   http://islamsci.mcgill.ca/RASI/BEA/Sibt_al-Maridini_BEA.htm
+21971   http://islamsci.mcgill.ca/RASI/BEA/Ali_al-Muwaqqit_BEA.htm
+22298   http://islamsci.mcgill.ca/RASI/BEA/Najm_al-Din_al-Misri_BEA.htm
+23358   http://islamsci.mcgill.ca/RASI/BEA/Miram_Celebi_BEA.htm
+23906   http://islamsci.mcgill.ca/RASI/BEA/Qunawi_BEA.htm
+24831   http://islamsci.mcgill.ca/RASI/BEA/Samaw%27al_BEA.htm
+25066   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Tufayl_BEA.htm
+27255   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Rushd_BEA.htm
+27887   http://islamsci.mcgill.ca/RASI/BEA/Umawi_BEA.htm
+28137   http://islamsci.mcgill.ca/RASI/BEA/Bitruji_BEA.htm
+29142   http://islamsci.mcgill.ca/RASI/BEA/Maimonides_BEA.htm
+30014   http://islamsci.mcgill.ca/RASI/BEA/Sharaf_al-Din_al-Tusi_BEA.htm
+31905   http://islamsci.mcgill.ca/RASI/BEA/Qattan_al-Marwazi_BEA.htm
+31986   http://islamsci.mcgill.ca/RASI/BEA/Isfizari_BEA.htm
+32015   http://islamsci.mcgill.ca/RASI/BEA/Shirwani_BEA.htm
+32258   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Bajja_BEA.htm
+34445   http://islamsci.mcgill.ca/RASI/BEA/Jabir_ibn_Aflah_BEA.htm
+34607   http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Salah_BEA.htm
+35456   http://islamsci.mcgill.ca/RASI/BEA/Abu_al-Salt_BEA.htm
+35984   http://islamsci.mcgill.ca/RASI/BEA/Khazini_BEA.htm
+37929   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Abi_al-Shukr_BEA.htm
+38032   http://islamsci.mcgill.ca/RASI/BEA/Barhebraeus_BEA.htm
+39022   http://islamsci.mcgill.ca/RASI/BEA/Mizzi_BEA.htm
+39177   http://islamsci.mcgill.ca/RASI/BEA/Samarqandi_BEA.htm
+39447   http://islamsci.mcgill.ca/RASI/BEA/Kharaqi_BEA.htm
+40635   http://islamsci.mcgill.ca/RASI/BEA/Shirazi_BEA.htm
+40908   http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Raqqam_BEA.htm
+41690   http://islamsci.mcgill.ca/RASI/BEA/Shams_al-Din_al-Bukhari_BEA.htm
+42295   http://islamsci.mcgill.ca/RASI/BEA/Ahmad_Mukhtar_BEA.htm
+42360   http://islamsci.mcgill.ca/RASI/BEA/Ashraf_BEA.htm
+42529   http://islamsci.mcgill.ca/RASI/BEA/Nisaburi_BEA.htm
+43236   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Ishaq_BEA.htm
+44436   http://islamsci.mcgill.ca/RASI/BEA/Farisi_BEA.htm
+45264   http://islamsci.mcgill.ca/RASI/BEA/Abhari_BEA.htm
+45772   http://islamsci.mcgill.ca/RASI/BEA/Marrakushi_BEA.htm
+47316   http://islamsci.mcgill.ca/RASI/BEA/Tusi_BEA.htm
+48884   http://islamsci.mcgill.ca/RASI/BEA/Urdi_BEA.htm
+50316   http://islamsci.mcgill.ca/RASI/BEA/Zhamaluding_BEA.htm
+50599   http://islamsci.mcgill.ca/RASI/BEA/Majriti_BEA.htm
+50990   http://islamsci.mcgill.ca/RASI/BEA/Kuhi_BEA.htm
+52057   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Yunus_BEA.htm
+52681   http://islamsci.mcgill.ca/RASI/BEA/Buzjani_BEA.htm
+53428   http://islamsci.mcgill.ca/RASI/BEA/Khujandi_BEA.htm
+53700   http://islamsci.mcgill.ca/RASI/BEA/Dunash_ibn_Tamim_BEA.htm
+54353   http://islamsci.mcgill.ca/RASI/BEA/Utarid_BEA.htm
+55901   http://islamsci.mcgill.ca/RASI/BEA/Saghani_BEA.htm
+56849   http://islamsci.mcgill.ca/RASI/BEA/Ikhwan_al-Safa%27_BEA.htm
+57661   http://islamsci.mcgill.ca/RASI/BEA/Qabisi_BEA.htm
+58576   http://islamsci.mcgill.ca/RASI/BEA/Sufi_BEA.htm
+58835   http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Alam_BEA.htm
+59144   http://islamsci.mcgill.ca/RASI/BEA/Qattan_BEA.htm
+59241   http://islamsci.mcgill.ca/RASI/BEA/Sulayman_ibn_Isma_BEA.htm
+60526   http://islamsci.mcgill.ca/RASI/BEA/Khazin_BEA.htm
+62099   http://islamsci.mcgill.ca/RASI/BEA/Ibrahim_ibn_Sinan_BEA.htm
+62466   http://islamsci.mcgill.ca/RASI/BEA/Farabi_BEA.htm
+63046   http://islamsci.mcgill.ca/RASI/BEA/Nastulus_BEA.htm
+63770   http://islamsci.mcgill.ca/RASI/BEA/Amajur_Family_BEA.htm
+64456   http://islamsci.mcgill.ca/RASI/BEA/Khayyam_BEA.htm
+65898   http://islamsci.mcgill.ca/RASI/BEA/Zarqali_BEA.htm
+67183   http://islamsci.mcgill.ca/RASI/BEA/Said_al-Andalusi_BEA.htm
+70924   http://islamsci.mcgill.ca/RASI/BEA/Biruni_BEA.htm
+71721   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Muadh_BEA.htm
+72419   http://islamsci.mcgill.ca/RASI/BEA/Nasawi_BEA.htm
+73175   http://islamsci.mcgill.ca/RASI/BEA/Ali_ibn_Khalaf_BEA.htm
+74095   http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Haytham_BEA.htm
+74607   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Sina_BEA.htm
+74872   http://islamsci.mcgill.ca/RASI/BEA/Juzjani_BEA.htm
+75736   http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Saffar_BEA.htm
+76587   http://islamsci.mcgill.ca/RASI/BEA/Hashimi_BEA.htm
+76792   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Labban_BEA.htm
+76942   http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Samh_BEA.htm
+77544   http://islamsci.mcgill.ca/RASI/BEA/Tabari_BEA.htm
+77798   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Sahl_BEA.htm
+78352   http://islamsci.mcgill.ca/RASI/BEA/Sijzi_BEA.htm
+78877   http://islamsci.mcgill.ca/RASI/BEA/Ibn_Iraq_BEA.htm
+81093   http://islamsci.mcgill.ca/RASI/BEA/Fazari_BEA.htm
+82201   http://islamsci.mcgill.ca/RASI/BEA/Yaqub_ibn_Tariq_BEA.htm
+95976   http://islamsci.mcgill.ca/RASI/BEA/Qusta_ibn_Luqa_al-Balabakki_BEA.htm
+96154   http://islamsci.mcgill.ca/RASI/BEA/Banu_Musa_BEA.htm
+96309   http://islamsci.mcgill.ca/RASI/BEA/Ishaq_ibn_Hunayn_BEA.htm
+97367   http://islamsci.mcgill.ca/RASI/BEA/Battani_BEA.htm
+97829   http://islamsci.mcgill.ca/RASI/BEA/Nayrizi_BEA.htm
+98608   http://islamsci.mcgill.ca/RASI/BEA/Abu_Mashar_BEA.htm
+98718   http://islamsci.mcgill.ca/RASI/BEA/Adami_BEA.htm
+98807   http://islamsci.mcgill.ca/RASI/BEA/Adami_BEA.htm
+99308   http://islamsci.mcgill.ca/RASI/BEA/Banu_Musa_BEA.htm
+99348   http://islamsci.mcgill.ca/RASI/BEA/Banu_Musa_BEA.htm
+100078  http://islamsci.mcgill.ca/RASI/BEA/Thabit_ibn_Qurra_BEA.htm
+100957  http://islamsci.mcgill.ca/RASI/BEA/Farghani_BEA.htm
+102343  http://islamsci.mcgill.ca/RASI/BEA/Kindi_BEA.htm
+102917  http://islamsci.mcgill.ca/RASI/BEA/Banu_Musa_BEA.htm
+103878  http://islamsci.mcgill.ca/RASI/BEA/Hajjaj_ibn_Yusuf_ibn_Matar_BEA.htm
+104105  http://islamsci.mcgill.ca/RASI/BEA/Yahya_ibn_Abi_Mansur_BEA.htm
+104293  http://islamsci.mcgill.ca/RASI/BEA/Masha%27allah_ibn_Athari_BEA.htm
+105280  http://islamsci.mcgill.ca/RASI/BEA/Jawhari_BEA.htm
+105453  http://islamsci.mcgill.ca/RASI/BEA/Sanad_ibn_Ali_BEA.htm
+105546  http://islamsci.mcgill.ca/RASI/BEA/Ali_ibn_Isa_al-Asturlabi_BEA.htm
+106357  http://islamsci.mcgill.ca/RASI/BEA/Khwarizmi_BEA.htm
+163308  http://islamsci.mcgill.ca/RASI/BEA/Salih_Zeki_BEA.htm
+163925  http://islamsci.mcgill.ca/RASI/BEA/Habash_al-Hasib_BEA.htm
+165794  http://islamsci.mcgill.ca/RASI/BEA/Birjandi_BEA.htm
+184350  http://islamsci.mcgill.ca/RASI/BEA/Severus_Sebokht_BEA.htm
+184524  http://islamsci.mcgill.ca/RASI/BEA/Ma%27mun_BEA.htm
+191603  http://islamsci.mcgill.ca/RASI/BEA/Rudani_BEA.htm
+191929  http://islamsci.mcgill.ca/RASI/BEA/Tezkireci_K%F6se_Ibrahim_BEA.htm
+199827  http://islamsci.mcgill.ca/RASI/BEA/Marwarrudhi_BEA.htm
+200525  http://islamsci.mcgill.ca/RASI/BEA/Ridwan_al-Falaki_BEA.htm
+205847  http://islamsci.mcgill.ca/RASI/BEA/Darandawi_BEA.htm
+207970  http://islamsci.mcgill.ca/RASI/BEA/Ubaydi_BEA.htm
+208419  http://islamsci.mcgill.ca/RASI/BEA/Jagannatha_Samrat_BEA.htm
+208455  http://islamsci.mcgill.ca/RASI/BEA/Kamalakara_BEA.htm
+208523  http://islamsci.mcgill.ca/RASI/BEA/Ibn_Sid_BEA.htm
+208529  http://islamsci.mcgill.ca/RASI/BEA/Ibn_Baso_BEA.htm
+208549  http://islamsci.mcgill.ca/RASI/BEA/Ibn_Ezra_BEA.htm
+208593  http://islamsci.mcgill.ca/RASI/BEA/Husayn_BEA.htm
+208623  http://islamsci.mcgill.ca/RASI/BEA/Ibn_al-Alam_BEA.htm
+208659  http://islamsci.mcgill.ca/RASI/BEA/Harun_al-Rashid_BEA.htm
+208683  http://islamsci.mcgill.ca/RASI/BEA/Husayn_BEA.htm
+208699  http://islamsci.mcgill.ca/RASI/BEA/Gersonides_BEA.htm
+208743  http://islamsci.mcgill.ca/RASI/BEA/G%F6kmen_BEA.htm
+208772  http://islamsci.mcgill.ca/RASI/BEA/Jacob_ben_Makhir_ibn_Tibbon_BEA.htm
+208846  http://islamsci.mcgill.ca/RASI/BEA/Dinakara_BEA.htm
+208964  http://islamsci.mcgill.ca/RASI/BEA/Ben_Solomon_BEA.htm
+208972  http://islamsci.mcgill.ca/RASI/BEA/Nastulus_BEA.htm
+209026  http://islamsci.mcgill.ca/RASI/BEA/Bar_Hiyya_BEA.htm
+209068  http://islamsci.mcgill.ca/RASI/BEA/Aryabhata_II_BEA.htm
+209099  http://islamsci.mcgill.ca/RASI/BEA/Aryabhata_I_BEA.htm
+209179  http://islamsci.mcgill.ca/RASI/BEA/Alfonso_X_BEA.htm
+209245  http://islamsci.mcgill.ca/RASI/BEA/Abbas_Wasim_Efendi_BEA.htm
+209932  http://islamsci.mcgill.ca/RASI/BEA/Yativrsabha_BEA.htm
+210028  http://islamsci.mcgill.ca/RASI/BEA/Yavanesvara_BEA.htm
+210065  http://islamsci.mcgill.ca/RASI/BEA/Raghavananda_Sarman_BEA.htm
+210105  http://islamsci.mcgill.ca/RASI/BEA/Paramesvara_of_Vatesseri_BEA.htm
+210199  http://islamsci.mcgill.ca/RASI/BEA/Mathuranatha_Sarman_BEA.htm
+210298  http://islamsci.mcgill.ca/RASI/BEA/Metochites_BEA.htm
+210350  http://islamsci.mcgill.ca/RASI/BEA/Khalifazade_Ismail_BEA.htm
+210368  http://islamsci.mcgill.ca/RASI/BEA/Kesava_BEA.htm
+210406  http://islamsci.mcgill.ca/RASI/BEA/Munjala_BEA.htm
Binary file importFromOpenMind/.DS_Store has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/importFromOpenMind/.project	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>importFromOpenMind</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/importFromOpenMind/.pydevproject	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?><pydev_project>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/${PROJECT_DIR_NAME}</path>
+</pydev_pathproperty>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 3.0</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+</pydev_project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/importFromOpenMind/converter/addDRI.py	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,49 @@
+from urllib import request
+
+class converter:
+    
+    out ="/var/tmp/out.csv"
+    url = "http://md.mpiwg-berlin.mpg.de/purls/search?q="  # /permanent/library/W028ATN3
+    def read(self,fn):
+        
+        of = open(self.out,"w")
+        
+        fl = open(fn,"r")
+        
+        for line in fl.readlines():
+            line = line.replace("\n","")
+            line = line.replace('"','')
+            splitted = line.split(",")
+            
+            path = splitted[0].replace('"','')
+            path = path.replace("/mpiwg/online","")
+            
+            qr = self.url + path
+            
+            g = request.urlopen(qr, data=bytearray(path,"utf-8"))
+            
+            p = g.read().decode('utf-8')
+            
+            spl = p.split("\t")
+            
+            if len(spl) > 1:
+                dri = spl[1]
+                
+                splitted.append(dri)
+                
+                print (splitted)
+                
+                of.write(",".join(splitted)+"\n")
+                
+        
+        of.close()
+            
+        
+            
+        
+cv =converter()
+
+cv.read("/var/tmp/archive.csv")
+            
+            
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/importFromOpenMind/importer/filterISMI.py	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,161 @@
+'''
+Created on 22.04.2014
+
+@author: dwinter
+'''
+
+import json
+import urllib.request
+
+class Importer:
+    
+    def loadJSON(self,url):
+       
+
+        response = urllib.request.urlopen(url)
+        str_response = response.readall().decode('utf-8')
+    
+        self.data = json.loads(str_response)
+        
+    
+    def loadJSONFromFile(self,fn):
+        
+
+        self.data = json.load(open(fn+".json",'r', encoding="utf-8"),encoding="utf-8")
+        
+        
+    def getEntIdsMentioned(self,kind="tar",filterOC=[]):
+        """ holt alle Id entweder als src_id """
+        
+        ents = self.data.get("ents")
+        
+        
+        
+        ret=set()
+        rels=[]
+        if kind=="tar":
+            rel_type="tar_rels"
+            id_type="src_id"
+            oc_type="src_oc"
+        else:       
+            rel_type="src_rels"
+            id_type="tar_id"
+            oc_type="tar_oc"
+        
+        for ent in ents:
+            tar_rels = ent.get(rel_type)
+            
+           
+            
+            for tar_rel in tar_rels:
+                
+               
+                if not tar_rel.get(oc_type) in filterOC:
+                    
+      
+                    ret.add(str(tar_rel.get(id_type)))
+                
+                
+                    rels.append(tar_rel)
+                
+                
+        
+        return ret,rels
+        
+       
+    def loadallEnts(self,kind="tar",filterOC=[]):
+        
+        ids,rels = self.getEntIdsMentioned(kind=kind,filterOC=filterOC)
+        
+        
+        baseUrl="http://openmind-ismi-dev.mpiwg-berlin.mpg.de/om4-ismi/jsonInterface?include_content=true&include_romanization=true&method=get_ents"
+        
+        lenId = len(ids)
+        
+        portions = int(lenId / 500) 
+        
+        ents = []
+        for p in range(portions+1):
+            
+            
+            start = p * 500
+            end = min(lenId,(p+1)*500)
+            
+            idsFrak = list(ids)[start:end]
+            idsString = ",".join(idsFrak)
+            
+            
+            qs = baseUrl+"&ids="+idsString
+            print (qs)
+            response = urllib.request.urlopen(qs)
+            entsJ = json.loads(response.readall().decode('utf-8'));
+            ents += entsJ.get("ents")
+            #str_response += response.readall().decode('utf-8')
+        
+        
+        str_response = json.dumps({"ents":ents});
+        return str_response,rels
+    
+    def saveallEnts(self,filename,kind="tar",filterOC=[]):
+        
+        ents,rels = self.loadallEnts(kind=kind,filterOC=filterOC)
+        of = open(filename+".json","wb")
+        of.write(ents.encode('utf-8'))
+        of.close()
+        
+        of = open(filename+"_rels.json","w")
+        json.dump({'rels':rels},of);
+        of.close()
+        
+        
+    
+if __name__ == '__main__':
+    imp = Importer()
+    
+#     url = """http://openmind-ismi-dev.mpiwg-berlin.mpg.de/om4-ismi/jsonInterface?method=get_ents&ids=27543,36745,58453,87298,259646,35093,22863,34870,36882,101488,36696,31794,37240,35014,35583,37025,35960,172492,98286,165721,260111,90980,36316,260120,36241,260129,260138,38860,176694,72545,36185,36575,260146,31672,37739,89861,176778,180743,86328,260150,90658,58423,181058,105948,35526,74078,260158,181096,31606,31568,27872,36938,4836,34668,76866,102230,76888,74070,73757,182685,260162,260170,1102,172888,260174,34806,28088,36713,37323,34551,35943,98095,260178,260182,182770,260186,260190,260194,36114,85003,31630,157290,37153,37213,172952,86871,64406,102590,82615,58245,179791,179550,12419,95861,36429,36099,74237,36065,74822,87549,83765,36733,19259,260198,34986,88041,260202,36550,260206,37228,39880,36318,36597,35035,58328,80831,58354,74277,36529,36380,69450,200246,260222,81178,260226,199952,262557,87212,99059,64270,81811,65785,36645
+# """
+#    
+
+    url = """http://openmind-ismi-dev.mpiwg-berlin.mpg.de/om4-ismi/jsonInterface?method=get_public_codices"""
+   
+   
+    imp.loadJSON(url)
+    
+    #ids= imp.getEntIdsMentioned()
+    
+    
+    #loadall = imp.loadallEnts()
+    #print(loadall.encode('utf-8'))
+    
+    
+    imp.saveallEnts("/tmp/witnesses")
+    
+    imp.saveallEnts("/tmp/codex_src",kind="src",filterOC=['CODEX','WITNESS'])
+    
+    #hole jetzt alle relationen an den witnessen
+    
+    imp.loadJSONFromFile("/tmp/witnesses")
+    
+    #ids= imp.getEntIdsMentioned(kind="src")
+ 
+    imp.saveallEnts("/tmp/texts",kind="src",filterOC=['CODEX','WITNESS','PERSON'])
+    
+    imp.loadJSONFromFile("/tmp/texts")
+    
+    imp.saveallEnts("/tmp/authors_subjects_src",kind="src",filterOC=['CODEX','WITNESS','TEXT'])
+    
+    imp.saveallEnts("/tmp/authors_subjects_tar",kind="tar",filterOC=['CODEX','WITNESS','TEXT'])
+    
+  
+    imp.loadJSONFromFile("/tmp/authors_subjects_src")
+    
+    imp.saveallEnts("/tmp/subjects_places",kind="src",filterOC=['CODEX','WITNESS','TEXT','PERSON'])
+    imp.saveallEnts("/tmp/references_places",kind="tar",filterOC=['CODEX','WITNESS','TEXT','PERSON'])
+  
+    
+    
+    
+    
+    
+    
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ismi_ext/ismi_ext.info	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,9 @@
+name = Extensions for ISMI
+description = Erweiterung für indexing
+dependencies[] = apachesolr
+
+package = Search Toolkit
+core = "7.x"
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ismi_ext/ismi_ext.module	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,127 @@
+<?php
+
+// alter indexing
+
+function ismi_ext_apachesolr_index_documents_alter($documents, $entity, $entity_type, $env_id){
+  // hole entities die sich auf diese beziehen
+
+    $attributes = $entity->field_attribute[LANGUAGE_NONE];
+
+    //TODO nimme nur das erste, kann es mehr geben?
+    if (isset ($documents[0])){
+      foreach ($attributes as $attribute){
+
+
+        #attributes als felder in solr
+        $txt = $attribute['ov'];
+
+        $txt_chunks = str_split($txt,$split_length=10000); # teile den String falls zu lang in chunks
+
+
+        foreach ($txt_chunks as $txt_chunk){
+          $documents[0]->addField("attr_" . $attribute['name'],$txt_chunk);
+          $documents[0]->addField("attrtext_" . $attribute['name'],$txt_chunk);
+        }
+
+      }
+    }
+
+    #relations als felder in solr
+
+    $rels = relation_query($entity_type, $entity->nid)->execute();
+
+    foreach($rels as $rel){
+
+
+      $rel_type = $rel->relation_type;
+
+      $relation = relation_load($rel->rid);
+
+      $endpoints = relation_get_endpoints($relation);
+
+
+      //store only the endpoint which is differes from the current _entity
+
+
+      $nodes = $endpoints['node'];
+
+
+
+      foreach ($nodes as $nid => $node){
+        if ($nid != $entity->nid){
+          $title = $node->title;
+        }
+      }
+
+      //TODO nimme nur das erste, kann es mehr geben?
+      if (isset ($documents[0])){
+
+        $documents[0]->addField("rel_" . $rel_type,$title);
+
+      }
+    }
+
+
+}
+
+
+
+function ismi_ext_facetapi_facet_info($searcher_info) {
+   $facets = array();
+
+   $facets['entityType'] = array(
+       'label' => t('Entity Types'),
+       'description' => t('Filter by Entity Type'),
+       'field' => 'sm_vid_openmind_types',
+       //'map callback' => 'facetapi_map_language',
+       //'values callback' => 'facetapi_callback_language_values',
+       'facet mincount allowed' => TRUE,
+       'dependency plugins' => array('bundle', 'role'),
+   );
+
+   $facets['explicit'] = array(
+       'label' => t('Explicit'),
+       'description' => t('Filter by Explicit'),
+       'field' => 'attrtext_explicit',
+       //'map callback' => 'facetapi_map_language',
+       //'values callback' => 'facetapi_callback_language_values',
+       'facet mincount allowed' => TRUE,
+       'dependency plugins' => array('bundle', 'role'),
+   );
+
+   $facets['incipit'] = array(
+       'label' => t('Incipit'),
+       'description' => t('Filter by Incipit'),
+       'field' => 'attrtext_incipit',
+       //'map callback' => 'ismi_ext_map_incipit',
+       //'values callback' => 'facetapi_callback_language_values',
+       'facet mincount allowed' => TRUE,
+       'dependency plugins' => array('bundle', 'role'),
+   );
+
+   $facets['persons'] = array(
+       'label' => t('Persons (created)'),
+       'description' => t('Filter by Persons (was_created_by)'),
+       'field' => 'rel_was_created_by',
+       //'map callback' => 'facetapi_map_language',
+       //'values callback' => 'facetapi_callback_language_values',
+       'facet mincount allowed' => TRUE,
+       'dependency plugins' => array('bundle', 'role'),
+   );
+
+  return $facets;
+}
+
+function ismi_ext_theme_registry_alter(&$theme_registry){
+   $link_active = $theme_registry['facetapi_link_inactive'];
+   $link_active['preprocess_functions'][]='ismi_ext_process_link';
+   $theme_registry['facetapi_link_active']=$link_active;
+
+
+}
+
+function imi_ext_process_link(&$value){
+  dpm($value);
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/LICENSE.txt	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/link-rtl.css	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,8 @@
+.link-field-column {
+  float: right;
+}
+
+.link-field-column.link-field-url .form-text {
+  direction: ltr;
+  text-align: left;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/link.css	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,8 @@
+.link-field-column {
+  float: left;
+  width: 48%;
+}
+
+.link-field-column .form-text {
+  width: 95%;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/link.devel_generate.inc	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Devel Generate support for Link module.
+ */
+
+/**
+ * Implements hook_devel_generate().
+ */
+function link_devel_generate($object, $field, $instance, $bundle) {
+  if (field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_CUSTOM) {
+    return devel_generate_multiple('_link_devel_generate', $object, $field, $instance, $bundle);
+  }
+  else {
+    return _link_devel_generate($object, $field, $instance, $bundle);
+  }
+}
+
+/**
+ * Callback for hook_devel_generate().
+ */
+function _link_devel_generate($object, $field, $instance, $bundle) {
+  $link = array(
+    'url' => url('<front>', array('absolute' => TRUE)),
+    'attributes' => _link_default_attributes(),
+  );
+  if ($instance['settings']['title'] != 'none') {
+    $link['title'] = devel_create_greeking(mt_rand(1, 3), TRUE);
+  }
+  return $link;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/link.diff.inc	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Provide diff field functions for the Link module.
+ */
+
+/**
+ * Diff field callback for parsing link fields comparative values.
+ */
+function link_field_diff_view($items, $context) {
+  $diff_items = array();
+  foreach ($items as $delta => $item) {
+    if ($item['url'] && $item['title']) {
+      $diff_items[$delta] = $item['title'] . ' (' . $item['url'] . ')';
+    }
+    else {
+      $diff_items[$delta] = $item['title'] . $item['url'];
+    }
+  }
+  return $diff_items;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/link.migrate.inc	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,108 @@
+<?php
+
+/**
+ * @file
+ * Support for migrate module.
+ *
+ * With Migrate 2.4 or later, you can use the subfield syntax to set the title
+ * and attributes:
+ *
+ * @code
+ * $this->addFieldMapping('field_my_link', 'source_url');
+ * $this->addFieldMapping('field_my_link:title', 'source_title');
+ * $this->addFieldMapping('field_my_link:attributes', 'source_attributes');
+ * @endcode
+ *
+ * With earlier versions of Migrate, you must pass an arguments array:
+ *
+ * @code
+ * $link_args = array(
+ *   'title' => array('source_field' => 'source_title'),
+ *   'attributes' => array('source_field' => 'source_attributes'),
+ * );
+ * $this->addFieldMapping('field_my_link', 'source_url')
+ *      ->arguments($link_args);
+ * @endcode
+ */
+
+/**
+ * Implements hook_migrate_api().
+ */
+function link_migrate_api() {
+  return array(
+    'api' => 2,
+    'field handlers' => array('MigrateLinkFieldHandler'),
+  );
+}
+
+class MigrateLinkFieldHandler extends MigrateFieldHandler {
+  public function __construct() {
+    $this->registerTypes(array('link_field'));
+  }
+
+  static function arguments($title = NULL, $attributes = NULL, $language = NULL) {
+    $arguments = array();
+    if (!is_null($title)) {
+      $arguments['title'] = $title;
+    }
+    if (!is_null($attributes)) {
+      $arguments['attributes'] = $attributes;
+    }
+    if (!is_null($language)) {
+      $arguments['language'] = $language;
+    }
+    return $arguments;
+  }
+
+  /**
+   * Implementation of MigrateFieldHandler::fields().
+   *
+   * @param $type
+   *  The field type.
+   * @param $instance
+   *  Instance info for the field.
+   * @param Migration $migration
+   *  The migration context for the parent field. We can look at the mappings
+   *  and determine which subfields are relevant.
+   * @return array
+   */
+  public function fields($type, $instance, $migration = NULL) {
+    return array(
+      'title' => t('Subfield: The link title attribute'),
+      'attributes' => t('Subfield: The attributes for this link'),
+      'language' => t('Subfield: The language for the field'),
+    );
+  }
+
+  public function prepare($entity, array $field_info, array $instance, array $values) {
+    if (isset($values['arguments'])) {
+      $arguments = $values['arguments'];
+      unset($values['arguments']);
+    }
+    else {
+      $arguments = array();
+    }
+
+    $language = $this->getFieldLanguage($entity, $field_info, $arguments);
+    $values = array_filter($values);
+
+    foreach ($values as $delta => $value) {
+      $item = array();
+      if (isset($arguments['title'])) {
+        if (!is_array($arguments['title'])) {
+          $item['title'] = $arguments['title'];
+        }
+        elseif (isset($arguments['title'][$delta])) {
+          $item['title'] = $arguments['title'][$delta];
+        }
+      }
+      if (isset($arguments['attributes'])) {
+        $item['attributes'] = $arguments['attributes'];
+      }
+      $item['url'] = $value;
+      $return[$language][$delta] = $item;
+    }
+
+    return isset($return) ? $return : NULL;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/openmindattribute.info	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,26 @@
+name = openmindattribute
+description = Defines simple openmindattribute field types.
+core = 7.x
+package = Fields
+
+files[] = openmindattribute.module
+;files[] = openmindattribute.migrate.inc
+
+; Tests
+;files[] = tests/openmindattribute.test
+;files[] = tests/openmindattribute.attribute.test
+;files[] = tests/openmindattribute.crud.test
+;files[] = tests/openmindattribute.crud_browser.test
+;files[] = tests/openmindattribute.token.test
+;files[] = tests/openmindattribute.validate.test
+
+; Views Handlers
+files[] = views/openmindattribute_views_handler_argument_target.inc
+files[] = views/openmindattribute_views_handler_filter_protocol.inc
+
+; Information added by  packaging script on 2013-11-24
+version = "7.x-1.2"
+core = "7.x"
+project = "openmindattribute"
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/openmindattribute.install	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,156 @@
+<?php
+
+/**
+ * @file
+ * Install file for the openmindattribute module.
+ */
+
+/**
+ * Upgrade notes:
+ * Things we need to make sure work when upgrading from Drupal 6 to Drupal 7:
+ */
+
+/**
+ * Implements hook_field_schema().
+ */
+function openmindattribute_field_schema($field) {
+  return array(
+    'columns' => array(
+      'name' => array(
+        'type' => 'varchar',
+        // Maximum URLs length.
+        'length' => 2048,
+        'not null' => FALSE,
+        'sortable' => TRUE,
+      ),
+      'ov' => array(
+        'type' => 'text',
+        'not null' => FALSE,
+        'sortable' => TRUE,
+      ),
+      'nov' => array(
+        'type' => 'text',
+        'not null' => FALSE,
+      	'sortable' => TRUE,
+      ),
+       'romanization' => array(
+    				'type' => 'text',
+    				'not null' => FALSE,
+    				'sortable' => TRUE,
+    		),
+    ),
+  );
+}
+
+/**
+ * Implements hook_update_last_removed().
+ */
+function openmindattribute_update_last_removed() {
+  return 6001;
+}
+
+
+//* add field romanization *//
+function openmindattribute_update_7230(&$sandbox) {
+	$fields = field_info_fields();
+	foreach ($fields as $field_name => $field) {
+		dpm($field['type']);
+		dpm($field_name);
+		dpm("---");
+		if (($field['type'] == 'openmindattribute_fields' || $field['type'] == 'openmindattribute_field') && $field['storage']['type'] == 'field_sql_storage') {
+			$schema = openmindattribute_field_schema($field);
+			
+			foreach ($field['storage']['details']['sql'] as $type => $table_info) {
+				foreach ($table_info as $table_name => $columns) {
+					try {
+						
+					$column_name = _field_sql_storage_columnname($field_name, 'romanization');
+					
+					dpm($field_name);
+					dpm($column_name);
+					db_add_field($table_name, $column_name, $schema['columns']['name']);
+					db_add_index($table_name, $column_name, array($column_name));
+					}
+					catch (Exception $e)
+					{
+						dpm("error");
+						dpm($table_name);
+					}
+				}
+			}
+		}
+	}
+	field_cache_clear();
+}
+
+
+/**
+ * Handles moving settings data from field_config.data to field_config_instance.data.
+ */
+function openmindattribute_update_7010() {
+  
+  // For each field that is a openmindattribute field, we need to copy the settings from the general field level down to the instance.
+  //$field_data = array();
+  $result = db_query("SELECT id, field_name, data FROM {field_config} WHERE module = 'openmindattribute' AND type = 'openmindattribute_field'");
+  foreach ($result as $field) {
+    $field_id = $field->id;
+    $name = $field->field_name;
+    $field_data = unserialize($field->data);
+    
+    $instances = db_query("SELECT id, data FROM {field_config_instance} WHERE field_id = :field_id", array(':field_id' => $field_id));
+    foreach ($instances as $instance) {
+      // If this field has been updated already, we want to skip it.
+      $instance_data = unserialize($instance->data);
+      $update_instance = FALSE;
+      if (!isset($instance_data['settings']['title'])) {
+        foreach ($field_data['settings'] as $key => $value) {
+          if (!isset($instance_data['settings'][$key])) {
+            $instance_data['settings'][$key] = $value;
+            $update_instance = TRUE;
+          }
+        }
+        if ($update_instance) {
+          // update the database.
+          $num_updated = db_update('field_config_instance')
+            ->fields(array('data' => serialize($instance_data)))
+            ->condition('id', $instance->id)
+            ->execute();
+        }
+      }
+    }
+  }
+  
+  return t("Instance settings have been set with the data from the field settings.");
+}
+
+/**
+ * Renames all displays from foobar to openmindattribute_foobar
+ */
+function openmindattribute_update_7001() {
+  // Update the display type for each openmindattribute field type.
+  $result = db_query("SELECT id, field_name, data FROM {field_config} WHERE module = 'openmindattribute' AND type = 'openmindattribute_field'");
+  foreach ($result as $field) {
+    $field_id = $field->id;
+    $name = $field->field_name;
+    $field_data = unserialize($field->data);
+    
+    $instances = db_query("SELECT id, data FROM {field_config_instance} WHERE field_id = :field_id", array(':field_id' => $field_id));
+    foreach ($instances as $instance) {
+      // If this field has been updated already, we want to skip it.
+      $instance_data = unserialize($instance->data);
+      $update_instance = FALSE;
+      foreach ($instance_data['display'] as $display_name => $display_data) {
+        if ($display_data['type'] && (0 !== strpos($display_data['type'], 'openmindattribute_'))) {
+          $instance_data['display'][$display_name]['type'] = 'openmindattribute_' . $display_data['type'];
+          $update_instance = TRUE;
+        }
+      }
+      if ($update_instance) {
+        db_update('field_config_instance')
+          ->fields(array('data' => serialize($instance_data)))
+          ->condition('id', $instance->id)
+          ->execute();
+      }
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/openmindattribute.module	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,1535 @@
+<?php
+
+
+
+/**
+ * Implements hook_field_info().
+ */
+function openmindattribute_field_info() {
+	return array(
+			'openmindattribute_field' => array(
+					'label' => t('Attribute'),
+					'description' => t('The attribute'),
+					'default_widget' => 'openmindattribute_field',
+					'default_formatter' => 'openmindattribute_default',
+					// Support hook_entity_property_info() from contrib "Entity API".
+					'property_type' => 'field_item_openmindattribute',
+					'property_callbacks' => array('openmindattribute_field_property_info_callback')
+			),
+			'openmindattribute_fields' => array(
+					'label' => t('All Attributes'),
+					'description' => t('The attributes'),
+					'default_widget' => 'openmindattribute_fields',
+					'default_formatter' => 'openmindattribute_default',
+					// Support hook_entity_property_info() from contrib "Entity API".
+					#'property_type' => 'field_item_openmindattribute',
+					#'property_callbacks' => array('openmindattribute_field_property_info_callback')
+			),
+			'openmindattribute_field' => array(
+					'label' => t('Attribute'),
+					'description' => t('The attribute'),
+					'default_widget' => 'openmindattribute_field',
+					'default_formatter' => 'openmindattribute_default',
+					// Support hook_entity_property_info() from contrib "Entity API".
+					'property_type' => 'field_item_openmindattribute',
+					'property_callbacks' => array('openmindattribute_field_property_info_callback')
+			),
+			 
+	);
+}
+
+/**
+ * Implements hook_field_instance_settings_form().
+ */
+function openmindattribute_field_instance_settings_form($field, $instance) {
+
+	if ($field['type'] == 'openmindattribute_fields'){ // nur ausgabe feld!
+		$form['name'] = array(
+				'#type' => 'textfield',
+				'#title' => t('Name'),
+				'#default_value' => isset($instance['settings']['name']) ? $instance['settings']['name'] : '',
+				'#description' => t('This title will always be used if &ldquo;Static Title&rdquo; is selected above.'),
+		);
+		return $form;
+	}
+	$form = array(
+			'#element_validate' => array('openmindattribute_field_settings_form_validate'),
+	);
+
+
+
+	$form['name'] = array(
+			'#type' => 'textfield',
+			'#title' => t('Name'),
+			'#default_value' => isset($instance['settings']['name']) ? $instance['settings']['name'] : '',
+			'#description' => t('This title will always be used if &ldquo;Static Title&rdquo; is selected above.'),
+	);
+
+
+
+
+
+	$form['ov'] = array(
+			'#type' => 'textfield',
+			'#title' => t('Ov'),
+			'#description' => t('Value'),
+			#'#default_value' => empty($instance['settings']['attributes']['rel']) ? '' : $instance['settings']['attributes']['rel'],
+			#'#field_prefix' => 'rel = "',
+			#'#field_suffix' => '"',
+			'#size' => 100,
+	);
+
+	$form['nov'] = array(
+			'#type' => 'textfield',
+			'#title' => t('Nov'),
+			'#description' => t('Normalised Value'),
+			#'#default_value' => empty($instance['settings']['attributes']['rel']) ? '' : $instance['settings']['attributes']['rel'],
+			#'#field_prefix' => 'rel = "',
+			#'#field_suffix' => '"',
+			'#size' => 100,
+	);
+	
+	$form['romanization'] = array(
+			'#type' => 'textfield',
+			'#title' => t('Romanization'),
+			'#description' => t('Normalised Value (LOC)'),
+			#'#default_value' => empty($instance['settings']['attributes']['rel']) ? '' : $instance['settings']['attributes']['rel'],
+			#'#field_prefix' => 'rel = "',
+			#'#field_suffix' => '"',
+			'#size' => 100,
+	);
+
+
+	return $form;
+}
+
+/**
+ * #element_validate handler for openmindattribute_field_instance_settings_form().
+ */
+function openmindattribute_field_settings_form_validate($element, &$form_state, $complete_form) {
+	return true;
+}
+
+/**
+ * Implements hook_field_is_empty().
+ */
+function openmindattribute_field_is_empty($item, $field) {
+	return false;
+}
+
+#/**
+# * Implements hook_field_load().
+# */
+#function link_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
+#  foreach ($entities as $id => $entity) {
+#    foreach ($items[$id] as $delta => $item) {
+#      $items[$id][$delta]['attributes'] = _link_load($field, $item, $instances[$id]);
+#    }
+#  }
+#}
+
+/**
+ * Implements hook_field_validate().
+ */
+function openmindattribute_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
+	return true;
+}
+
+
+
+/**
+ * Implements hook_field_insert().
+ */
+function openmindattribute_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
+	foreach ($items as $delta => $value) {
+		_openmindattribute_process($items[$delta], $delta, $field, $entity);
+	}
+}
+
+/**
+ * Implements hook_field_update().
+ */
+function openmindattribute_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
+	foreach ($items as $delta => $value) {
+		_openmindattribute_process($items[$delta], $delta, $field, $entity);
+	}
+}
+
+#/**
+# * Implements hook_field_prepare_view().
+#*/
+#function openmindattribute_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
+#  foreach ($items as $entity_id => $entity_items) {
+#    foreach ($entity_items as $delta => $value) {
+#      _link_sanitize($items[$entity_id][$delta], $delta, $field, $instances[$entity_id], $entities[$entity_id]);
+#    }
+#  }
+#}
+
+/**
+ * Implements hook_field_widget_info().
+ */
+function openmindattribute_field_widget_info() {
+	return array(
+			'openmindattribute_field' => array(
+					'label' => 'Attribute',
+					'field types' => array('openmindattribute_field'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_fields' => array(
+					'label' => 'NOTHING',
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_NONE
+			),
+	);
+}
+
+/**
+ * Implements hook_field_widget_form().
+ */
+function openmindattribute_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+
+
+	if ($field['type'] == 'openmindattribute_fields'){ // nur ausgabe feld!
+		return $element;
+	}
+	$element += array(
+			'#type' => $instance['widget']['type'],
+			'#default_value' =>  isset($items[$delta]) ? $items[$delta] : '',
+	);
+	return $element;
+}
+
+#/**
+# * Implements hook_field_widget_error().
+# */
+#function link_field_widget_error($element, $error, $form, &$form_state) {
+#  if ($error['error_element']['title']) {
+#    form_error($element['title'], $error['message']);
+#  }
+#  elseif ($error['error_element']['url']) {
+#    form_error($element['url'], $error['message']);
+#  }
+#}
+
+
+/**
+ * Prepares the item attributes and url for storage.
+ */
+function _openmindattribute_process(&$item, $delta = 0, $field, $entity) {
+	// Trim whitespace from URL.
+	$item['name'] = trim($item['name']);
+}
+
+
+
+
+/**
+ * Implements hook_theme().
+ */
+function openmindattribute_theme() {
+	return array(
+			'openmindattribute_formatter_default' => array(
+					'variables' => array('element' => NULL, 'field' => NULL, 'entity' => NULL),
+			),
+			'openmindattribute_formatter_fields_default' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			'openmindattribute_formatter_fields_specialized' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			'openmindattribute_formatter_field_identifier' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+			'openmindattribute_formatter_field_full_title' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+			
+			'openmindattribute_formatter_field_full_title_translit_romanization' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+
+			'openmindattribute_formatter_field_name_translit_romanization' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+			'openmindattribute_formatter_field_name' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL, 'nid' => NULL),
+			),
+				
+			'openmindattribute_formatter_field_ahlwardt' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+			'openmindattribute_formatter_fields_diva_link' => array(
+					'variables' => array('type' => NULL,'entid' => NULL)
+							),
+			
+			'openmindattribute_formatter_field_MPIWG_viewer' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			'openmindattribute_item_thumbnail'  => array(
+					'variables' => array('objid' => NULL,'entid' => NULL,'objdata'=>NULL,'type'=>NULL),
+				
+			),
+			
+			
+			'openmindattribute_reference_format' => array (
+					'variables' => array('type' => NULL,'entid' => NULL, 'attributes' => NULL, 'ov' => NULL, 'nid' => NULL ),
+			
+			),
+
+			
+						
+			
+			
+	);
+}
+
+function theme_openmindattribute_item_thumbnail($vars) {
+
+	$vars['objdata'] = digitalobjects_readMetadata($vars['objid']);
+	
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute-item-thumbnail.tpl.php", $vars);
+
+}
+
+
+function theme_openmindattribute_reference_format($vars){
+	
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_reference_format.tpl.php", $vars);
+	
+}
+
+/**
+ * Formats a link field widget.
+ */
+function theme_openmindattribute_field($vars) {
+	drupal_add_css(drupal_get_path('module', 'openmindattribute') . '/openmindattribute.css');
+	$element = $vars['element'];
+	// Prefix single value link fields with the name of the field.
+
+
+	$output = '';
+	$output .= '<div class="openmindattribute-field-subrow clearfix">';
+	$output = $output . $element['name'];
+	$output = $output . $element['ov'];
+	$output = $output . $element['nov'];
+	$output = $output . $element['romanization'];
+
+	return $output;
+}
+
+/**
+ * Implements hook_element_info().
+ */
+function openmindattribute_element_info() {
+	$elements = array();
+	$elements['openmindattribute_field'] = array(
+			'#input' => TRUE,
+			'#process' => array('openmindattribute_field_process'),
+			'#theme' => 'openmindattribute_field',
+			'#theme_wrappers' => array('form_element'),
+	);
+	return $elements;
+}
+
+
+
+/**
+ * Processes the link type element before displaying the field.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $complete_form['#field_info'][$element['#field_name']].
+ */
+function openmindattribute_field_process($element, $form_state, $complete_form) {
+
+	$instance = field_widget_instance($element, $form_state);
+
+	$settings = $instance['settings'];
+	$element['name'] = array(
+			'#type' => 'textfield',
+			'#maxlength' => 1000,
+			'#title' => t('name'),
+			'#required' =>  FALSE,
+			'#default_value' => isset($element['#value']['name']) ? $element['#value']['name'] : NULL,
+	);
+
+	$element['ov'] = array(
+			'#type' => 'textfield',
+			'#maxlength' => 1000,
+			'#title' => t('ov'),
+			'#required' =>  FALSE,
+			'#default_value' => isset($element['#value']['ov']) ? $element['#value']['ov'] : NULL,
+	);
+
+	$element['nov'] = array(
+			'#type' => 'textfield',
+			'#maxlength' => 1000,
+			'#title' => t('nov'),
+			'#required' =>  FALSE,
+			'#default_value' => isset($element['#value']['nov']) ? $element['#value']['nov'] : NULL,
+	);
+	
+	$element['romanization'] = array(
+			'#type' => 'textfield',
+			'#maxlength' => 1000,
+			'#title' => t('romanization'),
+			'#required' =>  FALSE,
+			'#default_value' => isset($element['#value']['romanization']) ? $element['#value']['romanization'] : NULL,
+	);
+
+
+
+	return $element;
+}
+
+/**
+ * Implements hook_field_formatter_info().
+ */
+function openmindattribute_field_formatter_info() {
+	return array(
+			
+			
+			'openmindattribute_reference_format' => array(
+					'label' => t('Formats a title field with the field selected, depending on the value of oc'),
+					'field types' => array('text'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_default' => array(
+					'label' => t('Attribute as default'),
+					'field types' => array('openmindattribute_field'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_fields_default' => array(
+					'label' => t('All Attribute as default'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_fields_specialized' => array(
+					'label' => t('All Attribute as specialized'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_fields_diva_link' => array(
+					'label' => t('DIVA-openmind-view'),
+					'field types' => array('text'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_field_identifier' => array(
+					'label' => t('Only the attribute identifer'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_field_full_title' => array(
+					'label' => t('Only the attribute full_title'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_field_full_title_translit_romanization' => array(
+					'label' => t('Only the attribute full_title_translit_romanization'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_field_name_translit_romanization' => array(
+					'label' => t('Only the attribute name_translit_romanization'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_field_ahlwardt' => array(
+					'label' => t('Only the attribute ahlwardt'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+				
+			'openmindattribute_field_name' => array(
+					'label' => t('Only the attribute name'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			
+			
+			'openmindattribute_field_MPIWG_viewer' => array(
+					'label' => t('MPIWG Image viewer'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_field_MPIWG_viewer_for_view' => array(
+					'label' => t('MPIWG Image viewer (for use in views)'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			
+	);
+}
+
+#/**
+# * Implements hook_field_formatter_settings_form().
+# */
+#function openmindattribute_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
+#  $display = $instance['display'][$view_mode];
+#  $settings = $display['settings'];
+#  $element = array();
+#  if ($display['type'] == 'link_domain') {
+#    $element['strip_www'] = array(
+#     '#title' => t('Strip www. from domain'),
+#      '#type' => 'checkbox',
+#      '#default_value' => $settings['strip_www'],
+#    );
+##  }
+#  return $element;
+#}
+
+#/**
+# * Implements hook_field_formatter_settings_summary().
+# */
+#function link_field_formatter_settings_summary($field, $instance, $view_mode) {
+#  $display = $instance['display'][$view_mode];
+#  $settings = $display['settings'];
+#  if ($display['type'] == 'link_domain') {
+#    if ($display['settings']['strip_www']) {
+#      return t('Strip www. from domain');
+#    }
+##    else {
+#     return t('Leave www. in domain');
+#   }
+# }
+# return '';
+#}
+
+
+function _openmindattribute_field_remap($atts){
+	//erzeuge eine array mit name -> (ov, nov,name)
+	$retmap = array();
+	foreach ($atts as $a){
+		$retmap[$a['name']]=$a;
+	}
+	return $retmap;
+}
+
+
+
+
+
+/**
+ * Implements hook_field_formatter_view().
+ */
+function openmindattribute_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+
+
+	#openmindattribute_fields ist nur experimentell, TODO: insbesondere field_oc, field_attribute sollte nicht hardcoded vorliegen.
+	
+	$elements= array();
+	
+	if ($field['type'] == 'text'){ // nur ausgabe feld!
+		
+		
+		
+		switch($display['type']){
+			
+			
+		case ("openmindattribute_fields_diva_link"):
+			
+			foreach ($items as $delta => $item) {
+			$entid =  $entity->field_id['und'][0]['value'];
+			
+			$ocid = $entity->field_oc['und'][0]['tid'];
+				 
+			$term = taxonomy_term_load($ocid);
+				 
+		
+			$elements[$delta] = array(
+					'#theme' => 'openmindattribute_formatter_fields_diva_link',
+					'#entid' => $entid,
+					'#type' => $term->name
+		
+			);
+			}
+		
+			return $elements;
+			
+			
+			break;
+			
+			case ("openmindattribute_reference_format"):
+					
+				foreach ($items as $delta => $item) {
+					$entid =  $entity->field_id['und'][0]['value'];
+						
+					$ocid = $entity->field_oc['und'][0]['tid'];
+						
+					$term = taxonomy_term_load($ocid);
+					
+
+					$atts =  $entity->field_attribute['und'];
+					
+					$atts_mapped = _openmindattribute_field_remap($atts);
+					
+					
+					
+						
+			
+					$elements[$delta] = array(
+							'#theme' => 'openmindattribute_reference_format',
+							'#entid' => $entid,
+							'#type' => $term->name,
+							'#attributes' => $atts_mapped,
+							'#ov' =>$entity->field_ov['und'][0]['value'],
+							'#nid' => $entity->nid
+								
+			
+					);
+				}
+			
+				return $elements;
+		}
+		
+		
+		
+		
+		
+		
+	}
+		
+	
+	if ($field['type'] == 'openmindattribute_fields'){ // nur ausgabe feld!
+		
+		switch($display['type']){
+
+			
+			case ("openmindattribute_fields_specialized"):
+				
+				 
+				$ocid = $entity->field_oc['und'][0]['tid'];
+				 
+				$term = taxonomy_term_load($ocid);
+				 
+				
+				$atts =  $entity->field_attribute['und'];
+				
+				$atts_mapped = _openmindattribute_field_remap($atts);
+				 
+
+				$elements = array(
+						'#theme' => 'openmindattribute_formatter_fields_specialized',
+						'#attributes' => $atts_mapped,
+						'#type' => $term->name
+				);
+				
+				break;
+
+			case ("openmindattribute_fields_default"):
+			
+
+				$ocid = $entity->field_oc['und'][0]['tid'];
+
+				$term = taxonomy_term_load($ocid);
+
+
+
+				$elements = array(
+						'#theme' => 'openmindattribute_formatter_fields_default',
+						'#attributes' => $entity->field_attribute['und'],
+						'#type' => $term->name
+				);
+			
+				break;
+				
+			// show only the identifier TODO only preliminary should define a formatter where you can configure the field
+			
+				
+				case ("openmindattribute_field_identifier"):
+					
+					//foreach ($items as $delta => $item) {					
+					$ocid = $entity->field_oc['und'][0]['tid'];
+						
+					$term = taxonomy_term_load($ocid);
+						
+				
+					$atts =  $entity->field_attribute['und'];
+				
+					$atts_mapped = _openmindattribute_field_remap($atts);
+					
+				
+					$output = array(
+						'#theme' => 'openmindattribute_formatter_field_identifier',
+						'#attributes' => $atts_mapped,
+						'#type' => $term->name,
+					);
+					
+					$elements[] =  $output;
+							 
+					//}		
+				
+				
+				    //$elements[$delta] = array ('#markup' => render($element_tmp));	
+					//}
+				    break;
+					
+				    case ("openmindattribute_field_full_title"):
+				    		
+				    	//foreach ($items as $delta => $item) {
+				    	$ocid = $entity->field_oc['und'][0]['tid'];
+				    
+				    	$term = taxonomy_term_load($ocid);
+				    
+				    
+				    	$atts =  $entity->field_attribute['und'];
+				    
+				    	$atts_mapped = _openmindattribute_field_remap($atts);
+				    		
+				    
+				    	$output = array(
+				    			'#theme' => 'openmindattribute_formatter_field_full_title',
+				    			'#attributes' => $atts_mapped,
+				    			'#type' => $term->name,
+				    	);
+				    		
+				    	$elements[] =  $output;
+				    
+				    	//}
+				    
+				    
+				    	//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    	//}
+				    	break;
+				    	
+				    	
+				    	case ("openmindattribute_field_full_title_translit_romanization"):
+				    	
+				    		//foreach ($items as $delta => $item) {
+				    		$ocid = $entity->field_oc['und'][0]['tid'];
+				    	
+				    		$term = taxonomy_term_load($ocid);
+				    	
+				    	
+				    		$atts =  $entity->field_attribute['und'];
+				    	
+				    		$atts_mapped = _openmindattribute_field_remap($atts);
+				    	
+				    	
+				    		$output = array(
+				    				'#theme' => 'openmindattribute_formatter_field_full_title_translit_romanization',
+				    				'#attributes' => $atts_mapped,
+				    				'#type' => $term->name,
+				    		);
+				    	
+				    		$elements[] =  $output;
+				    	
+				    		//}
+				    	
+				    	
+				    		//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    		//}
+				    		break;
+				    		 
+				    		
+				    		case ("openmindattribute_field_name_translit_romanization"):
+				    			 
+				    			//foreach ($items as $delta => $item) {
+				    			$ocid = $entity->field_oc['und'][0]['tid'];
+				    			 
+				    			$term = taxonomy_term_load($ocid);
+				    			 
+				    			 
+				    			$atts =  $entity->field_attribute['und'];
+				    			 
+				    			$atts_mapped = _openmindattribute_field_remap($atts);
+				    			 
+				    			 
+				    			$output = array(
+				    					'#theme' => 'openmindattribute_formatter_field_name_translit_romanization',
+				    					'#attributes' => $atts_mapped,
+				    					'#type' => $term->name,
+				    			);
+				    			 
+				    			$elements[] =  $output;
+				    			 
+				    			//}
+				    			 
+				    			 
+				    			//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    			//}
+				    			break;
+				    	case ("openmindattribute_field_name"):
+				    	
+				    		//foreach ($items as $delta => $item) {
+				    		$ocid = $entity->field_oc['und'][0]['tid'];
+				    	
+				    		$term = taxonomy_term_load($ocid);
+				    	
+				    	
+				    		$atts =  $entity->field_attribute['und'];
+				    	
+				    		$atts_mapped = _openmindattribute_field_remap($atts);
+				    		
+				    		
+				    		$nid = $entity->nid;
+
+				    		$output = array(
+				    				'#theme' => 'openmindattribute_formatter_field_name',
+				    				'#attributes' => $atts_mapped,
+				    				'#type' => $term->name,
+				    				'#nid' => $nid
+				    		);
+				    	
+				    		$elements[] =  $output;
+				    	
+				    		//}
+				    	
+				    	
+				    		//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    		//}
+				    		break;
+				    		 
+				    	
+				    case ("openmindattribute_field_ahlwardt"):
+				    		
+				    	//foreach ($items as $delta => $item) {
+				    	$ocid = $entity->field_oc['und'][0]['tid'];
+				    
+				    	$term = taxonomy_term_load($ocid);
+				    
+				    
+				    	$atts =  $entity->field_attribute['und'];
+				    
+				    	$atts_mapped = _openmindattribute_field_remap($atts);
+				    		
+				    
+				    	$output = array(
+				    			'#theme' => 'openmindattribute_formatter_field_ahlwardt',
+				    			'#attributes' => $atts_mapped,
+				    			'#type' => $term->name,
+				    	);
+				    		
+				    	$elements[] =  $output;
+				    
+				    	//}
+				    
+				    
+				    	//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    	//}
+				    	break;
+					
+					case ("openmindattribute_field_MPIWG_viewer"):
+						
+						
+						$ocid = $entity->field_oc['und'][0]['tid'];
+					
+						$term = taxonomy_term_load($ocid);
+					
+					
+						$atts =  $entity->field_attribute['und'];
+					
+						$atts_mapped = _openmindattribute_field_remap($atts);
+							
+					
+						if (isset($atts_mapped['mpiwg_id']['ov'])){
+						
+						$elements = array(
+								'#theme' => 'digitalobjects_item_thumbnail',
+								'#objid' => strtoupper($atts_mapped['mpiwg_id']['ov']),
+							
+					
+					
+						);
+						
+						
+						}
+					
+					break;
+					
+					case ("openmindattribute_field_MPIWG_viewer_for_view"):
+					
+					
+							
+						
+						
+						
+						$ocid = $entity->field_oc['und'][0]['tid'];
+							
+						$term = taxonomy_term_load($ocid);
+							
+							
+						$atts =  $entity->field_attribute['und'];
+							
+						$atts_mapped = _openmindattribute_field_remap($atts);
+							
+						$entid =  $entity->field_id['und'][0]['value'];
+							
+						if (isset($atts_mapped['mpiwg_id']['ov'])){
+					
+							$elements[] = array(
+									'#theme' => 'openmindattribute_item_thumbnail',
+									'#objid' => strtoupper($atts_mapped['mpiwg_id']['ov']),
+									'#entid' => $entid,
+									'#type' =>  $term->name,
+										
+										
+										
+							);
+					
+					
+						}
+							
+						break;
+							
+
+		}
+
+	
+		return $elements;
+	} else {
+
+
+		$elements = array();
+
+
+		foreach ($items as $delta => $item) {
+			$elements[$delta] = array(
+					'#theme' => 'openmindattribute_formatter_default',
+					'#element' => $item,
+					'#field' => $instance,
+					'#display' => $display,
+					'#entity' => $entity
+			);
+		}
+		return $elements;
+	}
+}
+
+/**
+ * Formats a link.
+ */
+function theme_openmindattribute_formatter_default($vars) {
+
+
+	$entity = $vars['type'];
+
+
+	$ocid = $entity->field_oc['und'][0]['tid'];
+
+
+	$term = taxonomy_term_load($ocid);
+
+
+
+	return $vars['element']['name'] . $vars['element']['ov'] . $vars['element']['nov'] . $vars['element']['romanization'];
+
+}
+
+function theme_openmindattribute_formatter_fields_specialized($vars) {
+
+	$type = $vars['type'];
+
+	
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_" . $type . ".tpl.php", $vars);
+
+	
+
+
+	
+
+}
+
+
+
+function theme_openmindattribute_formatter_field_identifier($vars) {
+	
+	$type = $vars['type'];
+	
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_identifier.tpl.php", $vars);
+
+
+
+	
+}
+
+
+function theme_openmindattribute_formatter_field_full_title($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_full_title.tpl.php", $vars);
+
+
+
+
+}
+
+
+
+function theme_openmindattribute_formatter_field_full_title_translit_romanization($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_full_title_translit_romanization.tpl.php", $vars);
+
+
+
+
+}
+
+function theme_openmindattribute_formatter_field_name_translit_romanization($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_name_translit_romanization.tpl.php", $vars);
+
+
+
+
+}
+
+
+
+function theme_openmindattribute_formatter_field_name($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_name.tpl.php", $vars);
+
+
+
+
+}
+
+
+
+function theme_openmindattribute_formatter_field_ahlwardt($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_ahlwardt.tpl.php", $vars);
+
+
+
+
+}
+
+function theme_openmindattribute_formatter_field_MPIWG_viewer($vars) {
+	
+	$type = $vars['type'];
+	
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_MPIWG_viewer.tpl.php", $vars);
+
+	
+}
+
+
+function theme_openmindattribute_formatter_fields_default($vars) {
+
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_default.tpl.php", $vars);
+	
+	
+
+
+	
+}
+
+function theme_openmindattribute_formatter_fields_diva_link($vars) {
+		
+	
+		return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_diva_link.tpl.php", $vars);
+	
+}
+
+
+/**
+ * Implements hook_views_api().
+ */
+function openmindattribute_views_api() {
+	return array(
+			'api' => 2,
+			'path' => drupal_get_path('module', 'openmindattribute') . '/views',
+	);
+}
+
+/**
+ * Implements hook_field_settings_form().
+ */
+function openmindattribute_field_settings_form() {
+	return array();
+}
+
+/**
+ * Additional callback to adapt the property info of link fields.
+ *
+ * @see entity_metadata_field_entity_property_info().
+ */
+function openmindattribute_field_property_info_callback(&$info, $entity_type, $field, $instance, $field_type) {
+	$property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$field['field_name']];
+	// Define a data structure so it's possible to deal with both the link title
+	// and URL.
+	$property['getter callback'] = 'entity_metadata_field_verbatim_get';
+	$property['setter callback'] = 'entity_metadata_field_verbatim_set';
+
+	// Auto-create the field item as soon as a property is set.
+	$property['auto creation'] = 'openmindattribute_field_item_create';
+
+	$property['property info'] = openmindattribute_field_item_property_info();
+	$property['property info']['name']['required'] = !$instance['settings']['name'];
+	$property['property info']['ov']['required'] = ($instance['settings']['ov'] == 'required');
+	if ($instance['settings']['ov'] == 'none') {
+		unset($property['property info']['ov']);
+	}
+
+	$property['property info']['nov']['required'] = ($instance['settings']['nov'] == 'required');
+	if ($instance['settings']['nov'] == 'none') {
+		unset($property['property info']['nov']);
+	}
+	unset($property['query callback']);
+}
+
+/**
+ * Callback for creating a new, empty link field item.
+ *
+ * @see link_field_property_info_callback()
+ */
+function openmindattribute_field_item_create() {
+	return array('title' => NULL, 'url' => NULL);
+}
+
+/**
+ * Defines info for the properties of the link-field item data structure.
+ */
+function openmindattribute_field_item_property_info() {
+	$properties['ov'] = array(
+			'type' => 'text',
+			'label' => t('The OV.'),
+			'setter callback' => 'entity_property_verbatim_set',
+	);
+	$properties['name'] = array(
+			'type' => 'text',
+			'label' => t('The name of the attribute'),
+			'setter callback' => 'entity_property_verbatim_set',
+	);
+
+	$properties['nov'] = array(
+			'type' => 'text',
+			'label' => t('The NOV'),
+			'setter callback' => 'entity_property_verbatim_set',
+	);
+	return $properties;
+}
+
+#/**
+# * Implements hook_field_update_instance().
+# */
+#function openmindattribute_field_update_instance($instance, $prior_instance) {
+#  if (function_exists('i18n_string_update') && $instance['widget']['type'] == 'openmindattribute_field' ) {
+#    $i18n_string_name = "field:{$instance['field_name']}:{$instance['bundle']}:title_value";
+#    i18n_string_update($i18n_string_name, $instance['settings']['title_value']);
+#  }
+#}
+
+/**
+ * Implements hook_i18n_string_list_TEXTGROUP_alter().
+ */
+#function link_i18n_string_list_field_alter(&$strings, $type = NULL, $object = NULL) {
+#  if ($type != 'field_instance' || !is_array($object) || !isset($object['widget']['type'])) {
+#    return;
+#  }
+#  if ($object['widget']['type'] == 'link_field' && isset($object['settings']['title_value'])) {
+##    $strings['field'][$object['field_name']][$object['bundle']]['title_value']['string'] = $object['settings']['title_value'];
+#}
+#}
+
+
+/**
+ * @file
+ *  implementation of Feeds mapping API for link.module.
+ */
+
+/**
+ * Implements hook_feeds_processor_targets_alter().
+ *
+ * @see FeedsProcessor::getMappingTargets()
+ */
+/*
+ function openmindattribute_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
+
+ foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
+ $info = field_info_field($name);
+
+ if ($info['type'] == 'openmindattribute_field') {
+ if (array_key_exists('name', $info['columns'])) {
+ $targets[$name . ':name'] = array(
+ 'name' => t('@name: name', array('@name' => $instance['label'])),
+ 'callback' => 'openmindattribute_feeds_set_target',
+ 'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+ 'real_target' => $name,
+ );
+ }
+ if (array_key_exists('ov', $info['columns'])) {
+ $targets[$name . ':ov'] = array(
+ 'name' => t('@name: OV', array('@name' => $instance['label'])),
+ 'callback' => 'openmindattribute_feeds_set_target',
+ 'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+ 'real_target' => $name,
+ );
+ }
+ if (array_key_exists('ov', $info['columns'])) {
+ $targets[$name . ':nov'] = array(
+ 'name' => t('@name: NOV', array('@name' => $instance['label'])),
+ 'callback' => 'openmindattribute_feeds_set_target',
+ 'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+ 'real_target' => $name,
+ );
+ }
+ }
+ }
+ }
+ */
+
+function openmindattribute_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
+
+	foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
+		$info = field_info_field($name);
+		#map the whole attr
+
+		if ($info['type'] == 'openmindattribute_field') {
+			$targets[$name] = array(
+					'name' => t('@name', array('@name' => $instance['label'])),
+					'callback' => 'openmindattribute_feeds_set_target',
+					'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+					'real_target' => $name,
+			);
+		}
+			
+
+	}
+}
+
+
+
+/**
+ * Callback for mapping. Here is where the actual mapping happens.
+ *
+ * When the callback is invoked, $target contains the name of the field the
+ * user has decided to map to and $value contains the value of the feed item
+ * element the user has picked as a source.
+ */
+/*
+ function openmindattribute_feeds_set_target($source, $entity, $target, $value) {
+if (empty($value)) {
+return;
+}
+
+// Handle non-multiple value fields.
+if (!is_array($value)) {
+$value = array($value);
+}
+
+// Iterate over all values.
+list($field_name, $column) = explode(':', $target);
+$info = field_info_field($field_name);
+
+$field = isset($entity->$field_name) ? $entity->$field_name : array();
+$delta = 0;
+
+foreach ($value as $v) {
+if ($info['cardinality'] == $delta) {
+break;
+}
+
+if (is_object($v) && ($v instanceof FeedsElement)) {
+$v = $v->getValue();
+}
+
+if (is_scalar($v)) {
+$field['und'][$delta][$column] = $v;
+$delta++;
+}
+}
+$entity->$field_name = $field;
+}
+*/
+
+function openmindattribute_feeds_set_target($source, $entity, $target, $value) {
+
+	if (empty($value)) {
+		return;
+	}
+
+	// Handle non-multiple value fields.
+	if (!is_array($value)) {
+		$value = array($value);
+	}
+
+	// Iterate over all values.
+	#list($field_name, $column) = explode(':', $target);
+
+	$field_name=$target;
+	$info = field_info_field($field_name);
+
+	$field = isset($entity->$field_name) ? $entity->$field_name : array();
+	$delta = 0;
+
+	
+	foreach ($value as $v) {
+			
+		
+		if ($info['cardinality'] == $delta) {
+			break;
+		}
+
+		if (is_object($v) && ($v instanceof FeedsElement)) {
+			$v = $v->getValue();
+		}
+
+		if (is_scalar($v)) {
+			$field['und'][$delta] = $v;
+			$delta++;
+		}
+		
+		if (is_array($v)){
+			$newVal = array();
+			$newVal['ov'] = $v['ov'];
+			$newVal['nov'] = $v['nov'];
+			$newVal['name'] = $v['name'];
+			$newVal['romanization'] = $v['romanization'];
+			$field['und'][$delta]= $newVal;
+			$delta++;
+				
+		}
+	}
+	$entity->$field_name = $field;
+}
+
+
+function openmindattribute_addIDs(){
+	#adds the author id from openmind to the biographies and umgekehrt
+	$query = new EntityFieldQuery();
+
+	$query->entityCondition('entity_type', 'node')
+	->entityCondition('bundle', 'openmind_entity')
+	->propertyCondition('status', 1)
+	->fieldCondition('field_oc', 'tid', '1', '='); #1 is PERSON #TODO should search for PERSON and not the id
+
+	$result = $query->execute();
+
+
+	if (isset($result['node'])) {
+		$persons_nids = array_keys($result['node']);
+		$persons = entity_load('node', $persons_nids);
+
+
+	}
+
+	#hole mapping bea url -> id
+
+	$beamapping=array();
+	$beamappingNodeId=array();
+	foreach ($persons as $person){
+
+		$attrs = $person->field_attribute['und'];
+
+		
+		$mappedattrs = _openmindattribute_field_remap($attrs);
+		
+		if (isset($mappedattrs['url'])){
+		
+		$url = $mappedattrs['url']['ov'];
+						
+		$exploded = explode("/", $url);
+		
+		#urls haben die Form http://islamsci.mcgill.ca/rasi/bea/tusi_bea.htm
+		#mich interessiert nur das ende ohne htm
+		
+		dpm($exploded);
+		$ident = $exploded[count($exploded)-1];
+		dpm($ident);
+		$ident = strtolower(str_replace(".htm", "", $ident));
+
+		dpm($ident);
+		$beamapping[$ident]=$person->field_id['und'][0]['value'];
+		//$beamappingNodeId[$ident]=$person->nid;
+		$beamappingNodeId[$ident][]=$person->nid;
+		}
+
+	}
+	
+	#hole jetzt alle biographien
+	
+	$query = new EntityFieldQuery();
+	
+	$query->entityCondition('entity_type', 'node')
+	->entityCondition('bundle', 'biography');
+	
+	
+	$result = $query->execute();
+	
+	
+	if (isset($result['node'])) {
+		$bios_nids = array_keys($result['node']);
+		$bios = entity_load('node', $bios_nids);
+		
+	}
+	
+	foreach ($bios as $bio){
+		$url = strtolower(drupal_get_path_alias("node/" . $bio->nid));
+		
+		dpm($url);
+		
+		if (isset ($beamapping[$url])){
+		$authorid = $beamapping[$url];
+		
+		$bio->field_id['und'][0]['value']=$authorid;
+		
+		
+		
+		
+		node_save($bio);
+		
+		dpm($url . " -->" . $authorid);
+		
+		dpm($bio);
+		
+		
+		foreach ($beamappingNodeId[$url] as $entNid){
+		//$entNid = $beamappingNodeId[$url];
+		
+		$ent = entity_load_single("node", $entNid);
+		
+		$ent->field_bio_id['und'][0]['value']=$bio->nid;
+		$ent->field_bio_id_reference['und'][0]['nid']=$bio->nid;
+		dpm($ent);
+		dpm($ent->nid);
+		node_save($ent);
+		}}
+		
+	}
+
+
+}
+
+function openmindattribute_addIDbibliographieID(){
+	#adds the add bibliographie
+	$query = new EntityFieldQuery();
+
+	$query->entityCondition('entity_type', 'node')
+	->entityCondition('bundle', 'openmind_entity')
+	->propertyCondition('status', 1)
+	->fieldCondition('field_oc', 'tid', '10', '='); #10 is reference #TODO should search for REFERENCE nd not the id
+ 
+	$result = $query->execute();
+	
+	
+	if (isset($result['node'])) {
+		$reference_nids = array_keys($result['node']);
+		$references = entity_load('node', $reference_nids);
+
+	}
+
+	foreach ($references as $reference){
+		#{King, 1983 #1290} References haben diese Titel
+		# Hole die Nummer
+		
+		$exploded = explode("#", $reference->title);
+		$number = str_replace("}", "", $exploded[1]);
+		
+		
+		#suche jetzt in biblios nach der Nummer "=feld Custom 3"
+		
+		$query = db_select('node', 'n');
+		$query->addField('n', 'nid');
+		$query->leftJoin('biblio', 'b', 'n.vid=b.vid');
+		
+		$query->addField('b', 'biblio_custom3');
+		$query->condition("b.biblio_custom3", $number);
+		
+		$results=$query->execute();
+		
+		foreach ($results as $node){
+			$nid= $node->nid;
+			$ent = entity_load_single("node", $nid);
+			dpm($reference);
+			$reference->field_biblio_reference['und'][0]['nid']=$nid;
+			node_submit($reference);
+			node_save($reference);
+		}
+		
+		
+	}
+}
+
+
+function _openmindattribute_collection_list($name,&$form){
+	$query = new EntityFieldQuery();
+	
+	$query->entityCondition('entity_type', 'node')
+	->entityCondition('bundle', 'openmind_entity')
+	->propertyCondition('status', 1)
+	->fieldCondition('field_oc', 'tid', '8', '='); #8 is COLLECTION #TODO should search for COLLECTION and not the id
+	
+	$result = $query->execute();
+	
+	$options = array();
+	
+	if (isset($result['node'])) {
+		$cols_nids = array_keys($result['node']);
+		$cols = entity_load('node', $cols_nids);
+	
+	
+	}
+	
+	
+	$options['']='All';
+	
+	$titel = array();
+	
+	foreach ($cols as $col){
+		$titel[]=$col->title;
+	}
+	
+	sort($titel);
+	
+	foreach($titel as $t){
+		       $options[$t]=$t;
+	}
+	
+		
+	$form[$name]=array(
+			'#type' => 'radios',
+			'#options' => $options,
+			'#default_value' => ''
+	);
+}
+
+function openmindattribute_form_views_exposed_form_alter(&$form, $form_state, $form_id) {
+	
+	
+	if($form["#id"]=="views-exposed-form-codices-page-codices"){
+		_openmindattribute_collection_list("title",$form);
+	
+	
+	} elseif ($form["#id"]=="views-exposed-form-codices-page-2"){
+		
+		_openmindattribute_collection_list("title_1",$form);
+	}
+	
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/openmindattribute.module~	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,1535 @@
+<?php
+
+
+
+/**
+ * Implements hook_field_info().
+ */
+function openmindattribute_field_info() {
+	return array(
+			'openmindattribute_field' => array(
+					'label' => t('Attribute'),
+					'description' => t('The attribute'),
+					'default_widget' => 'openmindattribute_field',
+					'default_formatter' => 'openmindattribute_default',
+					// Support hook_entity_property_info() from contrib "Entity API".
+					'property_type' => 'field_item_openmindattribute',
+					'property_callbacks' => array('openmindattribute_field_property_info_callback')
+			),
+			'openmindattribute_fields' => array(
+					'label' => t('All Attributes'),
+					'description' => t('The attributes'),
+					'default_widget' => 'openmindattribute_fields',
+					'default_formatter' => 'openmindattribute_default',
+					// Support hook_entity_property_info() from contrib "Entity API".
+					#'property_type' => 'field_item_openmindattribute',
+					#'property_callbacks' => array('openmindattribute_field_property_info_callback')
+			),
+			'openmindattribute_field' => array(
+					'label' => t('Attribute'),
+					'description' => t('The attribute'),
+					'default_widget' => 'openmindattribute_field',
+					'default_formatter' => 'openmindattribute_default',
+					// Support hook_entity_property_info() from contrib "Entity API".
+					'property_type' => 'field_item_openmindattribute',
+					'property_callbacks' => array('openmindattribute_field_property_info_callback')
+			),
+			 
+	);
+}
+
+/**
+ * Implements hook_field_instance_settings_form().
+ */
+function openmindattribute_field_instance_settings_form($field, $instance) {
+
+	if ($field['type'] == 'openmindattribute_fields'){ // nur ausgabe feld!
+		$form['name'] = array(
+				'#type' => 'textfield',
+				'#title' => t('Name'),
+				'#default_value' => isset($instance['settings']['name']) ? $instance['settings']['name'] : '',
+				'#description' => t('This title will always be used if &ldquo;Static Title&rdquo; is selected above.'),
+		);
+		return $form;
+	}
+	$form = array(
+			'#element_validate' => array('openmindattribute_field_settings_form_validate'),
+	);
+
+
+
+	$form['name'] = array(
+			'#type' => 'textfield',
+			'#title' => t('Name'),
+			'#default_value' => isset($instance['settings']['name']) ? $instance['settings']['name'] : '',
+			'#description' => t('This title will always be used if &ldquo;Static Title&rdquo; is selected above.'),
+	);
+
+
+
+
+
+	$form['ov'] = array(
+			'#type' => 'textfield',
+			'#title' => t('Ov'),
+			'#description' => t('Value'),
+			#'#default_value' => empty($instance['settings']['attributes']['rel']) ? '' : $instance['settings']['attributes']['rel'],
+			#'#field_prefix' => 'rel = "',
+			#'#field_suffix' => '"',
+			'#size' => 100,
+	);
+
+	$form['nov'] = array(
+			'#type' => 'textfield',
+			'#title' => t('Nov'),
+			'#description' => t('Normalised Value'),
+			#'#default_value' => empty($instance['settings']['attributes']['rel']) ? '' : $instance['settings']['attributes']['rel'],
+			#'#field_prefix' => 'rel = "',
+			#'#field_suffix' => '"',
+			'#size' => 100,
+	);
+	
+	$form['romanization'] = array(
+			'#type' => 'textfield',
+			'#title' => t('Romanization'),
+			'#description' => t('Normalised Value (LOC)'),
+			#'#default_value' => empty($instance['settings']['attributes']['rel']) ? '' : $instance['settings']['attributes']['rel'],
+			#'#field_prefix' => 'rel = "',
+			#'#field_suffix' => '"',
+			'#size' => 100,
+	);
+
+
+	return $form;
+}
+
+/**
+ * #element_validate handler for openmindattribute_field_instance_settings_form().
+ */
+function openmindattribute_field_settings_form_validate($element, &$form_state, $complete_form) {
+	return true;
+}
+
+/**
+ * Implements hook_field_is_empty().
+ */
+function openmindattribute_field_is_empty($item, $field) {
+	return false;
+}
+
+#/**
+# * Implements hook_field_load().
+# */
+#function link_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
+#  foreach ($entities as $id => $entity) {
+#    foreach ($items[$id] as $delta => $item) {
+#      $items[$id][$delta]['attributes'] = _link_load($field, $item, $instances[$id]);
+#    }
+#  }
+#}
+
+/**
+ * Implements hook_field_validate().
+ */
+function openmindattribute_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
+	return true;
+}
+
+
+
+/**
+ * Implements hook_field_insert().
+ */
+function openmindattribute_field_insert($entity_type, $entity, $field, $instance, $langcode, &$items) {
+	foreach ($items as $delta => $value) {
+		_openmindattribute_process($items[$delta], $delta, $field, $entity);
+	}
+}
+
+/**
+ * Implements hook_field_update().
+ */
+function openmindattribute_field_update($entity_type, $entity, $field, $instance, $langcode, &$items) {
+	foreach ($items as $delta => $value) {
+		_openmindattribute_process($items[$delta], $delta, $field, $entity);
+	}
+}
+
+#/**
+# * Implements hook_field_prepare_view().
+#*/
+#function openmindattribute_field_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items) {
+#  foreach ($items as $entity_id => $entity_items) {
+#    foreach ($entity_items as $delta => $value) {
+#      _link_sanitize($items[$entity_id][$delta], $delta, $field, $instances[$entity_id], $entities[$entity_id]);
+#    }
+#  }
+#}
+
+/**
+ * Implements hook_field_widget_info().
+ */
+function openmindattribute_field_widget_info() {
+	return array(
+			'openmindattribute_field' => array(
+					'label' => 'Attribute',
+					'field types' => array('openmindattribute_field'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_fields' => array(
+					'label' => 'NOTHING',
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_NONE
+			),
+	);
+}
+
+/**
+ * Implements hook_field_widget_form().
+ */
+function openmindattribute_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+
+
+	if ($field['type'] == 'openmindattribute_fields'){ // nur ausgabe feld!
+		return $element;
+	}
+	$element += array(
+			'#type' => $instance['widget']['type'],
+			'#default_value' =>  isset($items[$delta]) ? $items[$delta] : '',
+	);
+	return $element;
+}
+
+#/**
+# * Implements hook_field_widget_error().
+# */
+#function link_field_widget_error($element, $error, $form, &$form_state) {
+#  if ($error['error_element']['title']) {
+#    form_error($element['title'], $error['message']);
+#  }
+#  elseif ($error['error_element']['url']) {
+#    form_error($element['url'], $error['message']);
+#  }
+#}
+
+
+/**
+ * Prepares the item attributes and url for storage.
+ */
+function _openmindattribute_process(&$item, $delta = 0, $field, $entity) {
+	// Trim whitespace from URL.
+	$item['name'] = trim($item['name']);
+}
+
+
+
+
+/**
+ * Implements hook_theme().
+ */
+function openmindattribute_theme() {
+	return array(
+			'openmindattribute_formatter_default' => array(
+					'variables' => array('element' => NULL, 'field' => NULL, 'entity' => NULL),
+			),
+			'openmindattribute_formatter_fields_default' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			'openmindattribute_formatter_fields_specialized' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			'openmindattribute_formatter_field_identifier' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+			'openmindattribute_formatter_field_full_title' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+			
+			'openmindattribute_formatter_field_full_title_translit_romanization' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+
+			'openmindattribute_formatter_field_name_translit_romanization' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+			'openmindattribute_formatter_field_name' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL, 'nid' => NULL),
+			),
+				
+			'openmindattribute_formatter_field_ahlwardt' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			
+			'openmindattribute_formatter_fields_diva_link' => array(
+					'variables' => array('type' => NULL,'entid' => NULL)
+							),
+			
+			'openmindattribute_formatter_field_MPIWG_viewer' => array(
+					'variables' => array('type' => NULL,  'attributes' => NULL),
+			),
+			'openmindattribute_item_thumbnail'  => array(
+					'variables' => array('objid' => NULL,'entid' => NULL,'objdata'=>NULL,'type'=>NULL),
+				
+			),
+			
+			
+			'openmindattribute_reference_format' => array (
+					'variables' => array('type' => NULL,'entid' => NULL, 'attributes' => NULL, 'ov' => NULL, 'nid' => NULL ),
+			
+			),
+
+			
+						
+			
+			
+	);
+}
+
+function theme_openmindattribute_item_thumbnail($vars) {
+
+	$vars['objdata'] = digitalobjects_readMetadata($vars['objid']);
+	
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute-item-thumbnail.tpl.php", $vars);
+
+}
+
+
+function theme_openmindattribute_reference_format($vars){
+	
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_reference_format.tpl.php", $vars);
+	
+}
+
+/**
+ * Formats a link field widget.
+ */
+function theme_openmindattribute_field($vars) {
+	drupal_add_css(drupal_get_path('module', 'openmindattribute') . '/openmindattribute.css');
+	$element = $vars['element'];
+	// Prefix single value link fields with the name of the field.
+
+
+	$output = '';
+	$output .= '<div class="openmindattribute-field-subrow clearfix">';
+	$output = $output . $element['name'];
+	$output = $output . $element['ov'];
+	$output = $output . $element['nov'];
+	$output = $output . $element['romanization'];
+
+	return $output;
+}
+
+/**
+ * Implements hook_element_info().
+ */
+function openmindattribute_element_info() {
+	$elements = array();
+	$elements['openmindattribute_field'] = array(
+			'#input' => TRUE,
+			'#process' => array('openmindattribute_field_process'),
+			'#theme' => 'openmindattribute_field',
+			'#theme_wrappers' => array('form_element'),
+	);
+	return $elements;
+}
+
+
+
+/**
+ * Processes the link type element before displaying the field.
+ *
+ * Build the form element. When creating a form using FAPI #process,
+ * note that $element['#value'] is already set.
+ *
+ * The $fields array is in $complete_form['#field_info'][$element['#field_name']].
+ */
+function openmindattribute_field_process($element, $form_state, $complete_form) {
+
+	$instance = field_widget_instance($element, $form_state);
+
+	$settings = $instance['settings'];
+	$element['name'] = array(
+			'#type' => 'textfield',
+			'#maxlength' => 1000,
+			'#title' => t('name'),
+			'#required' =>  FALSE,
+			'#default_value' => isset($element['#value']['name']) ? $element['#value']['name'] : NULL,
+	);
+
+	$element['ov'] = array(
+			'#type' => 'textfield',
+			'#maxlength' => 1000,
+			'#title' => t('ov'),
+			'#required' =>  FALSE,
+			'#default_value' => isset($element['#value']['ov']) ? $element['#value']['ov'] : NULL,
+	);
+
+	$element['nov'] = array(
+			'#type' => 'textfield',
+			'#maxlength' => 1000,
+			'#title' => t('nov'),
+			'#required' =>  FALSE,
+			'#default_value' => isset($element['#value']['nov']) ? $element['#value']['nov'] : NULL,
+	);
+	
+	$element['romanization'] = array(
+			'#type' => 'textfield',
+			'#maxlength' => 1000,
+			'#title' => t('romanization'),
+			'#required' =>  FALSE,
+			'#default_value' => isset($element['#value']['romanization']) ? $element['#value']['romanization'] : NULL,
+	);
+
+
+
+	return $element;
+}
+
+/**
+ * Implements hook_field_formatter_info().
+ */
+function openmindattribute_field_formatter_info() {
+	return array(
+			
+			
+			'openmindattribute_reference_format' => array(
+					'label' => t('Formats a title field with the field selected, depending on the value of oc'),
+					'field types' => array('text'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_default' => array(
+					'label' => t('Attribute as default'),
+					'field types' => array('openmindattribute_field'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_fields_default' => array(
+					'label' => t('All Attribute as default'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_fields_specialized' => array(
+					'label' => t('All Attribute as specialized'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_fields_diva_link' => array(
+					'label' => t('DIVA-openmind-view'),
+					'field types' => array('text'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_field_identifier' => array(
+					'label' => t('Only the attribute identifer'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_field_full_title' => array(
+					'label' => t('Only the attribute full_title'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_field_full_title_translit_romanization' => array(
+					'label' => t('Only the attribute full_title_translit_romanization'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_field_name_translit_romanization' => array(
+					'label' => t('Only the attribute name_translit_romanization'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			'openmindattribute_field_ahlwardt' => array(
+					'label' => t('Only the attribute ahlwardt'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+				
+			'openmindattribute_field_name' => array(
+					'label' => t('Only the attribute name'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			
+			
+			'openmindattribute_field_MPIWG_viewer' => array(
+					'label' => t('MPIWG Image viewer'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			'openmindattribute_field_MPIWG_viewer_for_view' => array(
+					'label' => t('MPIWG Image viewer (for use in views)'),
+					'field types' => array('openmindattribute_fields'),
+					'multiple values' => FIELD_BEHAVIOR_DEFAULT,
+			),
+			
+			
+	);
+}
+
+#/**
+# * Implements hook_field_formatter_settings_form().
+# */
+#function openmindattribute_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
+#  $display = $instance['display'][$view_mode];
+#  $settings = $display['settings'];
+#  $element = array();
+#  if ($display['type'] == 'link_domain') {
+#    $element['strip_www'] = array(
+#     '#title' => t('Strip www. from domain'),
+#      '#type' => 'checkbox',
+#      '#default_value' => $settings['strip_www'],
+#    );
+##  }
+#  return $element;
+#}
+
+#/**
+# * Implements hook_field_formatter_settings_summary().
+# */
+#function link_field_formatter_settings_summary($field, $instance, $view_mode) {
+#  $display = $instance['display'][$view_mode];
+#  $settings = $display['settings'];
+#  if ($display['type'] == 'link_domain') {
+#    if ($display['settings']['strip_www']) {
+#      return t('Strip www. from domain');
+#    }
+##    else {
+#     return t('Leave www. in domain');
+#   }
+# }
+# return '';
+#}
+
+
+function _openmindattribute_field_remap($atts){
+	//erzeuge eine array mit name -> (ov, nov,name)
+	$retmap = array();
+	foreach ($atts as $a){
+		$retmap[$a['name']]=$a;
+	}
+	return $retmap;
+}
+
+
+
+
+
+/**
+ * Implements hook_field_formatter_view().
+ */
+function openmindattribute_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
+
+
+	#openmindattribute_fields ist nur experimentell, TODO: insbesondere field_oc, field_attribute sollte nicht hardcoded vorliegen.
+	
+	$elements= array();
+	
+	if ($field['type'] == 'text'){ // nur ausgabe feld!
+		
+		
+		
+		switch($display['type']){
+			
+			
+		case ("openmindattribute_fields_diva_link"):
+			
+			foreach ($items as $delta => $item) {
+			$entid =  $entity->field_id['und'][0]['value'];
+			
+			$ocid = $entity->field_oc['und'][0]['tid'];
+				 
+			$term = taxonomy_term_load($ocid);
+				 
+		
+			$elements[$delta] = array(
+					'#theme' => 'openmindattribute_formatter_fields_diva_link',
+					'#entid' => $entid,
+					'#type' => $term->name
+		
+			);
+			}
+		
+			return $elements;
+			
+			
+			break;
+			
+			case ("openmindattribute_reference_format"):
+					
+				foreach ($items as $delta => $item) {
+					$entid =  $entity->field_id['und'][0]['value'];
+						
+					$ocid = $entity->field_oc['und'][0]['tid'];
+						
+					$term = taxonomy_term_load($ocid);
+					
+
+					$atts =  $entity->field_attribute['und'];
+					
+					$atts_mapped = _openmindattribute_field_remap($atts);
+					
+					
+					
+						
+			
+					$elements[$delta] = array(
+							'#theme' => 'openmindattribute_reference_format',
+							'#entid' => $entid,
+							'#type' => $term->name,
+							'#attributes' => $atts_mapped,
+							'#ov' =>$entity->field_ov['und'][0]['value'],
+							'#nid' => $entity->nid
+								
+			
+					);
+				}
+			
+				return $elements;
+		}
+		
+		
+		
+		
+		
+		
+	}
+		
+	
+	if ($field['type'] == 'openmindattribute_fields'){ // nur ausgabe feld!
+		
+		switch($display['type']){
+
+			
+			case ("openmindattribute_fields_specialized"):
+				
+				 
+				$ocid = $entity->field_oc['und'][0]['tid'];
+				 
+				$term = taxonomy_term_load($ocid);
+				 
+				
+				$atts =  $entity->field_attribute['und'];
+				
+				$atts_mapped = _openmindattribute_field_remap($atts);
+				 
+
+				$elements = array(
+						'#theme' => 'openmindattribute_formatter_fields_specialized',
+						'#attributes' => $atts_mapped,
+						'#type' => $term->name
+				);
+				
+				break;
+
+			case ("openmindattribute_fields_default"):
+			
+
+				$ocid = $entity->field_oc['und'][0]['tid'];
+
+				$term = taxonomy_term_load($ocid);
+
+
+
+				$elements = array(
+						'#theme' => 'openmindattribute_formatter_fields_default',
+						'#attributes' => $entity->field_attribute['und'],
+						'#type' => $term->name
+				);
+			
+				break;
+				
+			// show only the identifier TODO only preliminary should define a formatter where you can configure the field
+			
+				
+				case ("openmindattribute_field_identifier"):
+					
+					//foreach ($items as $delta => $item) {					
+					$ocid = $entity->field_oc['und'][0]['tid'];
+						
+					$term = taxonomy_term_load($ocid);
+						
+				
+					$atts =  $entity->field_attribute['und'];
+				
+					$atts_mapped = _openmindattribute_field_remap($atts);
+					
+				
+					$output = array(
+						'#theme' => 'openmindattribute_formatter_field_identifier',
+						'#attributes' => $atts_mapped,
+						'#type' => $term->name,
+					);
+					
+					$elements[] =  $output;
+							 
+					//}		
+				
+				
+				    //$elements[$delta] = array ('#markup' => render($element_tmp));	
+					//}
+				    break;
+					
+				    case ("openmindattribute_field_full_title"):
+				    		
+				    	//foreach ($items as $delta => $item) {
+				    	$ocid = $entity->field_oc['und'][0]['tid'];
+				    
+				    	$term = taxonomy_term_load($ocid);
+				    
+				    
+				    	$atts =  $entity->field_attribute['und'];
+				    
+				    	$atts_mapped = _openmindattribute_field_remap($atts);
+				    		
+				    
+				    	$output = array(
+				    			'#theme' => 'openmindattribute_formatter_field_full_title',
+				    			'#attributes' => $atts_mapped,
+				    			'#type' => $term->name,
+				    	);
+				    		
+				    	$elements[] =  $output;
+				    
+				    	//}
+				    
+				    
+				    	//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    	//}
+				    	break;
+				    	
+				    	
+				    	case ("openmindattribute_field_full_title_translit_romanization"):
+				    	
+				    		//foreach ($items as $delta => $item) {
+				    		$ocid = $entity->field_oc['und'][0]['tid'];
+				    	
+				    		$term = taxonomy_term_load($ocid);
+				    	
+				    	
+				    		$atts =  $entity->field_attribute['und'];
+				    	
+				    		$atts_mapped = _openmindattribute_field_remap($atts);
+				    	
+				    	
+				    		$output = array(
+				    				'#theme' => 'openmindattribute_formatter_field_full_title_translit_romanization',
+				    				'#attributes' => $atts_mapped,
+				    				'#type' => $term->name,
+				    		);
+				    	
+				    		$elements[] =  $output;
+				    	
+				    		//}
+				    	
+				    	
+				    		//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    		//}
+				    		break;
+				    		 
+				    		
+				    		case ("openmindattribute_field_name_translit_romanization"):
+				    			 
+				    			//foreach ($items as $delta => $item) {
+				    			$ocid = $entity->field_oc['und'][0]['tid'];
+				    			 
+				    			$term = taxonomy_term_load($ocid);
+				    			 
+				    			 
+				    			$atts =  $entity->field_attribute['und'];
+				    			 
+				    			$atts_mapped = _openmindattribute_field_remap($atts);
+				    			 
+				    			 
+				    			$output = array(
+				    					'#theme' => 'openmindattribute_formatter_field_name_translit_romanization',
+				    					'#attributes' => $atts_mapped,
+				    					'#type' => $term->name,
+				    			);
+				    			 
+				    			$elements[] =  $output;
+				    			 
+				    			//}
+				    			 
+				    			 
+				    			//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    			//}
+				    			break;
+				    	case ("openmindattribute_field_name"):
+				    	
+				    		//foreach ($items as $delta => $item) {
+				    		$ocid = $entity->field_oc['und'][0]['tid'];
+				    	
+				    		$term = taxonomy_term_load($ocid);
+				    	
+				    	
+				    		$atts =  $entity->field_attribute['und'];
+				    	
+				    		$atts_mapped = _openmindattribute_field_remap($atts);
+				    		
+				    		
+				    		$nid = $entity->nid;
+
+				    		$output = array(
+				    				'#theme' => 'openmindattribute_formatter_field_name',
+				    				'#attributes' => $atts_mapped,
+				    				'#type' => $term->name,
+				    				'#nid' => $nid
+				    		);
+				    	
+				    		$elements[] =  $output;
+				    	
+				    		//}
+				    	
+				    	
+				    		//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    		//}
+				    		break;
+				    		 
+				    	
+				    case ("openmindattribute_field_ahlwardt"):
+				    		
+				    	//foreach ($items as $delta => $item) {
+				    	$ocid = $entity->field_oc['und'][0]['tid'];
+				    
+				    	$term = taxonomy_term_load($ocid);
+				    
+				    
+				    	$atts =  $entity->field_attribute['und'];
+				    
+				    	$atts_mapped = _openmindattribute_field_remap($atts);
+				    		
+				    
+				    	$output = array(
+				    			'#theme' => 'openmindattribute_formatter_field_ahlwardt',
+				    			'#attributes' => $atts_mapped,
+				    			'#type' => $term->name,
+				    	);
+				    		
+				    	$elements[] =  $output;
+				    
+				    	//}
+				    
+				    
+				    	//$elements[$delta] = array ('#markup' => render($element_tmp));
+				    	//}
+				    	break;
+					
+					case ("openmindattribute_field_MPIWG_viewer"):
+						
+						
+						$ocid = $entity->field_oc['und'][0]['tid'];
+					
+						$term = taxonomy_term_load($ocid);
+					
+					
+						$atts =  $entity->field_attribute['und'];
+					
+						$atts_mapped = _openmindattribute_field_remap($atts);
+							
+					
+						if (isset($atts_mapped['mpiwg_id']['ov'])){
+						
+						$elements = array(
+								'#theme' => 'digitalobjects_item_thumbnail',
+								'#objid' => strtoupper($atts_mapped['mpiwg_id']['ov']),
+							
+					
+					
+						);
+						
+						
+						}
+					
+					break;
+					
+					case ("openmindattribute_field_MPIWG_viewer_for_view"):
+					
+					
+							
+						
+						
+						
+						$ocid = $entity->field_oc['und'][0]['tid'];
+							
+						$term = taxonomy_term_load($ocid);
+							
+							
+						$atts =  $entity->field_attribute['und'];
+							
+						$atts_mapped = _openmindattribute_field_remap($atts);
+							
+						$entid =  $entity->field_id['und'][0]['value'];
+							
+						if (isset($atts_mapped['mpiwg_id']['ov'])){
+					
+							$elements[] = array(
+									'#theme' => 'openmindattribute_item_thumbnail',
+									'#objid' => strtoupper($atts_mapped['mpiwg_id']['ov']),
+									'#entid' => $entid,
+									'#type' =>  $term->name,
+										
+										
+										
+							);
+					
+					
+						}
+							
+						break;
+							
+
+		}
+
+	
+		return $elements;
+	} else {
+
+
+		$elements = array();
+
+
+		foreach ($items as $delta => $item) {
+			$elements[$delta] = array(
+					'#theme' => 'openmindattribute_formatter_default',
+					'#element' => $item,
+					'#field' => $instance,
+					'#display' => $display,
+					'#entity' => $entity
+			);
+		}
+		return $elements;
+	}
+}
+
+/**
+ * Formats a link.
+ */
+function theme_openmindattribute_formatter_default($vars) {
+
+
+	$entity = $vars['type'];
+
+
+	$ocid = $entity->field_oc['und'][0]['tid'];
+
+
+	$term = taxonomy_term_load($ocid);
+
+
+
+	return $vars['element']['name'] . $vars['element']['ov'] . $vars['element']['nov'] . $vars['element']['romanization'];
+
+}
+
+function theme_openmindattribute_formatter_fields_specialized($vars) {
+
+	$type = $vars['type'];
+
+	
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_" . $type . ".tpl.php", $vars);
+
+	
+
+
+	
+
+}
+
+
+
+function theme_openmindattribute_formatter_field_identifier($vars) {
+	
+	$type = $vars['type'];
+	
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_identifier.tpl.php", $vars);
+
+
+
+	
+}
+
+
+function theme_openmindattribute_formatter_field_full_title($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_full_title.tpl.php", $vars);
+
+
+
+
+}
+
+
+
+function theme_openmindattribute_formatter_field_full_title_translit_romanization($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_full_title_translit_romanization.tpl.php", $vars);
+
+
+
+
+}
+
+function theme_openmindattribute_formatter_field_name_translit_romanization($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_name_translit_romanization.tpl.php", $vars);
+
+
+
+
+}
+
+
+
+function theme_openmindattribute_formatter_field_name($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_name.tpl.php", $vars);
+
+
+
+
+}
+
+
+
+function theme_openmindattribute_formatter_field_ahlwardt($vars) {
+
+	$type = $vars['type'];
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_ahlwardt.tpl.php", $vars);
+
+
+
+
+}
+
+function theme_openmindattribute_formatter_field_MPIWG_viewer($vars) {
+	
+	$type = $vars['type'];
+	
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_MPIWG_viewer.tpl.php", $vars);
+
+	
+}
+
+
+function theme_openmindattribute_formatter_fields_default($vars) {
+
+
+
+	return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_default.tpl.php", $vars);
+	
+	
+
+
+	
+}
+
+function theme_openmindattribute_formatter_fields_diva_link($vars) {
+		
+	
+		return theme_render_template(drupal_get_path('module', 'openmindattribute') . "/templates/openmindattribute_diva_link.tpl.php", $vars);
+	
+}
+
+
+/**
+ * Implements hook_views_api().
+ */
+function openmindattribute_views_api() {
+	return array(
+			'api' => 2,
+			'path' => drupal_get_path('module', 'openmindattribute') . '/views',
+	);
+}
+
+/**
+ * Implements hook_field_settings_form().
+ */
+function openmindattribute_field_settings_form() {
+	return array();
+}
+
+/**
+ * Additional callback to adapt the property info of link fields.
+ *
+ * @see entity_metadata_field_entity_property_info().
+ */
+function openmindattribute_field_property_info_callback(&$info, $entity_type, $field, $instance, $field_type) {
+	$property = &$info[$entity_type]['bundles'][$instance['bundle']]['properties'][$field['field_name']];
+	// Define a data structure so it's possible to deal with both the link title
+	// and URL.
+	$property['getter callback'] = 'entity_metadata_field_verbatim_get';
+	$property['setter callback'] = 'entity_metadata_field_verbatim_set';
+
+	// Auto-create the field item as soon as a property is set.
+	$property['auto creation'] = 'openmindattribute_field_item_create';
+
+	$property['property info'] = openmindattribute_field_item_property_info();
+	$property['property info']['name']['required'] = !$instance['settings']['name'];
+	$property['property info']['ov']['required'] = ($instance['settings']['ov'] == 'required');
+	if ($instance['settings']['ov'] == 'none') {
+		unset($property['property info']['ov']);
+	}
+
+	$property['property info']['nov']['required'] = ($instance['settings']['nov'] == 'required');
+	if ($instance['settings']['nov'] == 'none') {
+		unset($property['property info']['nov']);
+	}
+	unset($property['query callback']);
+}
+
+/**
+ * Callback for creating a new, empty link field item.
+ *
+ * @see link_field_property_info_callback()
+ */
+function openmindattribute_field_item_create() {
+	return array('title' => NULL, 'url' => NULL);
+}
+
+/**
+ * Defines info for the properties of the link-field item data structure.
+ */
+function openmindattribute_field_item_property_info() {
+	$properties['ov'] = array(
+			'type' => 'text',
+			'label' => t('The OV.'),
+			'setter callback' => 'entity_property_verbatim_set',
+	);
+	$properties['name'] = array(
+			'type' => 'text',
+			'label' => t('The name of the attribute'),
+			'setter callback' => 'entity_property_verbatim_set',
+	);
+
+	$properties['nov'] = array(
+			'type' => 'text',
+			'label' => t('The NOV'),
+			'setter callback' => 'entity_property_verbatim_set',
+	);
+	return $properties;
+}
+
+#/**
+# * Implements hook_field_update_instance().
+# */
+#function openmindattribute_field_update_instance($instance, $prior_instance) {
+#  if (function_exists('i18n_string_update') && $instance['widget']['type'] == 'openmindattribute_field' ) {
+#    $i18n_string_name = "field:{$instance['field_name']}:{$instance['bundle']}:title_value";
+#    i18n_string_update($i18n_string_name, $instance['settings']['title_value']);
+#  }
+#}
+
+/**
+ * Implements hook_i18n_string_list_TEXTGROUP_alter().
+ */
+#function link_i18n_string_list_field_alter(&$strings, $type = NULL, $object = NULL) {
+#  if ($type != 'field_instance' || !is_array($object) || !isset($object['widget']['type'])) {
+#    return;
+#  }
+#  if ($object['widget']['type'] == 'link_field' && isset($object['settings']['title_value'])) {
+##    $strings['field'][$object['field_name']][$object['bundle']]['title_value']['string'] = $object['settings']['title_value'];
+#}
+#}
+
+
+/**
+ * @file
+ *  implementation of Feeds mapping API for link.module.
+ */
+
+/**
+ * Implements hook_feeds_processor_targets_alter().
+ *
+ * @see FeedsProcessor::getMappingTargets()
+ */
+/*
+ function openmindattribute_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
+
+ foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
+ $info = field_info_field($name);
+
+ if ($info['type'] == 'openmindattribute_field') {
+ if (array_key_exists('name', $info['columns'])) {
+ $targets[$name . ':name'] = array(
+ 'name' => t('@name: name', array('@name' => $instance['label'])),
+ 'callback' => 'openmindattribute_feeds_set_target',
+ 'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+ 'real_target' => $name,
+ );
+ }
+ if (array_key_exists('ov', $info['columns'])) {
+ $targets[$name . ':ov'] = array(
+ 'name' => t('@name: OV', array('@name' => $instance['label'])),
+ 'callback' => 'openmindattribute_feeds_set_target',
+ 'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+ 'real_target' => $name,
+ );
+ }
+ if (array_key_exists('ov', $info['columns'])) {
+ $targets[$name . ':nov'] = array(
+ 'name' => t('@name: NOV', array('@name' => $instance['label'])),
+ 'callback' => 'openmindattribute_feeds_set_target',
+ 'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+ 'real_target' => $name,
+ );
+ }
+ }
+ }
+ }
+ */
+
+function openmindattribute_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
+
+	foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
+		$info = field_info_field($name);
+		#map the whole attr
+
+		if ($info['type'] == 'openmindattribute_field') {
+			$targets[$name] = array(
+					'name' => t('@name', array('@name' => $instance['label'])),
+					'callback' => 'openmindattribute_feeds_set_target',
+					'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+					'real_target' => $name,
+			);
+		}
+			
+
+	}
+}
+
+
+
+/**
+ * Callback for mapping. Here is where the actual mapping happens.
+ *
+ * When the callback is invoked, $target contains the name of the field the
+ * user has decided to map to and $value contains the value of the feed item
+ * element the user has picked as a source.
+ */
+/*
+ function openmindattribute_feeds_set_target($source, $entity, $target, $value) {
+if (empty($value)) {
+return;
+}
+
+// Handle non-multiple value fields.
+if (!is_array($value)) {
+$value = array($value);
+}
+
+// Iterate over all values.
+list($field_name, $column) = explode(':', $target);
+$info = field_info_field($field_name);
+
+$field = isset($entity->$field_name) ? $entity->$field_name : array();
+$delta = 0;
+
+foreach ($value as $v) {
+if ($info['cardinality'] == $delta) {
+break;
+}
+
+if (is_object($v) && ($v instanceof FeedsElement)) {
+$v = $v->getValue();
+}
+
+if (is_scalar($v)) {
+$field['und'][$delta][$column] = $v;
+$delta++;
+}
+}
+$entity->$field_name = $field;
+}
+*/
+
+function openmindattribute_feeds_set_target($source, $entity, $target, $value) {
+
+	if (empty($value)) {
+		return;
+	}
+
+	// Handle non-multiple value fields.
+	if (!is_array($value)) {
+		$value = array($value);
+	}
+
+	// Iterate over all values.
+	#list($field_name, $column) = explode(':', $target);
+
+	$field_name=$target;
+	$info = field_info_field($field_name);
+
+	$field = isset($entity->$field_name) ? $entity->$field_name : array();
+	$delta = 0;
+
+	
+	foreach ($value as $v) {
+			
+		
+		if ($info['cardinality'] == $delta) {
+			break;
+		}
+
+		if (is_object($v) && ($v instanceof FeedsElement)) {
+			$v = $v->getValue();
+		}
+
+		if (is_scalar($v)) {
+			$field['und'][$delta] = $v;
+			$delta++;
+		}
+		
+		if (is_array($v)){
+			$newVal = array();
+			$newVal['ov'] = $v['ov'];
+			$newVal['nov'] = $v['nov'];
+			$newVal['name'] = $v['name'];
+			$newVal['romanization'] = $v['romanization'];
+			$field['und'][$delta]= $newVal;
+			$delta++;
+				
+		}
+	}
+	$entity->$field_name = $field;
+}
+
+
+function openmindattribute_addIDs(){
+	#adds the author id from openmind to the biographies and umgekehrt
+	$query = new EntityFieldQuery();
+
+	$query->entityCondition('entity_type', 'node')
+	->entityCondition('bundle', 'openmind_entity')
+	->propertyCondition('status', 1)
+	->fieldCondition('field_oc', 'tid', '1', '='); #1 is PERSON #TODO should search for PERSON and not the id
+
+	$result = $query->execute();
+
+
+	if (isset($result['node'])) {
+		$persons_nids = array_keys($result['node']);
+		$persons = entity_load('node', $persons_nids);
+
+
+	}
+
+	#hole mapping bea url -> id
+
+	$beamapping=array();
+	$beamappingNodeId=array();
+	foreach ($persons as $person){
+
+		$attrs = $person->field_attribute['und'];
+
+		
+		$mappedattrs = _openmindattribute_field_remap($attrs);
+		
+		if (isset($mappedattrs['url'])){
+		
+		$url = $mappedattrs['url']['ov'];
+						
+		$exploded = explode("/", $url);
+		
+		#urls haben die Form http://islamsci.mcgill.ca/rasi/bea/tusi_bea.htm
+		#mich interessiert nur das ende ohne htm
+		
+		dpm($exploded);
+		$ident = $exploded[count($exploded)-1];
+		dpm($ident);
+		$ident = strtolower(str_replace(".htm", "", $ident));
+
+		dpm($ident);
+		$beamapping[$ident]=$person->field_id['und'][0]['value'];
+		//$beamappingNodeId[$ident]=$person->nid;
+		$beamappingNodeId[$ident][]=$person->nid;
+		}
+
+	}
+	
+	#hole jetzt alle biographien
+	
+	$query = new EntityFieldQuery();
+	
+	$query->entityCondition('entity_type', 'node')
+	->entityCondition('bundle', 'biography');
+	
+	
+	$result = $query->execute();
+	
+	
+	if (isset($result['node'])) {
+		$bios_nids = array_keys($result['node']);
+		$bios = entity_load('node', $bios_nids);
+		
+	}
+	
+	foreach ($bios as $bio){
+		$url = strtolower(drupal_get_path_alias("node/" . $bio->nid));
+		
+		dpm($url);
+		
+		if (isset ($beamapping[$url])){
+		$authorid = $beamapping[$url];
+		
+		$bio->field_id['und'][0]['value']=$authorid;
+		
+		
+		
+		
+		node_save($bio);
+		
+		dpm($url . " -->" . $authorid);
+		
+		dpm($bio);
+		
+		
+		foreach ($beamappingNodeId[$url] as $entNid){
+		//$entNid = $beamappingNodeId[$url];
+		
+		$ent = entity_load_single("node", $entNid);
+		
+		$ent->field_bio_id['und'][0]['value']=$bio->nid;
+		$ent->field_bio_id_reference['und'][0]['nid']=$bio->nid;
+		dpm($ent);
+		dpm($ent->nid);
+		node_save($ent);
+		}}
+		
+	}
+
+
+}
+
+function openmindattribute_addIDbibliographieID(){
+	#adds the add bibliographie
+	$query = new EntityFieldQuery();
+
+	$query->entityCondition('entity_type', 'node')
+	->entityCondition('bundle', 'openmind_entity')
+	->propertyCondition('status', 1)
+	->fieldCondition('field_oc', 'tid', '10', '='); #10 is reference #TODO should search for REFERENCE nd not the id
+ 
+	$result = $query->execute();
+	
+	
+	if (isset($result['node'])) {
+		$reference_nids = array_keys($result['node']);
+		$references = entity_load('node', $reference_nids);
+
+	}
+
+	foreach ($references as $reference){
+		#{King, 1983 #1290} References haben diese Titel
+		# Hole die Nummer
+		
+		$exploded = explode("#", $reference->title);
+		$number = str_replace("}", "", $exploded[1]);
+		
+		
+		#suche jetzt in biblios nach der Nummer "=feld Custom 3"
+		
+		$query = db_select('node', 'n');
+		$query->addField('n', 'nid');
+		$query->leftJoin('biblio', 'b', 'n.vid=b.vid');
+		
+		$query->addField('b', 'biblio_custom3');
+		$query->condition("b.biblio_custom3", $number);
+		
+		$results=$query->execute();
+		
+		foreach ($results as $node){
+			$nid= $node->nid;
+			$ent = entity_load_single("node", $nid);
+			dpm($reference);
+			$reference->field_biblio_reference['und'][0]['nid']=$nid;
+			node_submit($reference);
+			node_save($reference);
+		}
+		
+		
+	}
+}
+
+
+function _openmindattribute_collection_list($name,&$form){
+	$query = new EntityFieldQuery();
+	
+	$query->entityCondition('entity_type', 'node')
+	->entityCondition('bundle', 'openmind_entity')
+	->propertyCondition('status', 1)
+	->fieldCondition('field_oc', 'tid', '8', '='); #8 is COLLECTION #TODO should search for COLLECTION and not the id
+	
+	$result = $query->execute();
+	
+	$options = array();
+	
+	if (isset($result['node'])) {
+		$cols_nids = array_keys($result['node']);
+		$cols = entity_load('node', $cols_nids);
+	
+	
+	}
+	
+	
+	$options['']='All';
+	
+	$titel = array();
+	
+	foreach ($cols as $col){
+		$titel[]=$col->title;
+	}
+	
+	sort($title);
+	
+	foreach($title as $t){
+	$options[$t]=$t;
+	}
+	
+		
+	$form[$name]=array(
+			'#type' => 'radios',
+			'#options' => $options,
+			'#default_value' => ''
+	);
+}
+
+function openmindattribute_form_views_exposed_form_alter(&$form, $form_state, $form_id) {
+	
+	
+	if($form["#id"]=="views-exposed-form-codices-page-codices"){
+		_openmindattribute_collection_list("title",$form);
+	
+	
+	} elseif ($form["#id"]=="views-exposed-form-codices-page-2"){
+		
+		_openmindattribute_collection_list("title_1",$form);
+	}
+	
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute-item-thumbnail.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,21 @@
+
+
+
+
+<div class="digitalobjects_item">
+<table class="digitalobjects_item_short">
+<tr>
+<td class="digitalobjects_item_image">
+
+
+<?php if ($type=="WITNESS"):?>
+<a href="https://openmind-ismi-dev.mpiwg-berlin.mpg.de/om4-ismi/public/publicWitness.jsp?eid=<?php print $entid ?>"><img src="<?php print $objdata['thumburl']; ?>"/></a>
+<?php endif;?>
+<?php if ($type=="CODEX"):?>
+<a href="https://openmind-ismi-dev.mpiwg-berlin.mpg.de/om4-ismi/public/publicCodex.jsp?eid=<?php print $entid ?>"><img src="<?php print $objdata['thumburl']; ?>"/></a>
+<?php endif;?>
+
+</td>
+</tr>
+</table>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_ALIAS.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,1 @@
+<?php print $attributes['ALIAS']['ov'] ?>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_CODEX.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,23 @@
+<h3 class="openmindattribute-header">Details</h3>
+<table class="openmindattribute-table" >
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Binding</td>
+<td class="openmindattribute-cell"><?php print $attributes['binding']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Dimensions</td>
+<td class="openmindattribute-cell"><?php print $attributes['dimensions']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Notes</td>
+<td class="openmindattribute-cell"><?php print $attributes['notes']['ov']?></td>
+</tr>
+
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Number of Folios</td>
+<td class="openmindattribute-cell"><?php print $attributes['number_of_folios']['ov']?></td>
+</tr>
+</table>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_MPIWG_viewer.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,1 @@
+<?php print $attributes['mpiwg_id']['ov'] ?>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_PERSON.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,29 @@
+<h3 class="openmindattribute-header">Details</h3>
+<table class="openmindattribute-table" >
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">Name</td>
+<td class="openmindattribute-cell"><?php print $attributes['name_translit']['ov']?><br/><?php print $attributes['name']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">Name (romanization)</td>
+<td class="openmindattribute-cell"><?php print $attributes['name_translit']['romanization']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">Notes</td>
+<td class="openmindattribute-cell"><?php print $attributes['notes']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">Date of birth</td>
+<td class="openmindattribute-cell"><?php print $attributes['birth_date_text']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">Date of death</td>
+<td class="openmindattribute-cell"><?php print $attributes['death_date_text']['ov']?></td>
+</tr>
+
+
+</table>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_TEXT.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,34 @@
+<h3 class="openmindattribute-header">Details</h3>
+<table class="openmindattribute-table" >
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">Full title</td>
+<td class="openmindattribute-cell"><?php print $attributes['full_title']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">(translit)</td>
+<td class="openmindattribute-cell"><?php print $attributes['full_title_translit']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">(romanization)</td>
+<td class="openmindattribute-cell"><?php print $attributes['full_title_translit']['romanization']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">Notes</td>
+<td class="openmindattribute-cell"><?php print $attributes['notes']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">Notes (arabic)</td>
+<td class="openmindattribute-cell"><?php print $attributes['notes_arabic']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name">Language</td>
+<td class="openmindattribute-cell"><?php print $attributes['language']['ov']?></td>
+</tr>
+
+
+</table>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_WITNESS.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,65 @@
+<h3 class="openmindattribute-header">Details</h3>
+<table class="openmindattribute-table" >
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Ahlwardt</td>
+<td class="openmindattribute-cell"><?php print $attributes['ahlwardt_no']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Explicit</td>
+<td class="openmindattribute-cell"><?php print $attributes['explicit']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Folios</td>
+<td class="openmindattribute-cell"><?php print $attributes['folios']['ov']?></td>
+</tr>
+
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Incipit</td>
+<td class="openmindattribute-cell"><?php print $attributes['incipit']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Lines per Page</td>
+<td class="openmindattribute-cell"><?php print $attributes['lines_per_page']['ov']?></td>
+</tr>
+
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Notes</td>
+<td class="openmindattribute-cell"><?php print $attributes['notes']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Notes on Title/Author</td>
+<td class="openmindattribute-cell"><?php print $attributes['notes_on_title_author']['ov']?></td>
+</tr>
+
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Page dimensions</td>
+<td class="openmindattribute-cell"><?php print $attributes['page_dimensions']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Source of information</td>
+<td class="openmindattribute-cell"><?php print $attributes['source_of_information']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Writing surface</td>
+<td class="openmindattribute-cell"><?php print $attributes['writing_surface']['ov']?></td>
+</tr>
+
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell">Writing area dimensions</td>
+<td class="openmindattribute-cell"><?php print $attributes['written_area_dimensions	']['ov']?></td>
+</tr>
+</table>
+
+<div>
+<h3>Table of Contents</h3>
+<div><?php print $attributes['table_of_contents']['ov']?></div>
+</div>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_ahlwardt.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,3 @@
+<?php if (isset( $attributes['ahlwardt_no'])):?>
+<?php print $attributes['ahlwardt_no']['ov'] ?>
+<?php endif;?>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_default.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,10 @@
+<h3 class="openmindattribute-header">Attributes</h3>
+<table class="openmindattribute-table" >
+<?php foreach ($attributes as $a):?>
+<tr class="openmindattribute-row">
+<td class="openmindattribute-cell openmindattribute-name"><?php print $a['name']?></td>
+<td class="openmindattribute-cell"><?php print $a['ov']?></td>
+<td class="openmindattribute-cell"><?php print $a['nov']?></td>
+<td class="openmindattribute-cell"><?php endforeach;?></td>
+</tr>
+</table>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_diva_link.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,7 @@
+<?php if ($type=="WITNESS"):?>
+<a href="https://openmind-ismi-dev.mpiwg-berlin.mpg.de/om4-ismi/public/publicWitness.jsp?eid=<?php print $entid ?>">View</a>
+<?php endif;?>
+<?php if ($type=="CODEX"):?>
+<a href="https://openmind-ismi-dev.mpiwg-berlin.mpg.de/om4-ismi/public/publicCodex.jsp?eid=<?php print $entid ?>">View</a>
+<?php endif;?>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_full_title.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,3 @@
+<?php if (isset( $attributes['full_title'])):?>
+<?php print $attributes['full_title']['ov'] ?>
+<?php endif;?>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_full_title_translit_romanization.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,4 @@
+<?php if (isset( $attributes['full_title_translit'])):?>
+<?php print $attributes['full_title_translit']['romanization'] ?>
+<?php endif;?>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_identifier.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,1 @@
+<?php print $attributes['identifier']['ov'] ?>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_name.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,1 @@
+<a href="./node/<?php print $nid ?>"><?php print $attributes['name']['ov'] ?></a>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_name_translit_romanization.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,4 @@
+<?php if (isset( $attributes['name_translit'])):?>
+<?php print $attributes['name_translit']['romanization'] ?>
+<?php endif;?>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/templates/openmindattribute_reference_format.tpl.php	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,1 @@
+<span class="openmind-reference"><a href="../node/<?php print $nid ?>"><?php print $type?>: <?php print $ov?></a></span>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/tests/link.attribute.test	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,494 @@
+<?php
+
+/**
+ * @file
+ * Basic simpletests to test options on link module.
+ */
+
+class LinkAttributeCrudTest extends DrupalWebTestCase {
+  private $zebra;
+
+  protected $permissions = array(
+    'access content',
+    'administer content types',
+    'administer nodes',
+    'administer filters',
+    'access comments',
+    'post comments',
+    'skip comment approval',
+    'access administration pages',
+  );
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Link Attribute Tests',
+      'description' => 'Tests the field attributes, making sure they appear in various displayed situations.',
+      'group' => 'Link',
+    );
+  }
+
+  function setup() {
+    parent::setup('field_ui', 'link');
+    $this->zebra = 0;
+    // Create and login user.
+    $this->web_user = $this->drupalCreateUser(array('administer content types'));
+    $this->drupalLogin($this->web_user);
+  }
+
+  protected function createLink($url, $title, $attributes = array()) {
+    return array(
+      'url' => $url,
+      'title' => $title,
+      'attributes' => $attributes,
+    );
+  }
+
+  protected function assertLinkOnNode($field_name, $link_value, $message = '', $group = 'Other') {
+    $this->zebra++;
+    $zebra_string = ($this->zebra % 2 == 0) ? 'even' : 'odd';
+    $cssFieldLocator = 'field-'. str_replace('_', '-', $field_name);
+    $this->assertPattern('@<div class="field field-type-link '. $cssFieldLocator .'".*<div class="field-item '. $zebra_string .'">\s*'. $link_value .'\s*</div>@is',
+                         $message,
+                         $group);
+  }
+
+  /**
+   * A simple test that just creates a new node type, adds a link field to it, creates a new node of that type, and makes sure
+   * that the node is being displayed.
+   */
+  function testBasic() {
+    $content_type_friendly = $this->randomName(20);
+    $content_type_machine = strtolower($this->randomName(10));
+    $title = $this->randomName(20);
+
+    $this->drupalGet('admin/structure/types');
+
+    // Create the content type.
+    $this->clickLink(t('Add content type'));
+
+    $edit = array (
+      'name' => $content_type_friendly,
+      'type' => $content_type_machine,
+    );
+    $this->drupalPost(NULL, $edit, t('Save and add fields'));
+    $this->assertText(t('The content type @name has been added.', array('@name' => $content_type_friendly)));
+
+    // Now add a singleton field.
+    $single_field_name_friendly = $this->randomName(20);
+    $single_field_name_machine = strtolower($this->randomName(10));
+    $single_field_name = 'field_'. $single_field_name_machine;
+    $edit = array (
+      'fields[_add_new_field][label]' => $single_field_name_friendly,
+      'fields[_add_new_field][field_name]' => $single_field_name_machine,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // We'll go with the default settings for this run-through.
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+
+    // Using all the default settings, so press the button.
+    $this->drupalPost(NULL, array(), t('Save settings'));
+    $this->assertText(t('Saved @name configuration.', array('@name' => $single_field_name_friendly)));
+
+    // Somehow clicking "save" isn't enough, and we have to do a
+    // node_types_rebuild().
+    node_types_rebuild();
+    menu_rebuild();
+    $type_exists = db_query('SELECT 1 FROM {node_type} WHERE type = :type', array(':type' => $content_type_machine))->fetchField();
+    $this->assertTrue($type_exists, 'The new content type has been created in the database.');
+
+    $permission = 'create ' . $content_type_machine . ' content';
+    $permission_edit = 'edit ' . $content_type_machine . ' content';
+    // Reset the permissions cache.
+    $this->checkPermissions(array($permission), TRUE);
+
+    // Now that we have a new content type, create a user that has privileges
+    // on the content type.
+    $permissions = array_merge($this->permissions, array($permission));
+    $this->web_user = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($this->web_user);
+
+    // Go to page.
+    $this->drupalGet('node/add/'. $content_type_machine);
+
+    // Add a node.
+    $edit = array(
+      'title' => $title,
+      'field_'. $single_field_name_machine. '[und][0][title]' => 'Link',
+      'field_'. $single_field_name_machine. '[und][0][url]' => 'http://www.drupal.org/',
+    );
+
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertText(t('@content_type_friendly @title has been created', array('@content_type_friendly' => $content_type_friendly, '@title' => $title)));
+
+    $this->drupalGet('node/add/'. $content_type_machine);
+
+    // Create a node:
+    $edit = array(
+      'title' => $title,
+      'field_' . $single_field_name_machine . '[und][0][url]' => 'http://www.example.com/',
+      'field_' . $single_field_name_machine . '[und][0][title]' => 'Display',
+    );
+
+    // Now we can fill in the second item in the multivalue field and save.
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertText(t('@content_type_friendly @title has been created', array('@content_type_friendly' => $content_type_friendly, '@title' => $title)));
+
+    $this->assertText('Display');
+    $this->assertLinkByHref('http://www.example.com');
+  }
+
+  protected function createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine) {
+    $this->drupalGet('admin/structure/types/manage/' . $content_type_machine . '/fields');
+    $edit = array (
+      'fields[_add_new_field][label]' => $single_field_name_friendly,
+      'fields[_add_new_field][field_name]' => $single_field_name_machine,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // We'll go with the default settings for this run-through.
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+
+    // Using all the default settings, so press the button.
+    $this->drupalPost(NULL, array(), t('Save settings'));
+    $this->assertText(t('Saved @name configuration.', array('@name' => $single_field_name_friendly)));
+
+    // Somehow clicking "save" isn't enough, and we have to do a
+    // node_types_rebuild().
+    node_types_rebuild();
+    menu_rebuild();
+    $type_exists = db_query('SELECT 1 FROM {node_type} WHERE type = :type', array(':type' => $content_type_machine))->fetchField();
+    $this->assertTrue($type_exists, 'The new content type has been created in the database.');
+  }
+
+  protected function createNodeTypeUser($content_type_machine) {
+    $permission = 'create ' . $content_type_machine . ' content';
+    $permission_edit = 'edit ' . $content_type_machine . ' content';
+    // Reset the permissions cache.
+    $this->checkPermissions(array($permission), TRUE);
+
+    // Now that we have a new content type, create a user that has privileges
+    // on the content type.
+    $permissions = array_merge($this->permissions, array($permission));
+    $this->web_user = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($this->web_user);
+  }
+
+  protected function createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $title, $url, $node_title = '') {
+    $this->drupalGet('node/add/'. $content_type_machine);
+
+    if (!$node_title) {
+      $node_title = $this->randomName(20);
+    }
+    $edit = array(
+      'title' => $node_title,
+    );
+    if ($url) {
+      $edit['field_' . $single_field_name_machine . '[und][0][url]'] = $url;
+    }
+    if ($title) {
+      $edit['field_' . $single_field_name_machine . '[und][0][title]'] = $title;
+    }
+
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertText(t('@content_type_friendly @title has been created', array('@content_type_friendly' => $content_type_friendly, '@title' => $node_title)));
+
+  }
+
+  /**
+   * Test the link_plain formatter and it's output.
+   */
+  function testFormatterPlain() {
+    $content_type_friendly = $this->randomName(20);
+    $content_type_machine = strtolower($this->randomName(10));
+
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
+
+    // Now add a singleton field.
+    $single_field_name_friendly = $this->randomName(20);
+    $single_field_name_machine = strtolower($this->randomName(10));
+    //$single_field_name = 'field_'. $single_field_name_machine;
+    $this->createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine);
+
+    // Okay, now we want to make sure this display is changed:
+    $this->drupalGet('admin/structure/types/manage/'. $content_type_machine .'/display');
+    $edit = array(
+      'fields[field_'. $single_field_name_machine .'][label]' => 'above',
+      'fields[field_'. $single_field_name_machine .'][type]' => 'link_plain',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    $this->createNodeTypeUser($content_type_machine);
+    
+    $link_tests = array(
+      'plain' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/',
+      ),
+      'query' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/?q=test',
+      ),
+      'fragment' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/#test',
+      ),
+    );
+
+    foreach ($link_tests as $key => $link_test) {
+      $link_text = $link_test['text'];
+      $link_url = $link_test['url'];
+      $this->createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $link_text, $link_url);
+  
+      $this->assertText($link_url);
+      $this->assertNoText($link_text);
+      $this->assertNoLinkByHref($link_url);
+    }
+  }
+
+  function testFormatterURL() {
+    $content_type_friendly = $this->randomName(20);
+    $content_type_machine = strtolower($this->randomName(10));
+
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
+
+    // Now add a singleton field.
+    $single_field_name_friendly = $this->randomName(20);
+    $single_field_name_machine = strtolower($this->randomName(10));
+    //$single_field_name = 'field_'. $single_field_name_machine;
+    $this->createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine);
+
+    // Okay, now we want to make sure this display is changed:
+    $this->drupalGet('admin/structure/types/manage/'. $content_type_machine .'/display');
+    $edit = array(
+      'fields[field_'. $single_field_name_machine .'][label]' => 'above',
+      'fields[field_'. $single_field_name_machine .'][type]' => 'link_url',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    $this->createNodeTypeUser($content_type_machine);
+    
+    $link_tests = array(
+      'plain' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/',
+      ),
+      'query' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/?q=test',
+      ),
+      'fragment' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/#test',
+      ),
+    );
+
+    foreach ($link_tests as $key => $link_test) {
+      $link_text = $link_test['text'];
+      $link_url = $link_test['url'];
+      $this->createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $link_text, $link_url);
+  
+      $this->assertNoText($link_text);
+      $this->assertLinkByHref($link_url);
+    }
+  }
+
+  function testFormatterShort() {
+    $content_type_friendly = $this->randomName(20);
+    $content_type_machine = strtolower($this->randomName(10));
+
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
+
+    // Now add a singleton field.
+    $single_field_name_friendly = $this->randomName(20);
+    $single_field_name_machine = strtolower($this->randomName(10));
+    //$single_field_name = 'field_'. $single_field_name_machine;
+    $this->createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine);
+
+    // Okay, now we want to make sure this display is changed:
+    $this->drupalGet('admin/structure/types/manage/'. $content_type_machine .'/display');
+    $edit = array(
+      'fields[field_'. $single_field_name_machine .'][label]' => 'above',
+      'fields[field_'. $single_field_name_machine .'][type]' => 'link_short',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    $this->createNodeTypeUser($content_type_machine);
+
+    $link_tests = array(
+      'plain' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/',
+      ),
+      'query' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/?q=test',
+      ),
+      'fragment' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/#test',
+      ),
+    );
+
+    foreach ($link_tests as $key => $link_test) {
+      $link_text = $link_test['text'];
+      $link_url = $link_test['url'];
+      $this->createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $link_text, $link_url);
+  
+      $this->assertText('Link');
+      $this->assertNoText($link_text);
+      $this->assertLinkByHref($link_url);
+    }
+  }
+
+  function testFormatterLabel() {
+    $content_type_friendly = $this->randomName(20);
+    $content_type_machine = strtolower($this->randomName(10));
+
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
+
+    // Now add a singleton field.
+    $single_field_name_friendly = $this->randomName(20);
+    $single_field_name_machine = strtolower($this->randomName(10));
+    //$single_field_name = 'field_'. $single_field_name_machine;
+    $this->createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine);
+
+    // Okay, now we want to make sure this display is changed:
+    $this->drupalGet('admin/structure/types/manage/'. $content_type_machine .'/display');
+    $edit = array(
+      'fields[field_'. $single_field_name_machine .'][label]' => 'above',
+      'fields[field_'. $single_field_name_machine .'][type]' => 'link_label',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    $this->createNodeTypeUser($content_type_machine);
+
+    $link_tests = array(
+      'plain' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/',
+      ),
+      'query' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/?q=test',
+      ),
+      'fragment' => array(
+        'text' => 'Display',
+        'url' => 'http://www.example.com/#test',
+      ),
+    );
+
+    foreach ($link_tests as $key => $link_test) {
+      $link_text = $link_test['text'];
+      $link_url = $link_test['url'];  
+      $this->createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $link_text, $link_url);
+  
+      $this->assertNoText($link_text);
+      $this->assertText($single_field_name_friendly);
+      $this->assertLinkByHref($link_url);
+    }
+  }
+
+  function testFormatterSeparate() {
+    $content_type_friendly = $this->randomName(20);
+    $content_type_machine = strtolower($this->randomName(10));
+
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
+
+    // Now add a singleton field.
+    $single_field_name_friendly = $this->randomName(20);
+    $single_field_name_machine = strtolower($this->randomName(10));
+    //$single_field_name = 'field_'. $single_field_name_machine;
+    $this->createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine);
+
+    // Okay, now we want to make sure this display is changed:
+    $this->drupalGet('admin/structure/types/manage/'. $content_type_machine .'/display');
+    $edit = array(
+      'fields[field_'. $single_field_name_machine .'][label]' => 'above',
+      'fields[field_'. $single_field_name_machine .'][type]' => 'link_separate',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    $this->createNodeTypeUser($content_type_machine);
+
+    $plain_url = 'http://www.example.com/';
+    $link_tests = array(
+      'plain' => array(
+        'text' => $this->randomName(20),
+        'url' => $plain_url,
+      ),
+      'query' => array(
+        'text' => $this->randomName(20),
+        'url' => $plain_url . '?q=test',
+      ),
+      'fragment' => array(
+        'text' => $this->randomName(20),
+        'url' => $plain_url . '#test',
+      ),
+    );
+
+    foreach ($link_tests as $key => $link_test) {
+      $link_text = $link_test['text'];
+      $link_url = $link_test['url'];
+      $this->createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $link_text, $link_url);
+  
+      $this->assertText($link_text);
+      $this->assertLink($plain_url);
+      $this->assertLinkByHref($link_url);
+    }
+  }
+  
+  function testFormatterPlainTitle() {
+    $content_type_friendly = $this->randomName(20);
+    $content_type_machine = strtolower($this->randomName(10));
+    
+    $this->drupalCreateContentType(array(
+      'type' => $content_type_machine,
+      'name' => $content_type_friendly,
+    ));
+    
+    // Now add a singleton field.
+    $single_field_name_friendly = $this->randomName(20);
+    $single_field_name_machine = strtolower($this->randomName(10));
+    //$single_field_name = 'field_'. $single_field_name_machine;
+    $this->createSimpleLinkField($single_field_name_machine, $single_field_name_friendly, $content_type_machine);
+    
+    // Okay, now we want to make sure this display is changed:
+    $this->drupalGet('admin/structure/types/manage/'. $content_type_machine .'/display');
+    $edit = array(
+      'fields[field_'. $single_field_name_machine .'][label]' => 'above',
+      'fields[field_'. $single_field_name_machine .'][type]' => 'link_title_plain',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+    
+    $this->createNodeTypeUser($content_type_machine);
+    
+    $link_text = 'Display';
+    $link_url = 'http://www.example.com/';
+    $this->createNodeForTesting($content_type_machine, $content_type_friendly, $single_field_name_machine, $link_text, $link_url);
+    
+    $this->assertText($link_text);
+    $this->assertNoText($link_url);
+    $this->assertNoLinkByHref($link_url);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/tests/link.crud.test	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,82 @@
+<?php
+
+/**
+ * @file
+ * Basic CRUD simpletests for the link module, based off of content.crud.test in CCK.
+ */
+
+class LinkContentCrudTest extends DrupalWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Link CRUD - Basic API tests',
+      'description' => 'Tests the field CRUD (create, read, update, delete) API.',
+      'group' => 'Link',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('field_ui', 'link');
+  }
+
+  /**
+   * All we're doing here is creating a content type, creating a simple link field
+   * on that content type.
+   */
+  function testLinkCreateFieldAPI() {
+    $content_type_friendly = $this->randomName(20);
+    $content_type_machine = strtolower($this->randomName(10));
+    $title = $this->randomName(20);
+
+    // Create and login user.
+    $this->web_user = $this->drupalCreateUser(array('administer content types'));
+    $this->drupalLogin($this->web_user);
+
+    $this->drupalGet('admin/structure/types');
+
+    // Create the content type.
+    $this->clickLink(t('Add content type'));
+
+    $edit = array (
+      'name' => $content_type_friendly,
+      'type' => $content_type_machine,
+    );
+    $this->drupalPost(NULL, $edit, t('Save and add fields'));
+    $this->assertText(t('The content type @name has been added.', array('@name' => $content_type_friendly)));
+
+    //$field = $this->createField(array('type' => 'link', 'widget_type' => 'link'), 0);
+    // Now add a singleton field.
+    $single_field_name_friendly = $this->randomName(20);
+    $single_field_name_machine = strtolower($this->randomName(10));
+    $edit = array (
+      'fields[_add_new_field][label]' => $single_field_name_friendly,
+      'fields[_add_new_field][field_name]' => $single_field_name_machine,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // We'll go with the default settings for this run-through.
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+
+    // Using all the default settings, so press the button.
+    $this->drupalPost(NULL, array(), t('Save settings'));
+    $this->assertText(t('Saved @name configuration.', array('@name' => $single_field_name_friendly)));
+
+    // Somehow clicking "save" isn't enough, and we have to do a
+    // node_types_rebuild().
+    node_types_rebuild();
+    menu_rebuild();
+    $type_exists = db_query('SELECT 1 FROM {node_type} WHERE type = :type', array(':type' => $content_type_machine))->fetchField();
+    $this->assertTrue($type_exists, 'The new content type has been created in the database.');
+
+    /*$table_schema = drupal_get_schema();
+    $this->assertEqual(1, 1, print_r(array_keys($table_schema), TRUE));
+    // Check the schema - the values should be in the per-type table.
+    $this->assertSchemaMatchesTables(array(
+      'per_type' => array(
+        $this->content_types[0]->type => array($field['field_name'] => array('url', 'title', 'attributes')),
+      ),
+    ));*/
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/tests/link.crud_browser.test	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,272 @@
+<?php
+
+/**
+ * @file
+ * Testing CRUD API in the browser.
+ */
+
+/**
+ * Testing that users can not input bad URLs or labels
+ */
+class LinkUITest extends DrupalWebTestcase {
+
+  /**
+   * Link supposed to be good
+   */
+  const LINK_INPUT_TYPE_GOOD = 0;
+
+  /**
+   * Link supposed to have a bad title
+   */
+  const LINK_INPUT_TYPE_BAD_TITLE = 1;
+
+  /**
+   * Link supposed to have a bad URL
+   */
+  const LINK_INPUT_TYPE_BAD_URL = 2;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Link CRUD - browser test',
+      'description' => 'Tests the field CRUD (create, read, update, delete) API 2.',
+      'group' => 'Link',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('field_ui', 'link');
+  }
+
+  /**
+   * Creates a link field for the "page" type and creates a page with a link.
+   */
+  function testLinkCreate() {
+    //libxml_use_internal_errors(true);
+    $this->web_user = $this->drupalCreateUser(array(
+      'administer content types',
+      'administer nodes',
+      'administer filters',
+      'access content',
+      'create page content',
+      'access administration pages'
+    ));
+    $this->drupalLogin($this->web_user);
+
+    // create field
+    $name = strtolower($this->randomName());
+    $edit = array(
+      'fields[_add_new_field][label]' => $name,
+      'fields[_add_new_field][field_name]' => $name,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $this->drupalPost('admin/structure/types/manage/page/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+    $this->drupalPost(NULL, array(), t('Save settings'));
+
+    // Is field created?
+    $this->assertRaw(t('Saved %label configuration', array('%label' => $name)), 'Field added');
+    node_types_rebuild();
+    menu_rebuild();
+
+    $permission = 'create page content';
+    $this->checkPermissions(array($permission), TRUE);
+
+    // create page form
+    //$this->drupalGet('node/add');
+    $this->drupalGet('node/add/page');
+    $field_name = 'field_' . $name;
+    $this->assertField('edit-field-'. $name .'-und-0-title', 'Title found');
+    $this->assertField('edit-field-'. $name .'-und-0-url', 'URL found');
+
+    $input_test_cases = array(
+      array(
+        'href' => 'http://example.com/' . $this->randomName(),
+        'label' => $this->randomName(),
+        'msg' => 'Link found',
+        'type' => self::LINK_INPUT_TYPE_GOOD
+      ),
+      array(
+        'href' => 'http://example.com/' . $this->randomName(),
+        'label' => $this->randomName() . '<script>alert("hi");</script>',
+        'msg' => 'js label',
+        'type' => self::LINK_INPUT_TYPE_BAD_TITLE
+      ),
+      array(
+        'href' => 'http://example.com/' . $this->randomName(),
+        'label' => $this->randomName() . '<script src="http://devil.site.com"></script>',
+        'msg' => 'js label',
+        'type' => self::LINK_INPUT_TYPE_BAD_TITLE
+      ),
+      array(
+        'href' => 'http://example.com/' . $this->randomName(),
+        'label' => $this->randomName() . '" onmouseover="alert(\'hi\')',
+        'msg' => 'js label',
+        'type' => self::LINK_INPUT_TYPE_BAD_TITLE
+      ),
+      array(
+        'href' => 'http://example.com/' . $this->randomName(),
+        'label' => $this->randomName() . '\' onmouseover="alert(\'hi\')',
+        'msg' => 'js label',
+        'type' => self::LINK_INPUT_TYPE_BAD_TITLE
+      ),
+      array(
+        'href' => 'javascript:alert("http://example.com/' . $this->randomName() . '")',
+        'label' => $this->randomName(),
+        'msg' => 'js url',
+        'type' => self::LINK_INPUT_TYPE_BAD_URL
+      ),
+      array(
+        'href' => 'http://ecs-es.kelkoo.es/ctl/go/sitesearchGo?.ts=1338833010331&.sig=qP9GXeEFH6syBzwmzYkxmsvp1EI-',
+        'label' => 'http://ecs-es.kelkoo.es/ctl/go/sitesearchGo?.ts=1338833010331&.sig=qP9GXeEFH6syBzwmzYkxmsvp1EI-',
+        'msg' => 'Url with . in querystring',
+        'type' => self::LINK_INPUT_TYPE_GOOD,
+      ),
+    );
+    $test_case = array(
+      'href' => 'www.example.com/'. $this->randomName(),
+      'label' => $this->randomName(),
+      'msg' => 'Link found',
+      'type' => self::LINK_INPUT_TYPE_GOOD,
+    );
+    $test_case['expected_href'] = 'http://'. $test_case['href'];
+    $input_test_cases[] = $test_case;
+
+    foreach ($input_test_cases as $input) {
+      $this->drupalLogin($this->web_user);
+      $this->drupalGet('node/add/page');
+
+      $edit = array(
+        'title' => $input['label'],
+        $field_name . '[und][0][title]' => $input['label'],
+        $field_name . '[und][0][url]' => $input['href'],
+      );
+      $this->drupalPost(NULL, $edit, t('Save'));
+      if ($input['type'] == self::LINK_INPUT_TYPE_BAD_URL) {
+        $this->assertRaw(t('The value provided for %field is not a valid URL.', array('%field' => $name)), 'Not a valid URL: ' . $input['href']);
+        continue;
+      }
+      else {
+        $this->assertRaw(t(' has been created.',
+                           array('@type' => 'Basic Page', '%title' => $edit['title'])),
+                         'Page created: ' . $input['href']);
+      }
+      $url = $this->getUrl();
+
+      // change to anonym user
+      $this->drupalLogout();
+
+      $this->drupalGet($url);
+      //debug($this);
+      // If simpletest starts using something to override the error system, this will flag
+      // us and let us know it's broken.
+      $this->assertFalse(libxml_use_internal_errors(TRUE));
+      if (isset($input['expected_href'])) {
+        $path = '//a[@href="'. $input['expected_href'] .'" and text()="'. $input['label'] .'"]';
+      }
+      else {
+        $path = '//a[@href="'. $input['href'] .'" and text()="'. $input['label'] .'"]';
+      }
+      //$this->pass(htmlentities($path));
+      $elements = $this->xpath($path);
+      libxml_use_internal_errors(FALSE);
+      $this->assertIdentical(isset($elements[0]), $input['type'] == self::LINK_INPUT_TYPE_GOOD, $input['msg']);
+    }
+    //libxml_use_internal_errors(FALSE);
+  }
+
+  /**
+   * Testing that if you use <strong> in a static title for your link, that the
+   * title actually displays <strong>.
+   */
+  function testStaticLinkCreate() {
+    $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+    $this->drupalLogin($this->web_user);
+
+    // create field
+    $name = strtolower($this->randomName());
+    $field_name = 'field_'. $name;
+    $edit = array(
+      'fields[_add_new_field][label]' => $name,
+      'fields[_add_new_field][field_name]' => $name,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $this->drupalPost('admin/structure/types/manage/page/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+    $this->drupalPost(NULL, array(
+      'instance[settings][title]' => 'value',
+      'instance[settings][title_value]' => '<strong>'. $name .'</strong>'), t('Save settings'));
+
+    // Is field created?
+    $this->assertRaw(t('Saved %label configuration', array('%label' => $name)), 'Field added');
+
+    // create page form
+    $this->drupalGet('node/add/page');
+    $this->assertField($field_name . '[und][0][url]', 'URL found');
+
+    $input = array(
+      'href' => 'http://example.com/' . $this->randomName()
+    );
+
+    $edit = array(
+      'title' => $name,
+      $field_name . '[und][0][url]' => $input['href'],
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    $url = $this->getUrl();
+
+    // change to anonymous user
+    $this->drupalLogout();
+    $this->drupalGet($url);
+
+    $this->assertRaw(l('<strong>'. $name .'</strong>', $input['href'], array('html' => TRUE)));
+  }
+
+  /**
+   * If we're creating a new field and just hit 'save' on the default options, we want to make
+   * sure they are set to the expected results.
+   */
+  function testCRUDCreateFieldDefaults() {
+    $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+    $this->drupalLogin($this->web_user);
+
+    // create field
+    $name = strtolower($this->randomName());
+    $edit = array(
+      'fields[_add_new_field][label]' => $name,
+      'fields[_add_new_field][field_name]' => $name,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $this->drupalPost('admin/structure/types/manage/page/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+    $this->drupalPost(NULL, array(), t('Save settings'));
+
+    // Is field created?
+    $this->assertRaw(t('Saved %label configuration', array('%label' => $name)), 'Field added');
+    node_types_rebuild();
+    menu_rebuild();
+    //_content_type_info(TRUE);
+    //$fields = content_fields();
+    //$field = $fields['field_'. $name];
+    //$field = field_info_field('field_'. $name);
+    _field_info_collate_fields(TRUE);
+    $instances = field_info_instances('node', 'page');
+    //$this->debug($instances);
+    //$this->assert('debug', '<pre>'. print_r($instances, TRUE) .'</pre>', 'Debug');
+    $instance = $instances['field_'. $name];
+    //$this->assertTrue(1 === $instance['validate_url'], 'Make sure validation is on.');
+    $this->assertFalse($instance['required'], 'Make sure field is not required.');
+    $this->assertEqual($instance['settings']['title'], 'optional', 'Title should be optional by default.');
+    $this->assertTrue($instance['settings']['enable_tokens'], 'Enable Tokens should be off by default.');
+    $this->assertEqual($instance['settings']['display']['url_cutoff'], 80, 'Url cutoff should be at 80 characters.');
+    $this->assertEqual($instance['settings']['attributes']['target'], 'default', 'Target should be "default"');
+    $this->assertFalse($instance['settings']['attributes']['rel'], 'Rel should be blank by default.');
+    $this->assertFalse($instance['settings']['attributes']['class'], 'By default, no class should be set.');
+    $this->assertFalse($instance['settings']['title_value'], 'By default, no title should be set.');
+
+    //$this->fail('<pre>'. print_r($fields['field_'. $name], TRUE) .'</pre>');
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/tests/link.test	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * @file
+ * Link base test file - contains common functions for testing links.
+ */
+
+class LinkBaseTestClass extends DrupalWebTestCase {
+  protected $permissions = array(
+    'access content',
+    'administer content types',
+    'administer nodes',
+    'administer filters',
+    'access comments',
+    'post comments',
+    'access administration pages',
+    'create page content',
+  );
+
+  function setUp() {
+    $modules = func_get_args();
+    $modules = (isset($modules[0]) && is_array($modules[0]) ? $modules[0] : $modules);
+    $modules[] = 'field_ui';
+    $modules[] = 'link';
+    parent::setUp($modules);
+    
+    $this->web_user = $this->drupalCreateUser($this->permissions);
+    $this->drupalLogin($this->web_user);
+  }
+
+  protected function createLinkField($node_type = 'page', $settings = array()) {
+    $name = strtolower($this->randomName());
+    $edit = array(
+      'fields[_add_new_field][label]' => $name,
+      'fields[_add_new_field][field_name]' => $name,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $field_name = 'field_'. $name;
+    $this->drupalPost('admin/structure/types/manage/'. $node_type .'/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+    $this->drupalPost(NULL, $settings, t('Save settings'));
+
+    // Is field created?
+    $this->assertRaw(t('Saved %label configuration', array('%label' => $name)), 'Field added');
+    node_types_rebuild();
+    menu_rebuild();
+
+    return $field_name;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/tests/link.token.test	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,377 @@
+<?php
+
+/**
+ * @file
+ * Contains simpletests making sure token integration works.
+ */
+
+/**
+ * Testing that tokens can be used in link titles
+ */
+class LinkTokenTest extends LinkBaseTestClass {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Link tokens - browser test',
+      'description' => 'Tests including tokens in link titles, making sure they appear in node views.',
+      'group' => 'Link',
+      'dependencies' => array('token'),
+    );
+  }
+
+  function setUp($modules = array()) {
+    parent::setUp(array('token'));
+  }
+
+  /**
+   * Creates a link field with a required title enabled for user-entered tokens.
+   * Creates a node with a token in the link title and checks the value.
+   */
+  function testUserTokenLinkCreate() {
+    // create field
+    $settings = array(
+      'instance[settings][enable_tokens]' => 1,
+    );
+    $field_name = $this->createLinkField('page',
+                                        $settings);
+
+    // create page form
+    $this->drupalGet('node/add/page');
+    //$field_name = 'field_' . $name;
+    $this->assertField($field_name . '[und][0][title]', 'Title found');
+    $this->assertField($field_name . '[und][0][url]', 'URL found');
+
+    $input = array(
+        'href' => 'http://example.com/' . $this->randomName(),
+        'label' => $this->randomName(),
+    );
+
+    //$this->drupalLogin($this->web_user);
+    $this->drupalGet('node/add/page');
+
+    $edit = array(
+      'title' => $input['label'],
+      $field_name . '[und][0][title]' => $input['label'] . " [node:content-type:machine-name]",
+      $field_name . '[und][0][url]' => $input['href'],
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $url = $this->getUrl();
+
+    // change to anonymous user
+    $this->drupalLogout();
+    $this->drupalGet($url);
+
+    $this->assertRaw(l($input['label'] . ' page', $input['href']));
+  }
+
+
+  /**
+   * Creates a link field with a static title and an admin-entered token.
+   * Creates a node with a link and checks the title value.
+   */
+  function testStaticTokenLinkCreate() {
+
+    // create field
+    $name = $this->randomName();
+    $settings = array(
+      'instance[settings][title]' => 'value',
+      'instance[settings][title_value]' => $name .' [node:content-type:machine-name]');
+    $field_name = $this->createLinkField('page', $settings);
+
+    // create page form
+    $this->drupalGet('node/add/page');
+    $this->assertField($field_name . '[und][0][url]', 'URL found');
+
+    $input = array(
+      'href' => 'http://example.com/' . $this->randomName()
+    );
+
+    //$this->drupalLogin($this->web_user);
+    $this->drupalGet('node/add/page');
+
+    $edit = array(
+      'title' => $name,
+      $field_name . '[und][0][url]' => $input['href'],
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    $url = $this->getUrl();
+
+    // change to anonymous user
+    $this->drupalLogout();
+    $this->drupalGet($url);
+
+    $this->assertRaw(l($name . ' page', $input['href']));
+  }
+
+  /**
+   * Creates a link field with a static title and an admin-entered token.
+   * Creates a node with a link and checks the title value.
+   *
+   * Basically, I want to make sure the [title-raw] token works, because it's a
+   * token that changes from node to node, where [type]'s always going to be the
+   * same.
+   */
+  function testStaticTokenLinkCreate2() {
+
+    // create field
+    $name = $this->randomName();
+    $settings = array(
+      'instance[settings][title]' => 'value',
+      'instance[settings][title_value]' => $name .' [node:title]');
+    $field_name = $this->createLinkField('page', $settings);
+
+    // create page form
+    $this->drupalGet('node/add/page');
+    $this->assertField($field_name . '[und][0][url]', 'URL found');
+
+    $input = array(
+      'href' => 'http://example.com/' . $this->randomName()
+    );
+
+    //$this->drupalLogin($this->web_user);
+    $this->drupalGet('node/add/page');
+
+    $edit = array(
+      'title' => $name,
+      $field_name . '[und][0][url]' => $input['href'],
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    $url = $this->getUrl();
+
+    // change to anonymous user
+    $this->drupalLogout();
+    $this->drupalGet($url);
+
+    $this->assertRaw(l($name .' '. $name, $input['href']));
+  }
+
+  // This test doesn't seem to actually work, due to lack of 'title' in url.
+  function _test_Link_With_Title_Attribute_token_url_form() {
+   /* $this->loginWithPermissions($this->permissions);
+    $this->acquireContentTypes(1);
+    $field_settings = array(
+      'type' => 'link',
+      'widget_type' => 'link',
+      'type_name' => $this->content_types[0]->name,
+      'attributes' => array(
+        'class' => '',
+        'target' => 'default',
+        'rel' => 'nofollow',
+        'title' => '',
+      ),
+    );
+
+    $field = $this->createField($field_settings, 0);
+    //$this->fail('<pre>'. print_r($field, TRUE) .'</pre>');
+    $field_name = $field['field_name'];
+    $field_db_info = content_database_info($field);
+    $url_type = str_replace('_', '-', $this->content_types[0]->type);
+
+    $edit = array('attributes[title]' => '['. $field_name .'-url]',
+                  'enable_tokens' => TRUE);
+
+    $this->drupalPost('admin/content/node-type/'. $url_type .'/fields/'. $field['field_name'],
+                      $edit, t('Save field settings'));
+    $this->assertText(t('Saved field @field_name', array('@field_name' => $field['field_name'])));*/
+    $name = $this->randomName();
+    $settings = array(
+      'instance[settings][attributes][rel]' => 'nofollow',
+    );
+
+    $field_name = $this->createLinkField('page', $settings);
+
+    // So, having saved this field_name, let's see if it works...
+    //$this->acquireNodes(1);
+
+    //$node = node_load($this->nodes[0]->nid);
+
+    //$this->drupalGet('node/'. $this->nodes[0]->nid);
+
+    $edit = array();
+    $test_link_url = 'http://www.example.com/test';
+    $edit[$field_name .'[und][0][url]'] = $test_link_url;
+    $title = 'title_'. $this->randomName(20);
+    $edit[$field_name .'[und][0][title]'] = $title;
+    $edit['title'] = $name;
+
+    $this->drupalGet('node/add/page');
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // Make sure we get a new version!
+    //$node = node_load($this->nodes[0]->nid, NULL, TRUE);
+    $this->assertText(t('Basic page @title has been updated.',
+                        array('@title' => $name)));
+
+    //$this->drupalGet('node/'. $node->nid);
+    $this->assertText($title, 'Make sure the link title/text shows');
+    $this->assertRaw(' title="'. $test_link_url .'"', "Do we show the link url as the title attribute?");
+    $this->assertNoRaw(' title="['. $field_name .'-url]"');
+    $this->assertTrue(module_exists('token'), t('Assure that Token Module is enabled.'));
+    //$this->fail($this->content);
+  }
+
+  /**
+   * If the title of the link is set to the title attribute, then the title
+   * attribute isn't supposed to show.
+   */
+  function _test_Link_With_Title_Attribute_token_title_form() {
+    $this->loginWithPermissions($this->permissions);
+    $this->acquireContentTypes(1);
+    $field_settings = array(
+      'type' => 'link',
+      'widget_type' => 'link',
+      'type_name' => $this->content_types[0]->name,
+      'attributes' => array(
+        'class' => '',
+        'target' => 'default',
+        'rel' => 'nofollow',
+        'title' => '',
+      ),
+    );
+
+    $field = $this->createField($field_settings, 0);
+    $field_name = $field['field_name'];
+    $field_db_info = content_database_info($field);
+    $url_type = str_replace('_', '-', $this->content_types[0]->type);
+
+    $edit = array('attributes[title]' => '['. $field_name .'-title]',
+                  'enable_tokens' => TRUE);
+
+    $this->drupalPost('admin/content/node-type/'. $url_type .'/fields/'. $field['field_name'],
+                      $edit, t('Save field settings'));
+    $this->assertText(t('Saved field @field_name', array('@field_name' => $field['field_name'])));
+
+    // So, having saved this field_name, let's see if it works...
+    $this->acquireNodes(1);
+
+    $node = node_load($this->nodes[0]->nid);
+
+    $this->drupalGet('node/'. $this->nodes[0]->nid);
+
+    $edit = array();
+    $edit[$field['field_name'] .'[0][url]'] = 'http://www.example.com/test';
+    $title = 'title_'. $this->randomName(20);
+    $edit[$field['field_name'] .'[0][title]'] = $title;
+
+    $this->drupalPost('node/'. $this->nodes[0]->nid .'/edit', $edit, t('Save'));
+
+    // Make sure we get a new version!
+    $node = node_load($this->nodes[0]->nid, NULL, TRUE);
+    $this->assertText(t('@type @title has been updated.',
+                        array('@title' => $node->title,
+                              '@type' => $this->content_types[0]->name)));
+
+    $this->drupalGet('node/'. $node->nid);
+    $this->assertText($title, 'Make sure the link title/text shows');
+    $this->assertNoRaw(' title="'. $title .'"', "We should not show the link title as the title attribute?");
+    $this->assertNoRaw(' title="['. $field_name .'-title]"');
+    //$this->fail($this->content);
+  }
+
+  /**
+   *  Trying to set the url to contain a token.
+   */
+  function _testUserTokenLinkCreateInURL() {
+    $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+    $this->drupalLogin($this->web_user);
+
+    // create field
+    $name = strtolower($this->randomName());
+    $edit = array(
+      '_add_new_field[label]' => $name,
+      '_add_new_field[field_name]' => $name,
+      '_add_new_field[type]' => 'link',
+      '_add_new_field[widget_type]' => 'link',
+    );
+    $this->drupalPost('admin/content/node-type/page/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(
+      'title' => 'required',
+      'enable_tokens' => 1), t('Save field settings'));
+
+    // Is field created?
+    $this->assertRaw(t('Added field %label.', array('%label' => $name)), 'Field added');
+
+    // create page form
+    $this->drupalGet('node/add/page');
+    $field_name = 'field_' . $name;
+    $this->assertField($field_name . '[0][title]', 'Title found');
+    $this->assertField($field_name . '[0][url]', 'URL found');
+
+    $input = array(
+        'href' => 'http://example.com/' . $this->randomName(),
+        'label' => $this->randomName(),
+    );
+
+    $this->drupalLogin($this->web_user);
+    $this->drupalGet('node/add/page');
+
+    $edit = array(
+      'title' => $input['label'],
+      $field_name . '[0][title]' => $input['label'],
+      $field_name . '[0][url]' => $input['href'] . "/[type]",
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $url = $this->getUrl();
+
+    // change to anonymous user
+    $this->drupalLogout();
+    $this->drupalGet($url);
+
+    $this->assertRaw(l($input['label'], $input['href'] .'/page'));
+    //$this->fail($this->content);
+  }
+
+  /**
+   *  Trying to set the url to contain a token.
+   */
+  function _testUserTokenLinkCreateInURL2() {
+    $this->web_user = $this->drupalCreateUser(array('administer content types', 'access content', 'create page content'));
+    $this->drupalLogin($this->web_user);
+
+    // create field
+    $name = strtolower($this->randomName());
+    $edit = array(
+      '_add_new_field[label]' => $name,
+      '_add_new_field[field_name]' => $name,
+      '_add_new_field[type]' => 'link',
+      '_add_new_field[widget_type]' => 'link',
+    );
+    $this->drupalPost('admin/content/node-type/page/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(
+      'title' => 'required',
+      'enable_tokens' => 1), t('Save field settings'));
+
+    // Is field created?
+    $this->assertRaw(t('Added field %label.', array('%label' => $name)), 'Field added');
+
+    // create page form
+    $this->drupalGet('node/add/page');
+    $field_name = 'field_' . $name;
+    $this->assertField($field_name . '[0][title]', 'Title found');
+    $this->assertField($field_name . '[0][url]', 'URL found');
+
+    $input = array(
+        'href' => 'http://example.com/' . $this->randomName(),
+        'label' => $this->randomName(),
+    );
+
+    $this->drupalLogin($this->web_user);
+    $this->drupalGet('node/add/page');
+
+    $edit = array(
+      'title' => $input['label'],
+      $field_name . '[0][title]' => $input['label'],
+      $field_name . '[0][url]' => $input['href'] . "/[author-uid]",
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $url = $this->getUrl();
+
+    // change to anonymous user
+    $this->drupalLogout();
+    $this->drupalGet($url);
+
+    $this->assertRaw(l($input['label'], $input['href'] .'/'. $this->web_user->uid));
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/tests/link.validate.test	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,494 @@
+<?php
+
+/**
+ * @file
+ * Tests that exercise the validation functions in the link module.
+ */
+
+class LinkValidateTestCase extends LinkBaseTestClass {
+
+  protected function createLink($url, $title, $attributes = array()) {
+    return array(
+      'url' => $url,
+      'title' => $title,
+      'attributes' => $attributes,
+    );
+  }
+
+  /**
+   * Takes a url, and sees if it can validate that the url is valid.
+   */
+  protected function link_test_validate_url($url) {
+
+    $field_name = $this->createLinkField();
+
+    $permission = 'create page content';
+    $this->checkPermissions(array($permission), TRUE);
+
+    $this->drupalGet('node/add/page');
+
+    $label = $this->randomName();
+    $edit = array(
+      'title' => $label,
+      $field_name . '[und][0][title]' => $label,
+      $field_name . '[und][0][url]' => $url,
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertRaw(t(' has been created.'), 'Node created');
+
+    $nid = 1; //$matches[1];
+
+    $node = node_load($nid);
+
+    $this->assertEqual($url, $node->{$field_name}['und'][0]['url']);
+  }
+}
+
+class LinkValidateTest extends LinkValidateTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Link Validation Tests',
+      'description' => 'Tests the field validation.',
+      'group' => 'Link',
+    );
+  }
+
+  function test_link_validate_basic_url() {
+    $this->link_test_validate_url('http://www.example.com');
+  }
+
+  /**
+   * Test if we're stopped from posting a bad url on default validation.
+   */
+  function test_link_validate_bad_url_validate_default() {
+    $this->web_user = $this->drupalCreateUser(array('administer content types',
+                                             'administer nodes',
+                                             'administer filters',
+                                             'access content',
+                                             'create page content',
+                                             'access administration pages'));
+    $this->drupalLogin($this->web_user);
+
+    // create field
+    $name = strtolower($this->randomName());
+    $edit = array(
+      'fields[_add_new_field][label]' => $name,
+      'fields[_add_new_field][field_name]' => $name,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $this->drupalPost('admin/structure/types/manage/page/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+    $this->drupalPost(NULL, array(), t('Save settings'));
+
+    // Is field created?
+    $this->assertRaw(t('Saved %label configuration', array('%label' => $name)), 'Field added');
+    node_types_rebuild();
+    menu_rebuild();
+
+    // create page form
+    $this->drupalGet('node/add/page');
+    $field_name = 'field_' . $name;
+    $this->assertField('edit-field-'. $name .'-und-0-title', 'Title found');
+    $this->assertField('edit-field-'. $name .'-und-0-url', 'URL found');
+
+
+    $edit = array(
+      'title' => 'Simple Title',
+      $field_name .'[und][0][url]' => 'edik:naw',
+    );
+
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertText(t('The value provided for @field is not a valid URL.', array('@field' => $name)));
+  }
+
+  /**
+   * Test if we're stopped from posting a bad url with validation on.
+   */
+  function test_link_validate_bad_url_validate_on() {
+    $this->web_user = $this->drupalCreateUser(array('administer content types',
+                                             'administer nodes',
+                                             'administer filters',
+                                             'access content',
+                                             'create page content',
+                                             'access administration pages'));
+    $this->drupalLogin($this->web_user);
+
+    // create field
+    $name = strtolower($this->randomName());
+    $edit = array(
+      'fields[_add_new_field][label]' => $name,
+      'fields[_add_new_field][field_name]' => $name,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $this->drupalPost('admin/structure/types/manage/page/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+    $this->drupalPost(NULL, array('instance[settings][validate_url]' => TRUE), t('Save settings'));
+
+    // Is field created?
+    $this->assertRaw(t('Saved %label configuration', array('%label' => $name)), 'Field added');
+    node_types_rebuild();
+    menu_rebuild();
+
+    // create page form
+    $this->drupalGet('node/add/page');
+    $field_name = 'field_' . $name;
+    $this->assertField('edit-field-'. $name .'-und-0-title', 'Title found');
+    $this->assertField('edit-field-'. $name .'-und-0-url', 'URL found');
+
+
+    $edit = array(
+      'title' => 'Simple Title',
+      $field_name .'[und][0][url]' => 'edik:naw',
+    );
+
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertText(t('The value provided for @field is not a valid URL.', array('@field' => $name)));
+
+  }
+
+  /**
+   * Test if we can post a bad url if the validation is expressly turned off.
+   */
+  function test_link_validate_bad_url_validate_off() {
+    $this->web_user = $this->drupalCreateUser(array('administer content types',
+                                             'administer nodes',
+                                             'administer filters',
+                                             'access content',
+                                             'create page content',
+                                             'access administration pages'));
+    $this->drupalLogin($this->web_user);
+
+    // create field
+    $name = strtolower($this->randomName());
+    $edit = array(
+      'fields[_add_new_field][label]' => $name,
+      'fields[_add_new_field][field_name]' => $name,
+      'fields[_add_new_field][type]' => 'link_field',
+      'fields[_add_new_field][widget_type]' => 'link_field',
+    );
+    $this->drupalPost('admin/structure/types/manage/page/fields', $edit, t('Save'));
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+    $this->drupalPost(NULL, array('instance[settings][validate_url]' => FALSE), t('Save settings'));
+
+    /*$instance_details = db_query("SELECT * FROM {field_config_instance} WHERE field_name = :field_name AND bundle = 'page'", array(':field_name' => 'field_'. $name))->fetchObject();
+    $this->fail('<pre>'. print_r($instance_details, TRUE) .'</pre>');
+    $this->fail('<pre>'. print_r(unserialize($instance_details->data), TRUE) .'</pre>');*/
+
+    // Is field created?
+    $this->assertRaw(t('Saved %label configuration', array('%label' => $name)), 'Field added');
+    node_types_rebuild();
+    menu_rebuild();
+
+    // create page form
+    $this->drupalGet('node/add/page');
+    $field_name = 'field_' . $name;
+    $this->assertField('edit-field-'. $name .'-und-0-title', 'Title found');
+    $this->assertField('edit-field-'. $name .'-und-0-url', 'URL found');
+
+
+    $edit = array(
+      'title' => 'Simple Title',
+      $field_name .'[und][0][url]' => 'edik:naw',
+    );
+
+    $this->drupalPost(NULL, $edit, t('Save'));
+    $this->assertNoText(t('The value provided for @field is not a valid URL.', array('@field' => $name)));
+  }
+
+  /**
+   * Test if a bad url can sneak through un-filtered if we play with the validation...
+   */
+  function x_test_link_validate_switching_between_validation_status() {
+    $this->acquireContentTypes(1);
+    $this->web_user = $this->drupalCreateUser(array('administer content types',
+                                             'administer nodes',
+                                             'access administration pages',
+                                             'access content',
+                                             'create '. $this->content_types[0]->type .' content',
+                                             'edit any '. $this->content_types[0]->type .' content'));
+    $this->drupalLogin($this->web_user);
+    variable_set('node_options_'. $this->content_types[0]->name, array('status', 'promote'));
+    $field_settings = array(
+      'type' => 'link',
+      'widget_type' => 'link',
+      'type_name' => $this->content_types[0]->name,
+      'attributes' => array(), // <-- This is needed or we have an error
+      'validate_url' => 0,
+    );
+
+    $field = $this->createField($field_settings, 0);
+    //$this->fail('<pre>'. print_r($field, TRUE) .'</pre>');
+    $field_db_info = content_database_info($field);
+
+    $this->acquireNodes(2);
+
+    $node = node_load($this->nodes[0]->nid);
+
+    $this->drupalGet('node/'. $this->nodes[0]->nid);
+
+    $edit = array();
+    $title = $this->randomName();
+    $url = 'javascript:alert("http://example.com/' . $this->randomName() . '")';
+    $edit[$field['field_name'] .'[0][url]'] = $url;
+    $edit[$field['field_name'] .'[0][title]'] = $title;
+
+    $this->drupalPost('node/'. $this->nodes[0]->nid .'/edit', $edit, t('Save'));
+    //$this->pass($this->content);
+    $this->assertNoText(t('The value provided for %field is not a valid URL.', array('%field' => $name)));
+
+    // Make sure we get a new version!
+    $node = node_load($this->nodes[0]->nid, NULL, TRUE);
+    $this->assertEqual($url, $node->{$field['field_name']}[0]['url']);
+
+    $this->drupalGet('node/'. $node->nid);
+    $this->assertNoRaw($url, 'Make sure Javascript does not display.');
+
+    // Turn the array validation back _on_.
+    $edit = array('validate_url' => TRUE);
+    $node_type_link = str_replace('_', '-', $node->type);
+    //$this->drupalGet('admin/content/node-type/'. $node_type_link .'/fields'); ///'. $field['field_name']);
+    //$this->fail($this->content);
+    $this->drupalPost('admin/content/node-type/'. $node_type_link .'/fields/'. $field['field_name'], $edit, t('Save field settings'));
+
+    $this->drupalGet('node/'. $node->nid);
+    // This actually works because the display_url goes through the core
+    // url() function.  But we should have a test that makes sure it continues
+    // to work.
+    $this->assertNoRaw($url, 'Make sure Javascript does not display.');
+    //$this->fail($this->content);
+
+  }
+
+  // Validate that '<front>' is a valid url.
+  function test_link_front_url() {
+    $this->link_test_validate_url('<front>');
+  }
+
+  // Validate that an internal url would be accepted.
+  function test_link_internal_url() {
+    $this->link_test_validate_url('node/32');
+  }
+
+  // Validate a simple mailto.
+  function test_link_mailto() {
+    $this->link_test_validate_url('mailto:jcfiala@gmail.com');
+  }
+
+  function test_link_external_https() {
+    $this->link_test_validate_url('https://www.example.com/');
+  }
+
+  function test_link_ftp() {
+    $this->link_test_validate_url('ftp://www.example.com/');
+  }
+}
+
+class LinkValidateTestNews extends LinkValidateTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Link News Validation Tests',
+      'description' => 'Tests the field validation for usenet urls.',
+      'group' => 'Link',
+    );
+  }
+
+  // Validate a news link to a message group
+  function test_link_news() {
+    $this->link_test_validate_url('news:comp.infosystems.www.misc');
+  }
+
+  // Validate a news link to a message id.  Said ID copied off of google groups.
+  function test_link_news_message() {
+    $this->link_test_validate_url('news:hj0db8$vrm$1@news.eternal-september.org');
+  }
+}
+
+class LinkValidateSpecificURL extends LinkValidateTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Link Specific URL Validation Tests',
+      'description' => 'Tests field validation with unusual urls',
+      'group' => 'Link',
+    );
+  }
+
+  // Lets throw in a lot of umlouts for testing!
+  function test_umlout_url() {
+    $this->link_test_validate_url('http://üÜü.exämple.com/nöde');
+  }
+
+  function test_umlout_mailto() {
+    $this->link_test_validate_url('mailto:Üser@exÅmple.com');
+  }
+
+  function test_german_b_url() {
+    $this->link_test_validate_url('http://www.test.com/ßstuff');
+  }
+
+  function test_special_n_url() {
+    $this->link_test_validate_url('http://www.testÑñ.com/');
+  }
+
+  function test_curly_brackets_in_query() {
+    $this->link_test_validate_url('http://www.healthyteennetwork.org/index.asp?Type=B_PR&SEC={2AE1D600-4FC6-4B4D-8822-F1D5F072ED7B}&DE={235FD1E7-208D-4363-9854-4E6775EB8A4C}');
+  }
+
+  /**
+   * Here, we're testing that a very long url is stored properly in the db.
+   *
+   * Basicly, trying to test http://drupal.org/node/376818
+   */
+  function testLinkURLFieldIsBig() {
+    $long_url = 'http://th.wikipedia.org/wiki/%E0%B9%82%E0%B8%A3%E0%B8%87%E0%B9%80%E0%B8%A3%E0%B8%B5%E0%B8%A2%E0%B8%99%E0%B9%80%E0%B8%9A%E0%B8%8D%E0%B8%88%E0%B8%A1%E0%B8%A3%E0%B8%B2%E0%B8%8A%E0%B8%B9%E0%B8%97%E0%B8%B4%E0%B8%A8_%E0%B8%99%E0%B8%84%E0%B8%A3%E0%B8%A8%E0%B8%A3%E0%B8%B5%E0%B8%98%E0%B8%A3%E0%B8%A3%E0%B8%A1%E0%B8%A3%E0%B8%B2%E0%B8%8A';
+    $this->link_test_validate_url($long_url);
+  }
+
+}
+
+/**
+ * A series of tests of links, only going against the link_validate_url function in link.module.
+ *
+ * Validation is guided by the rules in http://tools.ietf.org/html/rfc1738 !
+ */
+class LinkValidateUrlLight extends DrupalWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Link Light Validation Tests',
+      'description' => 'Tests the link_validate_url() function by itself, without invoking the full drupal/cck lifecycle.',
+      'group' => 'Link',
+    );
+  }
+
+  /**
+   * Translates the LINK type constants to english for display and debugging of tests
+   */
+  function name_Link_Type($type) {
+    switch ($type) {
+      case LINK_FRONT:
+        return "Front";
+      case LINK_EMAIL:
+        return "Email";
+      case LINK_NEWS:
+        return "Newsgroup";
+      case LINK_INTERNAL:
+        return "Internal Link";
+      case LINK_EXTERNAL:
+        return "External Link";
+      case FALSE:
+        return "Invalid Link";
+      default:
+        return "Bad Value:". $type;
+    }
+  }
+
+  // Make sure that a link labelled <front> works.
+  function testValidateFrontLink() {
+    $valid = link_validate_url('<front>');
+    $this->assertEqual(LINK_FRONT, $valid, 'Make sure that front link is verfied and identified');
+  }
+
+  function testValidateEmailLink() {
+    $valid = link_validate_url('mailto:bob@example.com');
+    $this->assertEqual(LINK_EMAIL, $valid, "Make sure a basic mailto is verified and identified");
+  }
+
+  function testValidateEmailLinkBad() {
+    $valid = link_validate_url(':bob@example.com');
+    $this->assertEqual(FALSE, $valid, 'Make sure just a bad address is correctly failed');
+  }
+
+  function testValidateNewsgroupLink() {
+    $valid = link_validate_url('news:comp.infosystems.www.misc');
+    $this->assertEqual(LINK_NEWS, $valid, 'Make sure link to newsgroup validates as news.');
+  }
+
+  function testValidateNewsArticleLink() {
+    $valid = link_validate_url('news:hj0db8$vrm$1@news.eternal-september.org');
+    $this->assertEqual(LINK_NEWS, $valid, 'Make sure link to specific article valiates as news.');
+  }
+
+  function testValidateBadNewsgroupLink() {
+    $valid = link_validate_url('news:comp.bad_name.misc');
+    $this->assertEqual(FALSE, $valid, 'newsgroup names can\'t contain underscores, so it should come back as invalid.');
+  }
+
+  function testValidateInternalLinks() {
+    $links = array(
+      'node/5',
+      'rss.xml',
+      'files/test.jpg',
+      '/var/www/test',
+    );
+    
+    foreach ($links as $link) {
+      $valid = link_validate_url($link);
+      $this->assertEqual(LINK_INTERNAL, $valid, 'Test ' . $link . ' internal link.');
+    }
+  }
+
+  function testValidateExternalLinks() {
+    $links = array(
+      'http://localhost:8080/',
+      'www.example.com',
+      'www.example.com/',
+      'http://username:p%40ssw0rd!@www.example.com/',
+      'http://@www.example.com/',
+      'http://username:@www.example.com/',
+      'http://username:password@www.example.com:8080/',
+      'http://127.0.0.1:80/',
+      'http://127.173.24.255:4723/',
+      '127.173.24.255:4723/',
+      'http://255.255.255.255:4823/',
+      'www.test-site.com',
+      'http://example.com/index.php?q=node/123',
+      'http://example.com/index.php?page=this\that',
+      'http://example.com/?first_name=Joe Bob&last_name=Smith',
+      // Anchors
+      'http://www.example.com/index.php#test',
+      'http://www.example.com/index.php#this@that.',
+      'http://www.example.com/index.php#',
+      'http://www.cnn.com/video/#/video/politics/2008/12/09/intv.madeleine.albright.cnn',
+      'http://www.archive.org/stream/aesopsfables00aesorich#page/n7/mode/2up',
+      'http://www.example.com/blah/#this@that?',
+    );
+    // Test all of the protocols.
+    $allowed_protocols = variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'));
+    foreach ($allowed_protocols as $protocol) {
+      if ($protocol !== 'news' && $protocol !== 'mailto') {
+        $links[] = $protocol .'://www.example.com';
+      }
+    }
+    foreach ($links as $link) {
+      $valid = link_validate_url($link);
+      $this->assertEqual(LINK_EXTERNAL, $valid, 'Testing that '. $link .' is a valid external link.');
+      // The following two lines are commented out and only used for comparisons.
+      //$valid2 = valid_url($link, TRUE);
+      //$this->assertEqual(TRUE, $valid2, "Using valid_url() on $link.");
+    }
+    // Test if we can make a tld valid:
+    variable_set('link_extra_domains', array('frog'));
+    $valid = link_validate_url('http://www.example.frog');
+    $this->assertEqual(LINK_EXTERNAL, $valid, "Testing that http://www.example.frog is a valid external link if we've added 'frog' to the list of valid domains.");
+  }
+
+  function testInvalidExternalLinks() {
+    $links = array(
+      'http://www.ex ample.com/',
+      'http://25.0.0/', // bad ip!
+      'http://4827.0.0.2/',
+      '//www.example.com/',
+      'http://www.testß.com/', // ß not allowed in domain names!
+      'http://www.example.frog/', // Bad TLD
+      //'http://www.-fudge.com/', // domains can't have sections starting with a dash.
+    );
+    foreach ($links as $link) {
+      $valid = link_validate_url($link);
+      $this->assertEqual(FALSE, $valid, 'Testing that '. $link .' is not a valid link.');
+    }
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/views/link.views.inc	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,113 @@
+<?php
+/**
+ * @file
+ * Contains functions handling views integration.
+ */
+
+/**
+ * Implementation of hook_views_handlers().
+ */
+/*function link_views_handlers() {
+  return array(
+    'info' => array(
+      'path' => drupal_get_path('module', 'link') .'/views',
+    ),
+    'handlers' => array(
+      'link_views_handler_argument_target' => array(
+        'parent' => 'views_handler_argument',
+      ),
+      'link_views_handler_filter_protocol' => array(
+        'parent' => 'views_handler_filter_string',
+      ),
+    ),
+  );
+}*/
+
+/**
+ * Return CCK Views data for the link_field_settings($op == 'views data').
+ *
+ * @TODO: Is there some way to tell views I have formatters for it?
+ */
+/*function link_views_content_field_data($field) {
+  // Build the automatic views data provided for us by CCK.
+  // This creates all the information necessary for the "url" field.
+  $data = content_views_field_views_data($field);
+
+  $db_info = content_database_info($field);
+  $table_alias = content_views_tablename($field);
+  $field_types = _content_field_types();
+
+  // Tweak the automatic views data for the link "url" field.
+  // Set the filter title to "@label URL"
+  $data[$table_alias][$field['field_name'] .'_url']['filter']['title'] = t('@label URL', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']);
+  // Remove the argument handling for URLs.
+  unset($data[$table_alias][$field['field_name'] .'_url']['argument']);
+
+  // Build out additional views data for the link "title" field.
+  $data[$table_alias][$field['field_name'] .'_title'] = array(
+    'group' => t('Content'),
+    'title' => t('@label title', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']) .' ('. $field['field_name'] .')',
+    'help' =>  $data[$table_alias][$field['field_name'] .'_url']['help'],
+    'argument' => array(
+      'field' => $db_info['columns']['title']['column'],
+      'tablename' => $db_info['table'],
+      'handler' => 'content_handler_argument_string',
+      'click sortable' => TRUE,
+      'name field' => '', // TODO, mimic content.views.inc :)
+      'content_field_name' => $field['field_name'],
+      'allow_empty' => TRUE,
+    ),
+    'filter' => array(
+      'field' => $db_info['columns']['title']['column'],
+      'title' => t('@label title', array('@label' => t($field_types[$field['type']]['label']))),
+      'tablename' => $db_info['table'],
+      'handler' => 'content_handler_filter_string',
+      'additional fields' => array(),
+      'content_field_name' => $field['field_name'],
+      'allow_empty' => TRUE,
+    ),
+    'sort' => array(
+      'field' => $db_info['columns']['title']['column'],
+      'tablename' => $db_info['table'],
+      'handler' => 'content_handler_sort',
+      'content_field_name' => $field['field_name'],
+      'allow_empty' => TRUE,
+    ),
+  );
+
+  // Build out additional Views filter for the link "protocol" pseudo field.
+  // TODO: Add a protocol argument.
+  $data[$table_alias][$field['field_name'] .'_protocol'] = array(
+    'group' => t('Content'),
+    'title' => t('@label protocol', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']) .' ('. $field['field_name'] .')',
+    'help' =>  $data[$table_alias][$field['field_name'] .'_url']['help'],
+    'filter' => array(
+      'field' => $db_info['columns']['url']['column'],
+      'title' => t('@label protocol', array('@label' => t($field_types[$field['type']]['label']))),
+      'tablename' => $db_info['table'],
+      'handler' => 'link_views_handler_filter_protocol',
+      'additional fields' => array(),
+      'content_field_name' => $field['field_name'],
+      'allow_empty' => TRUE,
+    ),
+  );
+
+  // Build out additional Views argument for the link "target" pseudo field.
+  // TODO: Add a target filter.
+  $data[$table_alias][$field['field_name'] .'_target'] = array(
+    'group' => t('Content'),
+    'title' => t('@label target', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']) .' ('. $field['field_name'] .')',
+    'help' =>  $data[$table_alias][$field['field_name'] .'_url']['help'],
+    'argument' => array(
+      'field' => $db_info['columns']['attributes']['column'],
+      'title' => t('@label target', array('@label' => t($field_types[$field['type']]['label']))) .': '. t($field['widget']['label']) .' ('. $field['field_name'] .')',
+      'tablename' => $db_info['table'],
+      'handler' => 'link_views_handler_argument_target',
+      'additional fields' => array(),
+      'content_field_name' => $field['field_name'],
+      'allow_empty' => TRUE,
+    ),
+  );
+
+  return $data;
+}*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/views/link_views_handler_argument_target.inc	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,149 @@
+<?php
+
+/**
+ * @file
+ * Argument handler to filter results by target.
+ */
+
+/**
+ * Argument handler to filter results by target.
+ */
+class link_views_handler_argument_target extends views_handler_argument {
+
+  /**
+   * Provide defaults for the argument when a new one is created.
+   */
+  function options(&$options) {
+    parent::options($options);
+  }
+
+  /**
+   * Provide a default options form for the argument.
+   */
+  function options_form(&$form, &$form_state) {
+    $defaults = $this->default_actions();
+
+    $form['title'] = array(
+      '#prefix' => '<div class="clear-block">',
+      '#suffix' => '</div>',
+      '#type' => 'textfield',
+      '#title' => t('Title'),
+      '#default_value' => $this->options['title'],
+      '#description' => t('The title to use when this argument is present; it will override the title of the view and titles from previous arguments. You can use percent substitution here to replace with argument titles. Use "%1" for the first argument, "%2" for the second, etc.'),
+    );
+
+    $form['clear_start'] = array(
+      '#value' => '<div class="clear-block">',
+    );
+
+    $form['defaults_start'] = array(
+      '#value' => '<div class="views-left-50">',
+    );
+
+    $form['default_action'] = array(
+      '#type' => 'radios',
+      '#title' => t('Action to take if argument is not present'),
+      '#default_value' => $this->options['default_action'],
+    );
+
+    $form['defaults_stop'] = array(
+      '#value' => '</div>',
+    );
+
+    $form['wildcard'] = array(
+      '#prefix' => '<div class="views-right-50">',
+      // prefix and no suffix means these two items will be grouped together.
+      '#type' => 'textfield',
+      '#title' => t('Wildcard'),
+      '#size' => 20,
+      '#default_value' => $this->options['wildcard'],
+      '#description' => t('If this value is received as an argument, the argument will be ignored; i.e, "all values"'),
+    );
+
+    $form['wildcard_substitution'] = array(
+      '#suffix' => '</div>',
+      '#type' => 'textfield',
+      '#title' => t('Wildcard title'),
+      '#size' => 20,
+      '#default_value' => $this->options['wildcard_substitution'],
+      '#description' => t('The title to use for the wildcard in substitutions elsewhere.'),
+    );
+
+    $form['clear_stop'] = array(
+      '#value' => '</div>',
+    );
+
+    $options = array();
+    $validate_options = array();
+    foreach ($defaults as $id => $info) {
+      $options[$id] = $info['title'];
+      if (empty($info['default only'])) {
+        $validate_options[$id] = $info['title'];
+      }
+      if (!empty($info['form method'])) {
+        $this->{$info['form method']}($form, $form_state);
+      }
+    }
+
+    $form['default_action']['#options'] = $options;
+
+    $form['validate_type'] = array(
+      '#type' => 'select',
+      '#title' => t('Validator'),
+      '#default_value' => $this->options['validate_type'],
+    );
+
+    $validate_types = array('none' => t('- Basic validation -'));
+    $plugins = views_fetch_plugin_data('argument validator');
+    foreach ($plugins as $id => $info) {
+      $valid = TRUE;
+      if (!empty($info['type'])) {
+        $valid = FALSE;
+        if (empty($this->definition['validate type'])) {
+          continue;
+        }
+        foreach ((array) $info['type'] as $type) {
+          if ($type == $this->definition['validate type']) {
+            $valid = TRUE;
+            break;
+          }
+        }
+      }
+
+      // If we decide this validator is ok, add it to the list.
+      if ($valid) {
+        $plugin = views_get_plugin('argument validator', $id);
+        if ($plugin) {
+          $plugin->init($this->view, $this, $id);
+          if ($plugin->access()) {
+            $plugin->validate_form($form, $form_state, $id);
+            $validate_types[$id] = $info['title'];
+          }
+        }
+      }
+    }
+
+    asort($validate_types);
+    $form['validate_type']['#options'] = $validate_types;
+    // Show this gadget if *anything* but 'none' is selected
+
+    $form['validate_fail'] = array(
+      '#type' => 'select',
+      '#title' => t('Action to take if argument does not validate'),
+      '#default_value' => $this->options['validate_fail'],
+      '#options' => $validate_options,
+    );
+  }
+
+  /**
+   * Set up the query for this argument.
+   *
+   * The argument sent may be found at $this->argument.
+   */
+  function query($group_by = FALSE) {
+    $this->ensure_my_table();
+    // Because attributes are stored serialized, our only option is to also
+    // serialize the data we're searching for and use LIKE to find similar data.
+    $this->query->add_where(0, $this->table_alias . '.' . $this->real_field . " LIKE '%%%s%'", serialize(array('target' => $this->argument)));
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/openmindattribute/views/link_views_handler_filter_protocol.inc	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * @file
+ * Contains filter handlers for protocol filters with views.
+ */
+
+/**
+ * Filter handler for limiting a view to URLs of a certain protocol.
+ */
+class link_views_handler_filter_protocol extends views_handler_filter_string {
+  /**
+   * Set defaults for the filter options.
+   */
+  function options(&$options) {
+    parent::options($options);
+    $options['operator'] = 'OR';
+    $options['value'] = 'http';
+    $options['case'] = 0;
+  }
+
+  /**
+   * Define the operators supported for protocols.
+   */
+  function operators() {
+    $operators = array(
+      'OR' => array(
+        'title' => t('Is one of'),
+        'short' => t('='),
+        'method' => 'op_protocol',
+        'values' => 1,
+      ),
+    );
+
+    return $operators;
+  }
+
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['case'] = array(
+      '#type' => 'value',
+      '#value' => 0,
+    );
+  }
+
+  /**
+   * Provide a select list to choose the desired protocols.
+   */
+  function value_form(&$form, &$form_state) {
+    // We have to make some choices when creating this as an exposed
+    // filter form. For example, if the operator is locked and thus
+    // not rendered, we can't render dependencies; instead we only
+    // render the form items we need.
+    $which = 'all';
+    if (!empty($form_state['exposed']) && empty($this->options['expose']['operator'])) {
+      $which = in_array($this->operator, $this->operator_values(1)) ? 'value' : 'none';
+    }
+
+    if ($which == 'all' || $which == 'value') {
+      $form['value'] = array(
+        '#type' => 'select',
+        '#title' => t('Protocol'),
+        '#default_value' => $this->value,
+        '#options' => drupal_map_assoc(variable_get('filter_allowed_protocols', array('http', 'https', 'ftp', 'news', 'nntp', 'telnet', 'mailto', 'irc', 'ssh', 'sftp', 'webcal'))),
+        '#multiple' => 1,
+        '#size' => 4,
+        '#description' => t('The protocols displayed here are those globally available. You may add more protocols by modifying the <em>filter_allowed_protocols</em> variable in your installation.'),
+      );
+    }
+  }
+
+  /**
+   * Filter down the query to include only the selected protocols.
+   */
+  function op_protocol($field, $upper) {
+    $db_type = db_driver();
+
+    $protocols = $this->value;
+
+    $where_conditions = array();
+    foreach ($protocols as $protocol) {
+      // Simple case, the URL begins with the specified protocol.
+      $condition = $field . ' LIKE \'' . $protocol . '%\'';
+
+      // More complex case, no protocol specified but is automatically cleaned up
+      // by link_cleanup_url(). RegEx is required for this search operation.
+      if ($protocol == 'http') {
+        $LINK_DOMAINS = _link_domains();
+        if ($db_type == 'pgsql') {
+          // PostGreSQL code has NOT been tested. Please report any problems to the link issue queue.
+          // pgSQL requires all slashes to be double escaped in regular expressions.
+          // See http://www.postgresql.org/docs/8.1/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP
+          $condition .= ' OR ' . $field .' ~* \''.'^(([a-z0-9]([a-z0-9\\-_]*\\.)+)(' . $LINK_DOMAINS . '|[a-z][a-z]))' . '\'';
+        }
+        else {
+          // mySQL requires backslashes to be double (triple?) escaped within character classes.
+          // See http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_regexp
+          $condition .= ' OR ' . $field . ' REGEXP \''.'^(([a-z0-9]([a-z0-9\\\-_]*\.)+)(' . $LINK_DOMAINS . '|[a-z][a-z]))' . '\'';
+        }
+      }
+
+      $where_conditions[] = $condition;
+    }
+
+    $this->query->add_where($this->options['group'], implode(' ' . $this->operator . ' ', $where_conditions));
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relation_processor/FeedsProcessor.inc	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,824 @@
+<?php
+
+/**
+ * @file
+ * Contains FeedsProcessor and related classes.
+ */
+
+// Update mode for existing items.
+define('FEEDS_SKIP_EXISTING', 0);
+define('FEEDS_REPLACE_EXISTING', 1);
+define('FEEDS_UPDATE_EXISTING', 2);
+
+// Default limit for creating items on a page load, not respected by all
+// processors.
+define('FEEDS_PROCESS_LIMIT', 50);
+
+/**
+ * Thrown if a validation fails.
+ */
+class FeedsValidationException extends Exception {}
+
+/**
+ * Thrown if a an access check fails.
+ */
+class FeedsAccessException extends Exception {}
+
+/**
+ * Abstract class, defines interface for processors.
+ */
+abstract class FeedsProcessor extends FeedsPlugin {
+
+  /**
+   * Implements FeedsPlugin::pluginType().
+   */
+  public function pluginType() {
+    return 'processor';
+  }
+
+  /**
+   * @defgroup entity_api_wrapper Entity API wrapper.
+   */
+
+  /**
+   * Entity type this processor operates on.
+   */
+  public abstract function entityType();
+
+  /**
+   * Bundle type this processor operates on.
+   *
+   * Defaults to the entity type for entities that do not define bundles.
+   *
+   * @return string|NULL
+   *   The bundle type this processor operates on, or NULL if it is undefined.
+   */
+  public function bundle() {
+    return $this->config['bundle'];
+  }
+
+  /**
+   * Provides a list of bundle options for use in select lists.
+   *
+   * @return array
+   *   A keyed array of bundle => label.
+   */
+  public function bundleOptions() {
+    $options = array();
+    foreach (field_info_bundles($this->entityType()) as $bundle => $info) {
+      if (!empty($info['label'])) {
+        $options[$bundle] = $info['label'];
+      }
+      else {
+        $options[$bundle] = $bundle;
+      }
+    }
+    return $options;
+  }
+
+  /**
+   * Create a new entity.
+   *
+   * @param $source
+   *   The feeds source that spawns this entity.
+   *
+   * @return
+   *   A new entity object.
+   */
+  protected abstract function newEntity(FeedsSource $source);
+
+  /**
+   * Load an existing entity.
+   *
+   * @param $source
+   *   The feeds source that spawns this entity.
+   * @param $entity_id
+   *   The unique id of the entity that should be loaded.
+   *
+   * @return
+   *   A new entity object.
+   *
+   * @todo We should be able to batch load these, if we found all of the
+   *   existing ids first.
+   */
+  protected function entityLoad(FeedsSource $source, $entity_id) {
+    if ($this->config['update_existing'] == FEEDS_UPDATE_EXISTING) {
+      $entities = entity_load($this->entityType(), array($entity_id));
+      return reset($entities);
+    }
+
+    $info = $this->entityInfo();
+
+    $args = array(':entity_id' => $entity_id);
+
+    $table = db_escape_table($info['base table']);
+    $key = db_escape_field($info['entity keys']['id']);
+
+    return db_query("SELECT * FROM {" . $table . "} WHERE $key = :entity_id", $args)->fetchObject();
+  }
+
+  /**
+   * Validate an entity.
+   *
+   * @throws FeedsValidationException $e
+   *   If validation fails.
+   */
+  protected function entityValidate($entity) {}
+
+  /**
+   * Access check for saving an enity.
+   *
+   * @param $entity
+   *   Entity to be saved.
+   *
+   * @throws FeedsAccessException $e
+   *   If the access check fails.
+   */
+  protected function entitySaveAccess($entity) {}
+
+  /**
+   * Save an entity.
+   *
+   * @param $entity
+   *   Entity to be saved.
+   */
+  protected abstract function entitySave($entity);
+
+  /**
+   * Delete a series of entities.
+   *
+   * @param $entity_ids
+   *   Array of unique identity ids to be deleted.
+   */
+  protected abstract function entityDeleteMultiple($entity_ids);
+
+  /**
+   * Wrap entity_get_info() into a method so that extending classes can override
+   * it and more entity information. Allowed additional keys:
+   *
+   * 'label plural' ... the plural label of an entity type.
+   */
+  protected function entityInfo() {
+    return entity_get_info($this->entityType());
+  }
+
+  /**
+   * @}
+   */
+
+  /**
+   * Process the result of the parsing stage.
+   *
+   * @param FeedsSource $source
+   *   Source information about this import.
+   * @param FeedsParserResult $parser_result
+   *   The result of the parsing stage.
+   */
+  public function process(FeedsSource $source, FeedsParserResult $parser_result) {
+    $state = $source->state(FEEDS_PROCESS);
+
+    while ($item = $parser_result->shiftItem()) {
+
+      // Check if this item already exists.
+      $entity_id = $this->existingEntityId($source, $parser_result);
+      $skip_existing = $this->config['update_existing'] == FEEDS_SKIP_EXISTING;
+
+      module_invoke_all('feeds_before_update', $source, $item, $entity_id);
+
+      // If it exists, and we are not updating, pass onto the next item.
+      if ($entity_id && $skip_existing) {
+        continue;
+      }
+
+      $hash = $this->hash($item);
+      $changed = ($hash !== $this->getHash($entity_id));
+      $force_update = $this->config['skip_hash_check'];
+
+      // Do not proceed if the item exists, has not changed, and we're not
+      // forcing the update.
+      if ($entity_id && !$changed && !$force_update) {
+        continue;
+      }
+
+      try {
+
+        // Load an existing entity.
+        if ($entity_id) {
+          $entity = $this->entityLoad($source, $entity_id);
+
+          // The feeds_item table is always updated with the info for the most
+          // recently processed entity. The only carryover is the entity_id.
+          $this->newItemInfo($entity, $source->feed_nid, $hash);
+          $entity->feeds_item->entity_id = $entity_id;
+          $entity->feeds_item->is_new = FALSE;
+        }
+
+        // Build a new entity.
+        else {
+
+          $entity = $this->newEntity($source);
+          $this->newItemInfo($entity, $source->feed_nid, $hash);
+        }
+
+        // Set property and field values.
+        $this->map($source, $parser_result, $entity);
+        $this->entityValidate($entity);
+
+        // Allow modules to alter the entity before saving.
+        module_invoke_all('feeds_presave', $source, $entity, $item, $entity_id);
+        if (module_exists('rules')) {
+          rules_invoke_event('feeds_import_'. $source->importer()->id, $entity);
+        }
+
+        // Enable modules to skip saving at all.
+        if (!empty($entity->feeds_item->skip)) {
+          continue;
+        }
+
+        // This will throw an exception on failure.
+        $this->entitySaveAccess($entity);
+        $this->entitySave($entity);
+
+        // Allow modules to perform operations using the saved entity data.
+        // $entity contains the updated entity after saving.
+        module_invoke_all('feeds_after_save', $source, $entity, $item, $entity_id);
+
+        // Track progress.
+        if (empty($entity_id)) {
+          $state->created++;
+        }
+        else {
+          $state->updated++;
+        }
+      }
+
+      // Something bad happened, log it.
+      catch (Exception $e) {
+        $state->failed++;
+        drupal_set_message($e->getMessage(), 'warning');
+        $message = $this->createLogMessage($e, $entity, $item);
+        $source->log('import', $message, array(), WATCHDOG_ERROR);
+      }
+    }
+
+    // Set messages if we're done.
+    if ($source->progressImporting() != FEEDS_BATCH_COMPLETE) {
+      return;
+    }
+    $info = $this->entityInfo();
+    $tokens = array(
+      '@entity' => strtolower($info['label']),
+      '@entities' => strtolower($info['label plural']),
+    );
+    $messages = array();
+    if ($state->created) {
+      $messages[] = array(
+       'message' => format_plural(
+          $state->created,
+          'Created @number @entity.',
+          'Created @number @entities.',
+          array('@number' => $state->created) + $tokens
+        ),
+      );
+    }
+    if ($state->updated) {
+      $messages[] = array(
+       'message' => format_plural(
+          $state->updated,
+          'Updated @number @entity.',
+          'Updated @number @entities.',
+          array('@number' => $state->updated) + $tokens
+        ),
+      );
+    }
+    if ($state->failed) {
+      $messages[] = array(
+       'message' => format_plural(
+          $state->failed,
+          'Failed importing @number @entity.',
+          'Failed importing @number @entities.',
+          array('@number' => $state->failed) + $tokens
+        ),
+        'level' => WATCHDOG_ERROR,
+      );
+    }
+    if (empty($messages)) {
+      $messages[] = array(
+        'message' => t('There are no new @entities.', array('@entities' => strtolower($info['label plural']))),
+      );
+    }
+    foreach ($messages as $message) {
+      drupal_set_message($message['message']);
+      $source->log('import', $message['message'], array(), isset($message['level']) ? $message['level'] : WATCHDOG_INFO);
+    }
+  }
+
+  /**
+   * Remove all stored results or stored results up to a certain time for a
+   * source.
+   *
+   * @param FeedsSource $source
+   *   Source information for this expiry. Implementers should only delete items
+   *   pertaining to this source. The preferred way of determining whether an
+   *   item pertains to a certain souce is by using $source->feed_nid. It is the
+   *   processor's responsibility to store the feed_nid of an imported item in
+   *   the processing stage.
+   */
+  public function clear(FeedsSource $source) {
+    $state = $source->state(FEEDS_PROCESS_CLEAR);
+
+    // Build base select statement.
+    $info = $this->entityInfo();
+    $select = db_select($info['base table'], 'e');
+    $select->addField('e', $info['entity keys']['id'], 'entity_id');
+    $select->join(
+      'feeds_item',
+      'fi',
+      "e.{$info['entity keys']['id']} = fi.entity_id AND fi.entity_type = '{$this->entityType()}'");
+    $select->condition('fi.id', $this->id);
+    $select->condition('fi.feed_nid', $source->feed_nid);
+
+    // If there is no total, query it.
+    if (!$state->total) {
+      $state->total = $select->countQuery()
+        ->execute()
+        ->fetchField();
+    }
+
+    // Delete a batch of entities.
+    $entities = $select->range(0, $this->getLimit())->execute();
+    $entity_ids = array();
+    foreach ($entities as $entity) {
+      $entity_ids[$entity->entity_id] = $entity->entity_id;
+    }
+    $this->entityDeleteMultiple($entity_ids);
+
+    // Report progress, take into account that we may not have deleted as
+    // many items as we have counted at first.
+    if (count($entity_ids)) {
+      $state->deleted += count($entity_ids);
+      $state->progress($state->total, $state->deleted);
+    }
+    else {
+      $state->progress($state->total, $state->total);
+    }
+
+    // Report results when done.
+    if ($source->progressClearing() == FEEDS_BATCH_COMPLETE) {
+      if ($state->deleted) {
+        $message = format_plural(
+          $state->deleted,
+          'Deleted @number @entity',
+          'Deleted @number @entities',
+          array(
+            '@number' => $state->deleted,
+            '@entity' => strtolower($info['label']),
+            '@entities' => strtolower($info['label plural']),
+          )
+        );
+        $source->log('clear', $message, array(), WATCHDOG_INFO);
+        drupal_set_message($message);
+      }
+      else {
+        drupal_set_message(t('There are no @entities to be deleted.', array('@entities' => $info['label plural'])));
+      }
+    }
+  }
+
+  /*
+   * Report number of items that can be processed per call.
+   *
+   * 0 means 'unlimited'.
+   *
+   * If a number other than 0 is given, Feeds parsers that support batching
+   * will only deliver this limit to the processor.
+   *
+   * @see FeedsSource::getLimit()
+   * @see FeedsCSVParser::parse()
+   */
+  public function getLimit() {
+    return variable_get('feeds_process_limit', FEEDS_PROCESS_LIMIT);
+  }
+
+  /**
+   * Delete feed items younger than now - $time. Do not invoke expire on a
+   * processor directly, but use FeedsImporter::expire() instead.
+   *
+   * @see FeedsImporter::expire().
+   * @see FeedsDataProcessor::expire().
+   *
+   * @param $time
+   *   If implemented, all items produced by this configuration that are older
+   *   than REQUEST_TIME - $time should be deleted.
+   *   If $time === NULL processor should use internal configuration.
+   *
+   * @return
+   *   FEEDS_BATCH_COMPLETE if all items have been processed, a float between 0
+   *   and 0.99* indicating progress otherwise.
+   */
+  public function expire($time = NULL) {
+    return FEEDS_BATCH_COMPLETE;
+  }
+
+  /**
+   * Counts the number of items imported by this processor.
+   */
+  public function itemCount(FeedsSource $source) {
+    return db_query("SELECT count(*) FROM {feeds_item} WHERE id = :id AND entity_type = :entity_type AND feed_nid = :feed_nid", array(':id' => $this->id, ':entity_type' => $this->entityType(), ':feed_nid' => $source->feed_nid))->fetchField();
+  }
+
+  /**
+   * Execute mapping on an item.
+   *
+   * This method encapsulates the central mapping functionality. When an item is
+   * processed, it is passed through map() where the properties of $source_item
+   * are mapped onto $target_item following the processor's mapping
+   * configuration.
+   *
+   * For each mapping FeedsParser::getSourceElement() is executed to retrieve
+   * the source element, then FeedsProcessor::setTargetElement() is invoked
+   * to populate the target item properly. Alternatively a
+   * hook_x_targets_alter() may have specified a callback for a mapping target
+   * in which case the callback is asked to populate the target item instead of
+   * FeedsProcessor::setTargetElement().
+   *
+   * @ingroup mappingapi
+   *
+   * @see hook_feeds_parser_sources_alter()
+   * @see hook_feeds_data_processor_targets_alter()
+   * @see hook_feeds_node_processor_targets_alter()
+   * @see hook_feeds_term_processor_targets_alter()
+   * @see hook_feeds_user_processor_targets_alter()
+   */
+  protected function map(FeedsSource $source, FeedsParserResult $result, $target_item = NULL) {
+
+    // Static cache $targets as getMappingTargets() may be an expensive method.
+    static $sources;
+    if (!isset($sources[$this->id])) {
+      $sources[$this->id] = feeds_importer($this->id)->parser->getMappingSources();
+    }
+    static $targets;
+    if (!isset($targets[$this->id])) {
+      $targets[$this->id] = $this->getMappingTargets();
+    }
+    $parser = feeds_importer($this->id)->parser;
+    if (empty($target_item)) {
+      $target_item = array();
+    }
+
+    // Many mappers add to existing fields rather than replacing them. Hence we
+    // need to clear target elements of each item before mapping in case we are
+    // mapping on a prepopulated item such as an existing node.
+    foreach ($this->config['mappings'] as $mapping) {
+      if (isset($targets[$this->id][$mapping['target']]['real_target'])) {
+        unset($target_item->{$targets[$this->id][$mapping['target']]['real_target']});
+      }
+      elseif (isset($target_item->{$mapping['target']})) {
+        unset($target_item->{$mapping['target']});
+      }
+    }
+
+    /*
+    This is where the actual mapping happens: For every mapping we envoke
+    the parser's getSourceElement() method to retrieve the value of the source
+    element and pass it to the processor's setTargetElement() to stick it
+    on the right place of the target item.
+
+    If the mapping specifies a callback method, use the callback instead of
+    setTargetElement().
+    */
+    self::loadMappers();
+    foreach ($this->config['mappings'] as $mapping) {
+      // Retrieve source element's value from parser.
+      if (isset($sources[$this->id][$mapping['source']]) &&
+          is_array($sources[$this->id][$mapping['source']]) &&
+          isset($sources[$this->id][$mapping['source']]['callback']) &&
+          function_exists($sources[$this->id][$mapping['source']]['callback'])) {
+        $callback = $sources[$this->id][$mapping['source']]['callback'];
+        $value = $callback($source, $result, $mapping['source']);
+      }
+      else {
+        $value = $parser->getSourceElement($source, $result, $mapping['source']);
+      }
+
+      // Map the source element's value to the target.
+      if (isset($targets[$this->id][$mapping['target']]) &&
+          is_array($targets[$this->id][$mapping['target']]) &&
+          isset($targets[$this->id][$mapping['target']]['callback']) &&
+          function_exists($targets[$this->id][$mapping['target']]['callback'])) {
+        $callback = $targets[$this->id][$mapping['target']]['callback'];
+        $callback($source, $target_item, $mapping['target'], $value, $mapping);
+      }
+      else {
+        $this->setTargetElement($source, $target_item, $mapping['target'], $value, $mapping);
+      }
+    }
+    return $target_item;
+  }
+
+  /**
+   * Per default, don't support expiry. If processor supports expiry of imported
+   * items, return the time after which items should be removed.
+   */
+  public function expiryTime() {
+    return FEEDS_EXPIRE_NEVER;
+  }
+
+  /**
+   * Declare default configuration.
+   */
+  public function configDefaults() {
+    $info = $this->entityInfo();
+    $bundle = NULL;
+    if (empty($info['entity keys']['bundle'])) {
+      $bundle = $this->entityType();
+    }
+    return array(
+      'mappings' => array(),
+      'update_existing' => FEEDS_SKIP_EXISTING,
+      'input_format' => NULL,
+      'skip_hash_check' => FALSE,
+      'bundle' => $bundle,
+    );
+  }
+
+  /**
+   * Overrides parent::configForm().
+   */
+  public function configForm(&$form_state) {
+    $info = $this->entityInfo();
+    $form = array();
+
+    if (!empty($info['entity keys']['bundle'])) {
+      $form['bundle'] = array(
+        '#type' => 'select',
+        '#options' => $this->bundleOptions(),
+        '#title' => !empty($info['bundle name']) ? $info['bundle name'] : t('Bundle'),
+        '#required' => TRUE,
+        '#default_value' => $this->bundle(),
+      );
+    }
+    else {
+      $form['bundle'] = array(
+        '#type' => 'value',
+        '#value' => $this->entityType(),
+      );
+    }
+
+    $tokens = array('@entities' => strtolower($info['label plural']));
+
+    $form['update_existing'] = array(
+      '#type' => 'radios',
+      '#title' => t('Update existing @entities', $tokens),
+      '#description' =>
+        t('Existing @entities will be determined using mappings that are a "unique target".', $tokens),
+      '#options' => array(
+        FEEDS_SKIP_EXISTING => t('Do not update existing @entities', $tokens),
+        FEEDS_REPLACE_EXISTING => t('Replace existing @entities', $tokens),
+        FEEDS_UPDATE_EXISTING => t('Update existing @entities', $tokens),
+      ),
+      '#default_value' => $this->config['update_existing'],
+    );
+    global $user;
+    $formats = filter_formats($user);
+    foreach ($formats as $format) {
+      $format_options[$format->format] = $format->name;
+    }
+    $form['skip_hash_check'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Skip hash check'),
+      '#description' => t('Force update of items even if item source data did not change.'),
+      '#default_value' => $this->config['skip_hash_check'],
+    );
+    $form['input_format'] = array(
+      '#type' => 'select',
+      '#title' => t('Text format'),
+      '#description' => t('Select the input format for the body field of the nodes to be created.'),
+      '#options' => $format_options,
+      '#default_value' => isset($this->config['input_format']) ? $this->config['input_format'] : 'plain_text',
+      '#required' => TRUE,
+    );
+
+    return $form;
+  }
+
+  /**
+   * Get mappings.
+   */
+  public function getMappings() {
+    return isset($this->config['mappings']) ? $this->config['mappings'] : array();
+  }
+
+  /**
+   * Declare possible mapping targets that this processor exposes.
+   *
+   * @ingroup mappingapi
+   *
+   * @return
+   *   An array of mapping targets. Keys are paths to targets
+   *   separated by ->, values are TRUE if target can be unique,
+   *   FALSE otherwise.
+   */
+  public function getMappingTargets() {
+
+    // The bundle has not been selected.
+    if (!$this->bundle()) {
+      $info = $this->entityInfo();
+      $bundle_name = !empty($info['bundle name']) ? drupal_strtolower($info['bundle name']) : t('bundle');
+      $plugin_key = feeds_importer($this->id)->config['processor']['plugin_key'];
+      $url = url('admin/structure/feeds/' . $this->id . '/settings/' . $plugin_key);
+      drupal_set_message(t('Please <a href="@url">select a @bundle_name</a>.', array('@url' => $url, '@bundle_name' => $bundle_name)), 'warning', FALSE);
+    }
+
+    return array(
+      'url' => array(
+        'name' => t('URL'),
+        'description' => t('The external URL of the item. E. g. the feed item URL in the case of a syndication feed. May be unique.'),
+        'optional_unique' => TRUE,
+      ),
+      'guid' => array(
+        'name' => t('GUID'),
+        'description' => t('The globally unique identifier of the item. E. g. the feed item GUID in the case of a syndication feed. May be unique.'),
+        'optional_unique' => TRUE,
+      ),
+    );
+  }
+
+  /**
+   * Set a concrete target element. Invoked from FeedsProcessor::map().
+   *
+   * @ingroup mappingapi
+   */
+  public function setTargetElement(FeedsSource $source, $target_item, $target_element, $value) {
+    switch ($target_element) {
+      case 'url':
+      case 'guid':
+        $target_item->feeds_item->$target_element = $value;
+        break;
+      default:
+        $target_item->$target_element = $value;
+        break;
+    }
+  }
+
+  /**
+   * Retrieve the target entity's existing id if available. Otherwise return 0.
+   *
+   * @ingroup mappingapi
+   *
+   * @param FeedsSource $source
+   *   The source information about this import.
+   * @param $result
+   *   A FeedsParserResult object.
+   *
+   * @return
+   *   The serial id of an entity if found, 0 otherwise.
+   */
+  protected function existingEntityId(FeedsSource $source, FeedsParserResult $result) {
+    $query = db_select('feeds_item')
+      ->fields('feeds_item', array('entity_id'))
+      ->condition('feed_nid', $source->feed_nid)
+      ->condition('entity_type', $this->entityType())
+      ->condition('id', $source->id);
+
+    // Iterate through all unique targets and test whether they do already
+    // exist in the database.
+    foreach ($this->uniqueTargets($source, $result) as $target => $value) {
+      switch ($target) {
+        case 'url':
+          $entity_id = $query->condition('url', $value)->execute()->fetchField();
+          break;
+        case 'guid':
+          $entity_id = $query->condition('guid', $value)->execute()->fetchField();
+          break;
+      }
+      if (isset($entity_id)) {
+        // Return with the content id found.
+        return $entity_id;
+      }
+    }
+    return 0;
+  }
+
+
+  /**
+   * Utility function that iterates over a target array and retrieves all
+   * sources that are unique.
+   *
+   * @param $batch
+   *   A FeedsImportBatch.
+   *
+   * @return
+   *   An array where the keys are target field names and the values are the
+   *   elements from the source item mapped to these targets.
+   */
+  protected function uniqueTargets(FeedsSource $source, FeedsParserResult $result) {
+    $parser = feeds_importer($this->id)->parser;
+    $targets = array();
+    foreach ($this->config['mappings'] as $mapping) {
+      if (!empty($mapping['unique'])) {
+        // Invoke the parser's getSourceElement to retrieve the value for this
+        // mapping's source.
+        $targets[$mapping['target']] = $parser->getSourceElement($source, $result, $mapping['source']);
+      }
+    }
+    return $targets;
+  }
+
+  /**
+   * Adds Feeds specific information on $entity->feeds_item.
+   *
+   * @param $entity
+   *   The entity object to be populated with new item info.
+   * @param $feed_nid
+   *   The feed nid of the source that produces this entity.
+   * @param $hash
+   *   The fingerprint of the source item.
+   */
+  protected function newItemInfo($entity, $feed_nid, $hash = '') {
+    $entity->feeds_item = new stdClass();
+    $entity->feeds_item->is_new = TRUE;
+    $entity->feeds_item->entity_id = 0;
+    $entity->feeds_item->entity_type = $this->entityType();
+    $entity->feeds_item->id = $this->id;
+    $entity->feeds_item->feed_nid = $feed_nid;
+    $entity->feeds_item->imported = REQUEST_TIME;
+    $entity->feeds_item->hash = $hash;
+    $entity->feeds_item->url = '';
+    $entity->feeds_item->guid = '';
+  }
+
+  /**
+   * Loads existing entity information and places it on $entity->feeds_item.
+   *
+   * @param $entity
+   *   The entity object to load item info for. Id key must be present.
+   *
+   * @return
+   *   TRUE if item info could be loaded, false if not.
+   */
+  protected function loadItemInfo($entity) {
+    $entity_info = entity_get_info($this->entityType());
+    $key = $entity_info['entity keys']['id'];
+    if ($item_info = feeds_item_info_load($this->entityType(), $entity->$key)) {
+      $entity->feeds_item = $item_info;
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
+   * Create MD5 hash of item and mappings array.
+   *
+   * Include mappings as a change in mappings may have an affect on the item
+   * produced.
+   *
+   * @return Always returns a hash, even with empty, NULL, FALSE:
+   *  Empty arrays return 40cd750bba9870f18aada2478b24840a
+   *  Empty/NULL/FALSE strings return d41d8cd98f00b204e9800998ecf8427e
+   */
+  protected function hash($item) {
+    return hash('md5', serialize($item) . serialize($this->config['mappings']));
+  }
+
+  /**
+   * Retrieves the MD5 hash of $entity_id from the database.
+   *
+   * @return string
+   *   Empty string if no item is found, hash otherwise.
+   */
+  protected function getHash($entity_id) {
+
+    if ($hash = db_query("SELECT hash FROM {feeds_item} WHERE entity_type = :type AND entity_id = :id", array(':type' => $this->entityType(), ':id' => $entity_id))->fetchField()) {
+      // Return with the hash.
+      return $hash;
+    }
+    return '';
+  }
+
+  /**
+   * Creates a log message for when an exception occured during import.
+   *
+   * @param Exception $e
+   *   The exception that was throwned during processing the item.
+   * @param $entity
+   *   The entity object.
+   * @param $item
+   *   The parser result for this entity.
+   *
+   * @return string
+   *   The message to log.
+   */
+  protected function createLogMessage(Exception $e, $entity, $item) {
+    include_once DRUPAL_ROOT . '/includes/utility.inc';
+    $message = $e->getMessage();
+    $message .= '<h3>Original item</h3>';
+    $message .= '<pre>' . drupal_var_export($item). '</pre>';
+    $message .= '<h3>Entity</h3>';
+    $message .= '<pre>' . drupal_var_export($entity) . '</pre>';
+    return $message;
+  }
+
+}
+
+class FeedsProcessorBundleNotDefined extends Exception {}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relation_processor/FeedsRelationProcessor.inc	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,413 @@
+<?php
+
+/**
+ * @file
+ * Class definition of FeedsNodeProcessor.
+ */
+
+/**
+ * Creates nodes from feed items.
+ */
+class FeedsRelationProcessor extends FeedsProcessor {
+
+  /**
+   * Define entity type.
+   */
+  public function entityType() {
+    return 'relation';
+  }
+
+  /**
+   * Implements parent::entityInfo().
+   */
+  protected function entityInfo() {
+    $info = parent::entityInfo();
+    $info['label plural'] = t('Relations');
+    return $info;
+  }
+
+  /**
+   * Creates a new node in memory and returns it.
+   */
+  protected function newEntity(FeedsSource $source) {
+    /*$node = new stdClass();
+     $node->type = $this->bundle();
+    $node->changed = REQUEST_TIME;
+    $node->created = REQUEST_TIME;
+    $node->language = LANGUAGE_NONE;
+    $node->is_new = TRUE;
+    node_object_prepare($node);
+    // Populate properties that are set by node_object_prepare().
+    $node->log = 'Created by FeedsNodeProcessor';
+    $node->uid = $this->config['author'];
+    */
+
+
+    $relation = new stdClass();
+    $relation->is_new = TRUE;
+
+    $relation->relation_type = $this->bundle();
+    $relation->uid = $this->config['author'];
+    $relation->endpoints[LANGUAGE_NONE] = Null;
+
+    $relation->changed = REQUEST_TIME;
+    $relation->created = REQUEST_TIME;
+
+    return $relation;
+
+  }
+
+  /**
+   * Loads an existing node.
+   *
+   * If the update existing method is not FEEDS_UPDATE_EXISTING, only the node
+   * table will be loaded, foregoing the node_load API for better performance.
+   *
+   * @todo Reevaluate the use of node_object_prepare().
+   */
+  protected function entityLoad(FeedsSource $source, $nid) {
+
+    $node = relation_load($nid);
+
+    if ($this->config['update_existing'] != FEEDS_UPDATE_EXISTING) {
+      $node->uid = $this->config['author'];
+    }
+
+    /* node_object_prepare($node);
+
+    // Workaround for issue #1247506. See #1245094 for backstory.
+    if (!empty($node->menu)) {
+    // If the node has a menu item(with a valid mlid) it must be flagged
+    // 'enabled'.
+    $node->menu['enabled'] = (int) (bool) $node->menu['mlid'];
+    }
+    */
+    // Populate properties that are set by node_object_prepare().
+    if ($this->config['update_existing'] == FEEDS_UPDATE_EXISTING) {
+      $node->log = 'Updated by FeedsNodeProcessor';
+    }
+    else {
+      $node->log = 'Replaced by FeedsNodeProcessor';
+    }
+    return $node;
+  }
+
+  /**
+   * Check that the user has permission to save a node.
+   */
+  protected function entitySaveAccess($entity) {
+
+    // The check will be skipped for anonymous nodes.
+    if ($this->config['authorize'] && !empty($entity->uid)) {
+
+      $author = user_load($entity->uid);
+
+      // If the uid was mapped directly, rather than by email or username, it
+      // could be invalid.
+      if (!$author) {
+        $message = 'User %uid is not a valid user.';
+        throw new FeedsAccessException(t($message, array('%uid' => $entity->uid)));
+      }
+
+      if (empty($entity->nid) || !empty($entity->is_new)) {
+        $op = 'create';
+        $access = node_access($op, $entity->type, $author);
+      }
+      else {
+        $op = 'update';
+        $access = node_access($op, $entity, $author);
+      }
+
+      if (!$access) {
+        $message = 'User %name is not authorized to %op content type %content_type.';
+        throw new FeedsAccessException(t($message, array('%name' => $author->name, '%op' => $op, '%content_type' => $entity->type)));
+      }
+    }
+  }
+
+  /**
+   * Validates a node.
+   */
+  protected function entityValidate($entity) {
+    if (!isset($entity->uid) || !is_numeric($entity->uid)) {
+      $entity->uid = $this->config['author'];
+    }
+  }
+  /**
+   * Save a node.
+   */
+  public function entitySave($entity) {
+    relation_save($entity);
+  }
+
+  /**
+   * Delete a series of nodes.
+   */
+  protected function entityDeleteMultiple($nids) {
+    relation_delete_multiple($nids);
+  }
+
+  /**
+   * Implement expire().
+   *
+   * @todo: move to processor stage?
+   */
+  public function expire($time = NULL) {
+    if ($time === NULL) {
+      $time = $this->expiryTime();
+    }
+    if ($time == FEEDS_EXPIRE_NEVER) {
+      return;
+    }
+    $count = $this->getLimit();
+    $nodes = db_query_range("SELECT n.nid FROM {node} n JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id WHERE fi.id = :id AND n.created < :created", 0, $count, array(':id' => $this->id, ':created' => REQUEST_TIME - $time));
+    $nids = array();
+    foreach ($nodes as $node) {
+      $nids[$node->nid] = $node->nid;
+    }
+    $this->entityDeleteMultiple($nids);
+    if (db_query_range("SELECT 1 FROM {node} n JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id WHERE fi.id = :id AND n.created < :created", 0, 1, array(':id' => $this->id, ':created' => REQUEST_TIME - $time))->fetchField()) {
+      return FEEDS_BATCH_ACTIVE;
+    }
+    return FEEDS_BATCH_COMPLETE;
+  }
+
+  /**
+   * Return expiry time.
+   */
+  public function expiryTime() {
+    return $this->config['expire'];
+  }
+
+  /**
+   * Override parent::configDefaults().
+   */
+  public function configDefaults() {
+    return array(
+        'expire' => FEEDS_EXPIRE_NEVER,
+        'author' => 0,
+        'authorize' => TRUE,
+    ) + parent::configDefaults();
+  }
+
+  /**
+   * Override parent::configForm().
+   */
+  public function configForm(&$form_state) {
+    $form = parent::configForm($form_state);
+
+    $author = user_load($this->config['author']);
+    $form['author'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Author'),
+        '#description' => t('Select the author of the nodes to be created - leave empty to assign "anonymous".'),
+        '#autocomplete_path' => 'user/autocomplete',
+        '#default_value' => empty($author->name) ?  'anonymous' : check_plain($author->name),
+    );
+    $form['authorize'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Authorize'),
+        '#description' => t('Check that the author has permission to create the node.'),
+        '#default_value' => $this->config['authorize'],
+    );
+    $period = drupal_map_assoc(array(FEEDS_EXPIRE_NEVER, 3600, 10800, 21600, 43200, 86400, 259200, 604800, 2592000, 2592000 * 3, 2592000 * 6, 31536000), 'feeds_format_expire');
+    $form['expire'] = array(
+        '#type' => 'select',
+        '#title' => t('Expire nodes'),
+        '#options' => $period,
+        '#description' => t('Select after how much time nodes should be deleted. The node\'s published date will be used for determining the node\'s age, see Mapping settings.'),
+        '#default_value' => $this->config['expire'],
+    );
+    return $form;
+  }
+
+  /**
+   * Override parent::configFormValidate().
+   */
+  public function configFormValidate(&$values) {
+    if ($author = user_load_by_name($values['author'])) {
+      $values['author'] = $author->uid;
+    }
+    else {
+      $values['author'] = 0;
+    }
+  }
+
+  /**
+   * Reschedule if expiry time changes.
+   */
+  public function configFormSubmit(&$values) {
+    if ($this->config['expire'] != $values['expire']) {
+      feeds_reschedule($this->id);
+    }
+    parent::configFormSubmit($values);
+  }
+
+  /**
+   * Override setTargetElement to operate on a target item that is a node.
+   */
+  public function setTargetElement(FeedsSource $source, $target_node, $target_element, $value) {
+    switch ($target_element) {
+      case 'created':
+        $target_node->created = feeds_to_unixtime($value, REQUEST_TIME);
+        break;
+      case 'feeds_source':
+        // Get the class of the feed node importer's fetcher and set the source
+        // property. See feeds_node_update() how $node->feeds gets stored.
+        if ($id = feeds_get_importer_id($this->bundle())) {
+          $class = get_class(feeds_importer($id)->fetcher);
+          $target_node->feeds[$class]['source'] = $value;
+          // This effectively suppresses 'import on submission' feature.
+          // See feeds_node_insert().
+          $target_node->feeds['suppress_import'] = TRUE;
+        }
+        break;
+      case 'user_name':
+        if ($user = user_load_by_name($value)) {
+          $target_node->uid = $user->uid;
+        }
+        break;
+      case 'user_mail':
+        if ($user = user_load_by_mail($value)) {
+          $target_node->uid = $user->uid;
+        }
+        break;
+      default:
+        parent::setTargetElement($source, $target_node, $target_element, $value);
+        break;
+    }
+  }
+
+  /**
+   * Return available mapping targets.
+   */
+  public function getMappingTargets() {
+    $type = relation_type_load($this->bundle());
+
+    $targets = parent::getMappingTargets();
+
+    $targets['source_id'] = array(
+        'name' => t('Source Field'),
+        'description' => t('Source.'),
+        'optional_unique' => FALSE,
+    );
+
+    $targets['target_id'] = array(
+        'name' => t('Target Field'),
+        'description' => t('Target.'),
+        'optional_unique' => FALSE,
+    );
+
+
+    $targets['relation_name'] = array(
+        'name' => t('Relation type'),
+        'description' => t('Target.'),
+        'optional_unique' => FALSE,
+    );
+
+
+    $targets['nid'] = array(
+        'name' => t('Node ID'),
+        'description' => t('The nid of the node. NOTE: use this feature with care, node ids are usually assigned by Drupal.'),
+        'optional_unique' => TRUE,
+    );
+    $targets['uid'] = array(
+        'name' => t('User ID'),
+        'description' => t('The Drupal user ID of the node author.'),
+    );
+    $targets['user_name'] = array(
+        'name' => t('Username'),
+        'description' => t('The Drupal username of the node author.'),
+    );
+    $targets['user_mail'] = array(
+        'name' => t('User email'),
+        'description' => t('The email address of the node author.'),
+    );
+    $targets['status'] = array(
+        'name' => t('Published status'),
+        'description' => t('Whether a node is published or not. 1 stands for published, 0 for not published.'),
+    );
+    $targets['created'] = array(
+        'name' => t('Published date'),
+        'description' => t('The UNIX time when a node has been published.'),
+    );
+
+    // Include language field if Locale module is enabled.
+    if (module_exists('locale')) {
+      $targets['language'] = array(
+          'name' => t('Language'),
+          'description' => t('The two-character language code of the node.'),
+      );
+    }
+
+
+    // If the target content type is a Feed node, expose its source field.
+    if ($id = feeds_get_importer_id($this->bundle())) {
+      $name = feeds_importer($id)->config['name'];
+      $targets['feeds_source'] = array(
+          'name' => t('Feed source'),
+          'description' => t('The content type created by this processor is a Feed Node, it represents a source itself. Depending on the fetcher selected on the importer "@importer", this field is expected to be for example a URL or a path to a file.', array('@importer' => $name)),
+          'optional_unique' => TRUE,
+      );
+    }
+
+    // Let other modules expose mapping targets.
+    self::loadMappers();
+
+    // load nodes mapper
+    require_once("nodes.inc");
+    //$entity_type = $this->entityType();
+    $entity_type = "relation";
+    $bundle = $this->bundle();
+    drupal_alter('feeds_processor_targets', $targets, $entity_type, $bundle);
+
+    return $targets;
+  }
+
+  /**
+   * Get nid of an existing feed item node if available.
+   */
+  protected function existingEntityId(FeedsSource $source, FeedsParserResult $result) {
+    if ($nid = parent::existingEntityId($source, $result)) {
+      return $nid;
+    }
+
+    // Iterate through all unique targets and test whether they do already
+    // exist in the database.
+    foreach ($this->uniqueTargets($source, $result) as $target => $value) {
+      switch ($target) {
+        case 'nid':
+          $nid = db_query("SELECT rid FROM {relation} WHERE rid = :rid", array(':rid' => $value))->fetchField();
+          break;
+        case 'title':
+          $nid = db_query("SELECT rid FROM {relation} WHERE title = :title AND type = :type", array(':title' => $value, ':type' => $this->bundle()))->fetchField();
+          break;
+        case 'feeds_source':
+          if ($id = feeds_get_importer_id($this->bundle())) {
+            $nid = db_query("SELECT fs.feed_nid FROM {relation} n JOIN {feeds_source} fs ON n.rid = fs.feed_nid WHERE fs.id = :id AND fs.source = :source", array(':id' => $id, ':source' => $value))->fetchField();
+          }
+          break;
+      }
+      if ($nid) {
+        // Return with the first nid found.
+        return $nid;
+      }
+    }
+    return 0;
+  }
+
+
+  /**
+   * Provides a list of bundle options for use in select lists.
+   *
+   * @return array
+   *   A keyed array of bundle => label.
+   */
+  public function bundleOptions() {
+    $options = array();
+
+    $options = relation_get_types_options();
+    return $options;
+
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relation_processor/FeedsRelationProcessor.inc~	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,413 @@
+<?php
+
+/**
+ * @file
+ * Class definition of FeedsNodeProcessor.
+ */
+
+/**
+ * Creates nodes from feed items.
+ */
+class FeedsRelationProcessor extends FeedsProcessor {
+
+  /**
+   * Define entity type.
+   */
+  public function entityType() {
+    return 'relation';
+  }
+
+  /**
+   * Implements parent::entityInfo().
+   */
+  protected function entityInfo() {
+    $info = parent::entityInfo();
+    $info['label plural'] = t('Relations');
+    return $info;
+  }
+
+  /**
+   * Creates a new node in memory and returns it.
+   */
+  protected function newEntity(FeedsSource $source) {
+    /*$node = new stdClass();
+     $node->type = $this->bundle();
+    $node->changed = REQUEST_TIME;
+    $node->created = REQUEST_TIME;
+    $node->language = LANGUAGE_NONE;
+    $node->is_new = TRUE;
+    node_object_prepare($node);
+    // Populate properties that are set by node_object_prepare().
+    $node->log = 'Created by FeedsNodeProcessor';
+    $node->uid = $this->config['author'];
+    */
+
+
+    $relation = new stdClass();
+    $relation->is_new = TRUE;
+    dpm($this->bundle());
+    $relation->relation_type = $this->bundle();
+    $relation->uid = $this->config['author'];
+    $relation->endpoints[LANGUAGE_NONE] = Null;
+
+    $relation->changed = REQUEST_TIME;
+    $relation->created = REQUEST_TIME;
+
+    return $relation;
+
+  }
+
+  /**
+   * Loads an existing node.
+   *
+   * If the update existing method is not FEEDS_UPDATE_EXISTING, only the node
+   * table will be loaded, foregoing the node_load API for better performance.
+   *
+   * @todo Reevaluate the use of node_object_prepare().
+   */
+  protected function entityLoad(FeedsSource $source, $nid) {
+
+    $node = relation_load($nid);
+
+    if ($this->config['update_existing'] != FEEDS_UPDATE_EXISTING) {
+      $node->uid = $this->config['author'];
+    }
+
+    /* node_object_prepare($node);
+
+    // Workaround for issue #1247506. See #1245094 for backstory.
+    if (!empty($node->menu)) {
+    // If the node has a menu item(with a valid mlid) it must be flagged
+    // 'enabled'.
+    $node->menu['enabled'] = (int) (bool) $node->menu['mlid'];
+    }
+    */
+    // Populate properties that are set by node_object_prepare().
+    if ($this->config['update_existing'] == FEEDS_UPDATE_EXISTING) {
+      $node->log = 'Updated by FeedsNodeProcessor';
+    }
+    else {
+      $node->log = 'Replaced by FeedsNodeProcessor';
+    }
+    return $node;
+  }
+
+  /**
+   * Check that the user has permission to save a node.
+   */
+  protected function entitySaveAccess($entity) {
+
+    // The check will be skipped for anonymous nodes.
+    if ($this->config['authorize'] && !empty($entity->uid)) {
+
+      $author = user_load($entity->uid);
+
+      // If the uid was mapped directly, rather than by email or username, it
+      // could be invalid.
+      if (!$author) {
+        $message = 'User %uid is not a valid user.';
+        throw new FeedsAccessException(t($message, array('%uid' => $entity->uid)));
+      }
+
+      if (empty($entity->nid) || !empty($entity->is_new)) {
+        $op = 'create';
+        $access = node_access($op, $entity->type, $author);
+      }
+      else {
+        $op = 'update';
+        $access = node_access($op, $entity, $author);
+      }
+
+      if (!$access) {
+        $message = 'User %name is not authorized to %op content type %content_type.';
+        throw new FeedsAccessException(t($message, array('%name' => $author->name, '%op' => $op, '%content_type' => $entity->type)));
+      }
+    }
+  }
+
+  /**
+   * Validates a node.
+   */
+  protected function entityValidate($entity) {
+    if (!isset($entity->uid) || !is_numeric($entity->uid)) {
+      $entity->uid = $this->config['author'];
+    }
+  }
+  /**
+   * Save a node.
+   */
+  public function entitySave($entity) {
+    relation_save($entity);
+  }
+
+  /**
+   * Delete a series of nodes.
+   */
+  protected function entityDeleteMultiple($nids) {
+    relation_delete_multiple($nids);
+  }
+
+  /**
+   * Implement expire().
+   *
+   * @todo: move to processor stage?
+   */
+  public function expire($time = NULL) {
+    if ($time === NULL) {
+      $time = $this->expiryTime();
+    }
+    if ($time == FEEDS_EXPIRE_NEVER) {
+      return;
+    }
+    $count = $this->getLimit();
+    $nodes = db_query_range("SELECT n.nid FROM {node} n JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id WHERE fi.id = :id AND n.created < :created", 0, $count, array(':id' => $this->id, ':created' => REQUEST_TIME - $time));
+    $nids = array();
+    foreach ($nodes as $node) {
+      $nids[$node->nid] = $node->nid;
+    }
+    $this->entityDeleteMultiple($nids);
+    if (db_query_range("SELECT 1 FROM {node} n JOIN {feeds_item} fi ON fi.entity_type = 'node' AND n.nid = fi.entity_id WHERE fi.id = :id AND n.created < :created", 0, 1, array(':id' => $this->id, ':created' => REQUEST_TIME - $time))->fetchField()) {
+      return FEEDS_BATCH_ACTIVE;
+    }
+    return FEEDS_BATCH_COMPLETE;
+  }
+
+  /**
+   * Return expiry time.
+   */
+  public function expiryTime() {
+    return $this->config['expire'];
+  }
+
+  /**
+   * Override parent::configDefaults().
+   */
+  public function configDefaults() {
+    return array(
+        'expire' => FEEDS_EXPIRE_NEVER,
+        'author' => 0,
+        'authorize' => TRUE,
+    ) + parent::configDefaults();
+  }
+
+  /**
+   * Override parent::configForm().
+   */
+  public function configForm(&$form_state) {
+    $form = parent::configForm($form_state);
+
+    $author = user_load($this->config['author']);
+    $form['author'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Author'),
+        '#description' => t('Select the author of the nodes to be created - leave empty to assign "anonymous".'),
+        '#autocomplete_path' => 'user/autocomplete',
+        '#default_value' => empty($author->name) ?  'anonymous' : check_plain($author->name),
+    );
+    $form['authorize'] = array(
+        '#type' => 'checkbox',
+        '#title' => t('Authorize'),
+        '#description' => t('Check that the author has permission to create the node.'),
+        '#default_value' => $this->config['authorize'],
+    );
+    $period = drupal_map_assoc(array(FEEDS_EXPIRE_NEVER, 3600, 10800, 21600, 43200, 86400, 259200, 604800, 2592000, 2592000 * 3, 2592000 * 6, 31536000), 'feeds_format_expire');
+    $form['expire'] = array(
+        '#type' => 'select',
+        '#title' => t('Expire nodes'),
+        '#options' => $period,
+        '#description' => t('Select after how much time nodes should be deleted. The node\'s published date will be used for determining the node\'s age, see Mapping settings.'),
+        '#default_value' => $this->config['expire'],
+    );
+    return $form;
+  }
+
+  /**
+   * Override parent::configFormValidate().
+   */
+  public function configFormValidate(&$values) {
+    if ($author = user_load_by_name($values['author'])) {
+      $values['author'] = $author->uid;
+    }
+    else {
+      $values['author'] = 0;
+    }
+  }
+
+  /**
+   * Reschedule if expiry time changes.
+   */
+  public function configFormSubmit(&$values) {
+    if ($this->config['expire'] != $values['expire']) {
+      feeds_reschedule($this->id);
+    }
+    parent::configFormSubmit($values);
+  }
+
+  /**
+   * Override setTargetElement to operate on a target item that is a node.
+   */
+  public function setTargetElement(FeedsSource $source, $target_node, $target_element, $value) {
+    switch ($target_element) {
+      case 'created':
+        $target_node->created = feeds_to_unixtime($value, REQUEST_TIME);
+        break;
+      case 'feeds_source':
+        // Get the class of the feed node importer's fetcher and set the source
+        // property. See feeds_node_update() how $node->feeds gets stored.
+        if ($id = feeds_get_importer_id($this->bundle())) {
+          $class = get_class(feeds_importer($id)->fetcher);
+          $target_node->feeds[$class]['source'] = $value;
+          // This effectively suppresses 'import on submission' feature.
+          // See feeds_node_insert().
+          $target_node->feeds['suppress_import'] = TRUE;
+        }
+        break;
+      case 'user_name':
+        if ($user = user_load_by_name($value)) {
+          $target_node->uid = $user->uid;
+        }
+        break;
+      case 'user_mail':
+        if ($user = user_load_by_mail($value)) {
+          $target_node->uid = $user->uid;
+        }
+        break;
+      default:
+        parent::setTargetElement($source, $target_node, $target_element, $value);
+        break;
+    }
+  }
+
+  /**
+   * Return available mapping targets.
+   */
+  public function getMappingTargets() {
+    $type = relation_type_load($this->bundle());
+
+    $targets = parent::getMappingTargets();
+
+    $targets['source_id'] = array(
+        'name' => t('Source Field'),
+        'description' => t('Source.'),
+        'optional_unique' => FALSE,
+    );
+
+    $targets['target_id'] = array(
+        'name' => t('Target Field'),
+        'description' => t('Target.'),
+        'optional_unique' => FALSE,
+    );
+
+
+    $targets['relation_name'] = array(
+        'name' => t('Relation type'),
+        'description' => t('Target.'),
+        'optional_unique' => FALSE,
+    );
+
+
+    $targets['nid'] = array(
+        'name' => t('Node ID'),
+        'description' => t('The nid of the node. NOTE: use this feature with care, node ids are usually assigned by Drupal.'),
+        'optional_unique' => TRUE,
+    );
+    $targets['uid'] = array(
+        'name' => t('User ID'),
+        'description' => t('The Drupal user ID of the node author.'),
+    );
+    $targets['user_name'] = array(
+        'name' => t('Username'),
+        'description' => t('The Drupal username of the node author.'),
+    );
+    $targets['user_mail'] = array(
+        'name' => t('User email'),
+        'description' => t('The email address of the node author.'),
+    );
+    $targets['status'] = array(
+        'name' => t('Published status'),
+        'description' => t('Whether a node is published or not. 1 stands for published, 0 for not published.'),
+    );
+    $targets['created'] = array(
+        'name' => t('Published date'),
+        'description' => t('The UNIX time when a node has been published.'),
+    );
+
+    // Include language field if Locale module is enabled.
+    if (module_exists('locale')) {
+      $targets['language'] = array(
+          'name' => t('Language'),
+          'description' => t('The two-character language code of the node.'),
+      );
+    }
+
+
+    // If the target content type is a Feed node, expose its source field.
+    if ($id = feeds_get_importer_id($this->bundle())) {
+      $name = feeds_importer($id)->config['name'];
+      $targets['feeds_source'] = array(
+          'name' => t('Feed source'),
+          'description' => t('The content type created by this processor is a Feed Node, it represents a source itself. Depending on the fetcher selected on the importer "@importer", this field is expected to be for example a URL or a path to a file.', array('@importer' => $name)),
+          'optional_unique' => TRUE,
+      );
+    }
+
+    // Let other modules expose mapping targets.
+    self::loadMappers();
+
+    // load nodes mapper
+    require_once("nodes.inc");
+    //$entity_type = $this->entityType();
+    $entity_type = "relation";
+    $bundle = $this->bundle();
+    drupal_alter('feeds_processor_targets', $targets, $entity_type, $bundle);
+
+    return $targets;
+  }
+
+  /**
+   * Get nid of an existing feed item node if available.
+   */
+  protected function existingEntityId(FeedsSource $source, FeedsParserResult $result) {
+    if ($nid = parent::existingEntityId($source, $result)) {
+      return $nid;
+    }
+
+    // Iterate through all unique targets and test whether they do already
+    // exist in the database.
+    foreach ($this->uniqueTargets($source, $result) as $target => $value) {
+      switch ($target) {
+        case 'nid':
+          $nid = db_query("SELECT rid FROM {relation} WHERE rid = :rid", array(':rid' => $value))->fetchField();
+          break;
+        case 'title':
+          $nid = db_query("SELECT rid FROM {relation} WHERE title = :title AND type = :type", array(':title' => $value, ':type' => $this->bundle()))->fetchField();
+          break;
+        case 'feeds_source':
+          if ($id = feeds_get_importer_id($this->bundle())) {
+            $nid = db_query("SELECT fs.feed_nid FROM {relation} n JOIN {feeds_source} fs ON n.rid = fs.feed_nid WHERE fs.id = :id AND fs.source = :source", array(':id' => $id, ':source' => $value))->fetchField();
+          }
+          break;
+      }
+      if ($nid) {
+        // Return with the first nid found.
+        return $nid;
+      }
+    }
+    return 0;
+  }
+
+
+  /**
+   * Provides a list of bundle options for use in select lists.
+   *
+   * @return array
+   *   A keyed array of bundle => label.
+   */
+  public function bundleOptions() {
+    $options = array();
+
+    $options = relation_get_types_options();
+    return $options;
+
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relation_processor/nodes.inc	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,424 @@
+<?php
+
+/**
+ * @file
+ * On behalf implementation of Feeds mapping API for taxonomy.module.
+ */
+
+/**
+ * Search by term name.
+ */
+define('FEEDS_ENTITY_SEARCH_TERM_NAME', 0);
+
+/**
+ * Search by term id.
+ */
+define('FEEDS_ENTITY_SEARCH_TERM_ID', 1);
+
+/**
+ * Search by GUID.
+ */
+define('FEEDS_ENTITY_SEARCH_TERM_GUID', 2);
+
+
+/**
+ * Search by CITEKEY.
+ */
+define('FEEDS_ENTITY_SEARCH_TERM_CITEKEY', 3);
+
+/**
+ * Implements hook_feeds_parser_sources_alter().
+ */
+function entity_feeds_parser_sources_alter(&$sources, $content_type) {
+
+  if (!empty($content_type)) {
+      $sources['sources'] = array(
+        'name' => t('Feed node: Entity'),
+        'description' => t('Entites  from feed node.'),
+        'callback' => 'entites_feeds_get_source',
+      );
+    }
+  }
+
+
+/**
+ * Callback, returns taxonomy from feed node.
+ */
+function entity_feeds_get_source(FeedsSource $source, FeedsParserResult $result, $key) {
+  /*if ($node = node_load($source->feed_nid)) {
+    $terms = taxonomy_feeds_node_get_terms($node);
+    $vocabularies = taxonomy_vocabulary_load_multiple(array(), array('machine_name' => str_replace('parent:taxonomy:', '', $key)));
+    $vocabulary = array_shift($vocabularies);
+    $result = array();
+    foreach ($terms as $tid => $term) {
+      if ($term->vid == $vocabulary->vid) {
+        $result[] = new FeedsTermElement($term);
+      }
+    }*/
+
+    return $result;
+  //}
+}
+
+/**
+ * Implements hook_feeds_processor_targets_alter().
+ */
+function entity_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_name) {
+  /*foreach (field_info_instances($entity_type, $bundle_name) as $name => $instance) {
+    $info = field_info_field($name);
+    if ($info['type'] == 'taxonomy_term_reference') {
+      $targets[$name] = array(
+        'name' => check_plain($instance['label']),
+        'callback' => 'taxonomy_feeds_set_target',
+        'description' => t('The @label field of the entity.', array('@label' => $instance['label'])),
+        'summary_callback' => 'taxonomy_feeds_summary_callback',
+        'form_callback' => 'taxonomy_feeds_form_callback',
+      );
+    }
+  }*/
+
+
+  if ($entity_type == "relation"){
+
+    $targets["source_id"]=  array(
+        'name' => 'Source Field',
+        'callback' => 'entity_feeds_set_target',
+        'description' => t('The guid of the entity.'),
+        'summary_callback' => 'entity_feeds_summary_callback',
+        'form_callback' => 'entity_feeds_form_callback',
+      );
+
+    $targets["target_id"]=  array(
+        'name' => 'Target Field',
+        'callback' => 'entity_feeds_set_target',
+        'description' => t('The guid of the entity.'),
+        'summary_callback' => 'entity_feeds_summary_callback',
+        'form_callback' => 'entity_feeds_form_callback',
+    );
+
+    $targets["relation_name"]=  array(
+        'name' => 'Relation Type',
+        'callback' => 'entity_feeds_set_relation_type',
+
+    );
+
+  }
+
+}
+
+
+
+/*callback for relation_types
+ *
+ *
+ */
+function entity_feeds_set_relation_type($source, $entity, $target, $terms, $mapping = array()) {
+
+  if (empty($terms)) {
+    return;
+  }
+
+  // don't Handle non-multiple values.
+  if (is_array($terms)) {
+    return;
+  }
+
+
+  $types=relation_get_types(array($terms));
+
+  if(sizeof($types)==0){ //typ gibt es nicht dann erzeuge mit defualt werten #TODO konfigurierbar?
+    dpm("CREATE RELATION TYPE:" . $terms);
+    $info = array();
+    $info['relation_type']=$terms;
+    $info['directional']=TRUE;
+    $info['source_bundles'][]="node:*";
+    $info['target_bundles'][]="node:*";
+    $info['reverse_label']="invOf_" . $terms;
+    $rel_type = relation_type_create($info);
+    relation_type_save($rel_type);
+  }
+
+  $entity->relation_type=$terms;
+  relation_update($entity);
+}
+
+/**
+ * Callback for mapping. Here is where the actual mapping happens.
+ *
+ * @todo Do not create new terms for non-autotag fields.
+ */
+function entity_feeds_set_target($source, $entity, $target, $terms, $mapping = array()) {
+
+  // Allow mapping the string '0' to a term name.
+  if (empty($terms) && $terms != 0) {
+    return;
+  }
+
+  // Handle non-multiple values.
+  if (!is_array($terms)) {
+    $terms = array($terms);
+  }
+
+  // Add in default values.
+  $mapping += array(
+    'term_search' => FEEDS_ENTITY_SEARCH_TERM_NAME,
+    'autocreate' => FALSE,
+  );
+
+
+  $cache = &drupal_static(__FUNCTION__);
+
+
+  //$query = new EntityFieldQuery();
+  //$query->entityCondition('entity_type', 'node')
+  //  ->range(0, 1);
+
+
+
+
+
+
+  // Iterate over all values.
+
+
+  #$mapping['term_search']=FEEDS_ENTITY_SEARCH_TERM_GUID;
+  foreach ($terms as $term) {
+  //dpm($term);
+
+
+    $tid = FALSE;
+
+    switch ($mapping['term_search']){
+        // Lookup by name.
+        case FEEDS_ENTITY_SEARCH_TERM_NAME:
+          $name_query = clone $query;
+          if ($tids = $name_query->propertyCondition('name', $term)->execute()) {
+            $tid = key($tids['taxonomy_term']);
+          }
+
+        // Lookup by tid.
+        case FEEDS_ENTITY_SEARCH_TERM_ID:
+          if (is_numeric($term)) {
+            $tid = $term;
+          }
+          break;
+
+        // Lookup by GUID.
+        case FEEDS_ENTITY_SEARCH_TERM_GUID:
+
+          $tid = entity_feeds_entity_lookup_entity_by_guid($term);
+
+          break;
+
+        case FEEDS_ENTITY_SEARCH_TERM_CITEKEY:
+          $tid = _searchEntityByBiblioValue("biblio","citekey",$term);
+    }
+  }
+
+
+  $eps = $entity->endpoints[LANGUAGE_NONE];
+  if (!isset($entity->endpoints[LANGUAGE_NONE])){ // noch nicht existent
+    $entity->endpoints[LANGUAGE_NONE][]=array();
+  } else if  (sizeof($entity->endpoints[LANGUAGE_NONE])<1) { // nicht mindestens ein eintrag
+    $entity->endpoints[LANGUAGE_NONE][]=array();
+  }
+
+  switch ($target){
+    case "source_id":
+      // source is immer der erste eintrag
+      $entity->endpoints[LANGUAGE_NONE][0]=array('entity_type' => 'node', 'entity_id' => $tid);
+      break;
+
+    case "target_id":
+      //target können mehrere existieren, hinten anfügen.
+      $entity->endpoints[LANGUAGE_NONE][]=array('entity_type' => 'node', 'entity_id' => $tid);
+  }
+
+  //dpm($entity);
+
+
+  //if ($target=="target_id"){
+   relation_update($entity);
+
+
+   if  (sizeof($entity->endpoints[LANGUAGE_NONE])>1){ // WENN ZWEI ENDPUNKTE VORHANDEN DANN abspeichern
+   $entity->is_new=FALSE;
+
+   }
+ // }
+}
+
+/**
+ * Finds all terms associated with the given node, within one vocabulary.
+ */
+
+/*
+function taxonomy_feeds_node_get_terms($node, $key = 'tid') {
+  $terms = &drupal_static(__FUNCTION__);
+
+  if (!isset($terms[$node->nid][$key])) {
+    // Get tids from all taxonomy_term_reference fields.
+    $tids = array();
+    $fields = field_info_fields();
+    foreach ($fields as $field_name => $field) {
+      if ($field['type'] == 'taxonomy_term_reference' && field_info_instance('node', $field_name, $node->type)) {
+        if (($items = field_get_items('node', $node, $field_name)) && is_array($items)) {
+          $tids = array_merge($tids, array_map('_taxonomy_feeds_extract_tid', $items));
+        }
+      }
+    }
+
+    // Load terms and cache them in static var.
+    $curr_terms = taxonomy_term_load_multiple($tids);
+    $terms[$node->nid][$key] = array();
+    foreach ($curr_terms as $term) {
+      $terms[$node->nid][$key][$term->$key] = $term;
+    }
+  }
+  return $terms[$node->nid][$key];
+}
+
+*/
+
+/**
+ * Extracts tid from array item returned by field_get_items().
+ *
+ * @param array $item
+ *   Tid information in the form of a single element array
+ *   (key == 'tid', value == tid we're looking for)
+ *
+ * @return int
+ *   Term id extracted from $item.
+ *
+ * @see taxonomy_feeds_node_get_terms()
+ * @see field_get_items()
+ */
+function _entity_feeds_extract_tid($item) {
+  return $item['tid'];
+}
+
+/**
+ * Looks up a term by GUID, assumes SQL storage backend.
+ *
+ * @param string $guid
+ *   The Feeds GUID to compare against.
+ *
+ * @return int|FALSE
+ *   The term id, or FALSE if one was not found.
+ */
+function entity_feeds_entity_lookup_entity_by_guid($guid) {
+
+
+  $res = db_select('feeds_item')
+  ->fields('feeds_item', array('entity_id'))
+  //->condition('feed_nid', $source->feed_nid)
+  //->condition('entity_type', $this->entityType())
+  //->condition('id', $source->id);
+  ->condition('guid', $guid)
+  ->execute()
+  ->fetchField();
+
+
+  return $res;
+ /* return db_select('feeds_item')
+    ->fields('feeds_item', array('entity_id'))
+    ->condition('entity_type', 'taxonomy_term')
+    ->condition('guid', $guid)
+    ->execute()
+    ->fetchField();*/
+}
+
+/**
+ * Mapping configuration summary for taxonomy.module.
+ *
+ * @param array $mapping
+ *   Associative array of the mapping settings.
+ * @param array $target
+ *   Array of target settings, as defined by the processor or
+ *   hook_feeds_processor_targets_alter().
+ * @param array $form
+ *   The whole mapping form.
+ * @param array $form_state
+ *   The form state of the mapping form.
+ *
+ * @return string
+ *   Returns, as a string that may contain HTML, the summary to display while
+ *   the full form isn't visible.
+ *   If the return value is empty, no summary and no option to view the form
+ *   will be displayed.
+ */
+function entity_feeds_summary_callback($mapping, $target, $form, $form_state) {
+  $options = _entity_feeds_form_callback_options();
+  if (empty($mapping['term_search'])) {
+    return t('Search Entity terms by: <strong>@search</strong>', array('@search' => $options[FEEDS_ENTITY_SEARCH_TERM_NAME]));
+  }
+  return t('Search Entity terms by: <strong>@search</strong>', array('@search' => $options[$mapping['term_search']]));
+}
+
+/**
+ * Settings form callback.
+ *
+ * @return array
+ *   The per mapping configuration form. Once the form is saved, $mapping will
+ *   be populated with the form values.
+ */
+function entity_feeds_form_callback($mapping, $target, $form, $form_state) {
+  return array(
+    'term_search' => array(
+      '#type' => 'select',
+      '#title' => t('Search Entity  by'),
+      '#options' => _entity_feeds_form_callback_options(),
+      '#default_value' => !empty($mapping['term_search']) ? $mapping['term_search'] : FEEDS_ENTITY_SEARCH_TERM_NAME,
+    ),
+  );
+}
+
+/**
+ * Returns the list of available term search methods.
+ *
+ * @return array
+ *   An array of taxonomy search option titles.
+ */
+function _entity_feeds_form_callback_options() {
+  return array(
+    FEEDS_ENTITY_SEARCH_TERM_NAME => 'Entity name',
+    FEEDS_ENTITY_SEARCH_TERM_ID => 'Entity ID',
+    FEEDS_ENTITY_SEARCH_TERM_GUID => 'GUID',
+    FEEDS_ENTITY_SEARCH_TERM_CITEKEY => 'CITEKEY'
+  );
+}
+
+
+
+/* sucht nach entity vom typ mit Wert von Feld (fieldname) = term */
+function _searchEntityByBiblioValue($bundle,$fieldName,$term){
+
+  $fc = module_load_include('inc', 'biblio', 'includes/biblio.pages');
+  if ($fc==FALSE){
+  dpm("FEHLER: cann't find biblio module!");
+  return;
+  }
+  $arglist = array (
+     "f" => array( $fieldName => $term)
+  );
+  $res = biblio_build_query($arglist);
+  $nid = $res[0][0];
+
+
+  return $nid;
+}
+
+function _searchEntityByFieldValue($bundle,$fieldName,$term){
+
+  $query = new EntityFieldQuery();
+  $query->entityCondition('entity_type', 'node')
+  ->entityCondition('bundle', $bundle)
+  ->fieldCondition($fieldName, 'value',$term, '=');
+
+  $result = $query->execute();
+  if (isset($result['node'])) {
+    $news_items_nids = array_keys($result['node']);
+    $news_items = entity_load('node', $news_items_nids);
+    return $news_items[0];
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relation_processor/relation_processor.info	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,9 @@
+name = relation_processor
+description = Processes relaitons
+package = Feeds
+core = 7.x
+dependencies[] = ctools
+dependencies[] = job_scheduler
+
+files[] = FeedsRelationProcessor.inc
+files[] = relation_processor.module
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relation_processor/relation_processor.module	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * Implements hook_feeds_plugins().
+ */
+function relation_processor_feeds_plugins() {
+  $path = drupal_get_path('module', 'relation_processor');
+
+  $info = array();
+  $info['FeedsRelationProcessor'] = array(
+      'name' => 'Relation processor',
+      'description' => 'Create and update relations.',
+      'help' => 'Create and update relations from parsed content.',
+      'handler' => array(
+          'parent' => 'FeedsProcessor',
+          'class' => 'FeedsRelationProcessor',
+          'file' => 'FeedsRelationProcessor.inc',
+          'path' => $path,
+      ),
+  );
+
+  return $info;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/transformBEA/.project	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>transformBEA</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.python.pydev.PyDevBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.python.pydev.pythonNature</nature>
+	</natures>
+</projectDescription>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/transformBEA/.pydevproject	Fri Mar 27 19:21:42 2015 +0100
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?eclipse-pydev version="1.0"?><pydev_project>
+<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
+<path>/${PROJECT_DIR_NAME}</path>
+</pydev_pathproperty>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
+<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
+</pydev_project>