static void test_minimaltrie()
{
	printf ("Test minimal trie\n");

	Trie *trie = test_insert (0, "", "");
	Key *s = keyNew ("", KEY_END);
	Key *mp = keyNew ("", KEY_VALUE, "", KEY_END);

	succeed_if (elektraTrieLookup (trie, s), "trie should not be null");
	compare_key(elektraTrieLookup (trie, s)->mountpoint, mp);

	keySetName (s, "user");
	compare_key(elektraTrieLookup (trie, s)->mountpoint, mp);

	keySetName (s, "system");
	compare_key(elektraTrieLookup (trie, s)->mountpoint, mp);

	keySetName (s, "user/below");
	compare_key(elektraTrieLookup (trie, s)->mountpoint, mp);

	keySetName (s, "system/below");
	compare_key(elektraTrieLookup (trie, s)->mountpoint, mp);

	elektraTrieClose(trie, 0);
	keyDel (s);
	keyDel (mp);
}
static void test_defaultonly()
{
	printf ("Test mounting with default only\n");

	KDB *kdb = kdb_new();
	Key *errorKey = keyNew(0);
	KeySet *modules = modules_config();
	succeed_if (elektraMountOpen(kdb, minimal_config(), modules, errorKey) == 0, "could not buildup mount");
	succeed_if (elektraMountDefault(kdb, modules, errorKey) == 0, "could not mount default backend");


	// output_split (kdb->split);

	succeed_if (kdb->split->size == 4, "size of split not correct");
	Key *mp = keyNew("spec", KEY_VALUE, "default", KEY_END);
	compare_key(mp, kdb->split->parents[0]);
	keySetName(mp, "dir"); keySetString (mp, "default");
	compare_key(mp, kdb->split->parents[1]);
	keySetName(mp, "user"); keySetString (mp, "default");
	compare_key(mp, kdb->split->parents[2]);
	keySetName(mp, "system"); keySetString (mp, "default");
	compare_key(mp, kdb->split->parents[3]);

	succeed_if(output_warnings (errorKey), "warnings found");
	succeed_if(output_error (errorKey), "error found");

	succeed_if (!kdb->trie, "trie should be empty");

	Key *searchKey = keyNew("", KEY_END);
	Backend *b2 = 0;

	keySetName (searchKey, "user");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2 == 0, "should be default backend");


	keySetName(searchKey, "user/tests/simple");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2 == 0, "should be default backend");


	keySetName(searchKey, "user/tests/simple/below");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2 == 0, "should be default backend");


	keySetName(searchKey, "user/tests/simple/deep/below");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2 == 0, "should be default backend");

	keyDel (mp);

	keyDel (searchKey);

	kdb_del (kdb);
	keyDel (errorKey);
	ksDel (modules);
}
static void test_umlauts()
{
	printf ("Test umlauts trie\n");

	Trie *trie = test_insert (0, "user/umlauts/test", "slash");
	trie = test_insert (trie, "user/umlauts#test", "hash");
	trie = test_insert (trie, "user/umlauts test", "space");
	trie = test_insert (trie, "user/umlauts\200test", "umlauts");

	exit_if_fail (trie, "trie was not build up successfully");

	Key *searchKey = keyNew("user", KEY_END);
	Backend *backend = elektraTrieLookup(trie, searchKey);
	succeed_if (!backend, "there should be no backend");


	Key *mp = keyNew("user/umlauts/test", KEY_VALUE, "slash", KEY_END);
	keySetName(searchKey, "user/umlauts/test");
	backend = elektraTrieLookup(trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, mp);


	keySetName(searchKey, "user/umlauts#test");
	keySetName(mp, "user/umlauts#test");
	keySetString(mp, "hash");
	Backend *b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend != b2, "should be other backend");
	compare_key(b2->mountpoint, mp);


	keySetName(searchKey, "user/umlauts test");
	keySetName(mp, "user/umlauts test");
	keySetString(mp, "space");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend != b2, "should be other backend");
	compare_key(b2->mountpoint, mp);

	keySetName(searchKey, "user/umlauts\200test");
	keySetName(mp, "user/umlauts\200test");
	keySetString(mp, "umlauts");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend != b2, "should be other backend");
	compare_key(b2->mountpoint, mp);

	// output_trie(trie);

	elektraTrieClose(trie, 0);
	keyDel (mp);
	keyDel (searchKey);
}
static void test_us ()
{
	printf ("Test mounting of user and system backends\n");

	KDB * kdb = kdb_new ();
	KeySet * modules = ksNew (0, KS_END);
	elektraModulesInit (modules, 0);
	Key * mp;

	KeySet * config = set_us ();
	ksAppendKey (config, keyNew ("system/elektra/mountpoints", KEY_END));
	succeed_if (mountOpen (kdb, config, modules, 0) == 0, "could not open mount");
	succeed_if (mountDefault (kdb, modules, 1, 0) == 0, "could not mount default backend");

	succeed_if (kdb->split->size == 5, "size of split not correct");
	mp = keyNew ("system", KEY_VALUE, "system", KEY_END);
	compare_key (mp, kdb->split->parents[0]);
	keySetName (mp, "user");
	keySetString (mp, "user");
	compare_key (mp, kdb->split->parents[1]);
	keySetName (mp, "system/elektra");
	keySetString (mp, "default");
	compare_key (mp, kdb->split->parents[4]);
	keyDel (mp);

	Key * key = keyNew ("user/anywhere/backend/simple", KEY_END);
	Backend * backend = trieLookup (kdb->trie, key);

	keyAddBaseName (key, "somewhere");
	keyAddBaseName (key, "deep");
	keyAddBaseName (key, "below");
	Backend * backend2 = trieLookup (kdb->trie, key);
	succeed_if (backend == backend2, "should be same backend");

	succeed_if ((mp = backend->mountpoint) != 0, "no mountpoint found");
	succeed_if_same_string (keyName (mp), "user");
	succeed_if_same_string (keyString (mp), "user");


	keySetName (key, "system/anywhere/tests/backend/two");
	Backend * two = trieLookup (kdb->trie, key);
	succeed_if (two != backend, "should be differnt backend");

	succeed_if ((mp = two->mountpoint) != 0, "no mountpoint found");
	succeed_if_same_string (keyName (mp), "system");
	succeed_if_same_string (keyString (mp), "system");

	keyDel (key);
	kdb_del (kdb);
	elektraModulesClose (modules, 0);
	ksDel (modules);
}
static void test_simple()
{
	printf ("Test simple mount\n");

	KDB *kdb = kdb_new();
	Key *errorKey = keyNew(0);
	KeySet *modules = modules_config();
	Key *mp = keyNew("user/tests/simple", KEY_VALUE, "simple", KEY_END);

	succeed_if (elektraMountOpen(kdb, simple_config(), modules, errorKey) == 0, "could not open trie");

	succeed_if (kdb->split->size == 1, "size of split not correct");
	compare_key(mp, kdb->split->parents[0]);

	succeed_if(output_warnings (errorKey), "warnings found");
	succeed_if(output_error (errorKey), "error found");

	exit_if_fail (kdb->trie, "kdb->trie was not build up successfully");

	Key *searchKey = keyNew("user", KEY_END);
	Backend *backend = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (!backend, "there should be no backend");


	keySetName(searchKey, "user/tests/simple");
	backend = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, mp);


	keySetName(searchKey, "user/tests/simple/below");
	Backend *b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);


	keySetName(searchKey, "user/tests/simple/deep/below");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);

	keyDel (errorKey);
	ksDel (modules);
	keyDel (mp);
	keyDel (searchKey);
	kdb_del (kdb);
}
static void test_keyValue (const size_t storagePlugin, const char * tmpFile)
{
	Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
	open_storage_plugin (storagePlugin);
	Plugin * plugin = plugins[storagePlugin];

	KeySet * ks = metaTestKeySet ();
	const char * name = "user/tests/storage/specialkey";
	size_t valueSize = 42;
	void * value = elektraMalloc (valueSize);
	memset (value, 42, valueSize);

	Key * key = keyNew (name, KEY_END);
	keySetBinary (key, value, valueSize);
	ksAppendKey (ks, keyDup (key));
	succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");
	succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful");

	Key * found = ksLookupByName (ks, name, 0);
	succeed_if (found, "did not find key");
	compare_key (key, found);

	elektraFree (value);
	keyDel (parentKey);
	ksDel (ks);
	keyDel (key);
	closeStoragePlugin (storagePlugin);
}
static void test_keyCopy_newKey (const size_t storagePlugin, const char * tmpFile)
{
	Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
	open_storage_plugin (storagePlugin);
	Plugin * plugin = plugins[storagePlugin];

	KeySet * ks = metaTestKeySet ();
	succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");
	succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful");

	Key * found = ksLookupByName (ks, "user/tests/storage/b", 0);
	succeed_if (found, "did not find key");

	Key * copy = keyNew (0, KEY_END);
	succeed_if (keyCopy (copy, found) != -1, "keyCopy failed");

	compare_key (found, copy);

	// check that keyCopy has not changed KeySet
	KeySet * expected = metaTestKeySet ();
	compare_keyset (ks, expected);

	// check that KeySet is intact after deleting Key copy
	keyDel (copy);
	compare_keyset (ks, expected);

	ksDel (expected);
	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
Exemple #8
0
/**
 * Internal: deletes an entry with the specified key from the list
 *
 * Parameters:
 * - list: the list belonging to the index of the hashed key
 * - key: the element's key
 *
 * Returns:
 * - 1 if the entry was deleted, or 0 if not
 */
static int delete_entry_from_list(qhi *hash, qhl *list, qhv key)
{
	if (!list->head) {
		// there is no bucket list for this hashed key
		return 0;
	} else {
		qhb *previous = NULL;
		qhb *current = list->head;

		// loop over the elements in this bucket list to see if the key exists,
		// also keep track of the previous one
		do {
			if (compare_key(hash, current, key)) {
				// if previous is not set, it's the first element in the list, so we just adjust head.
				if (!previous) {
					list->head = current->next;
				} else {
					previous->next = current->next;
				}
				list->size--;
				return 1;
			}
			previous = current;
			current = current->next;
		} while(current);
	}
	return 0;
}
size_t decode_dict(const char *b,size_t len,const char *keylist)
{
  size_t rl,dl,nl;
  const char *pkey;
  dl = 0;
  if(2 > len || *b != 'd') return 0;

  dl++; len--;
  for(;len && *(b + dl) != 'e';){
    rl = buf_str(b + dl,len,&pkey,&nl);

    if( !rl || KEYNAME_SIZ < nl) return 0;
    dl += rl;
    len -= rl;

    if(keylist && compare_key(pkey,nl,keylist) == 0){
      pkey = next_key(keylist);
      if(! *pkey ) return dl;
      rl = decode_dict(b + dl,len, pkey);
      if( !rl ) return 0;
      return dl + rl;
    }

    rl = decode_rev(b + dl,len,(const char*) 0);
    if( !rl ) return 0;

    dl += rl;len -= rl;
  }
  if( !len || keylist) return 0;
  return dl + 1;	/* add the last char 'e' */
}
Exemple #10
0
int			main(UNUSED int ac, char **av, char **env)
{
  t_config		config;
  t_tetrimino		*tetri;
  char			key[10];
  int			c;
  struct winsize	win;

  tetri = NULL;
  if ((tetri = init_main(av, env, &config, tetri)) == NULL)
    return (-1);
  c = 0;
  key[0] = 0;
  while (compare_key(key, config.quit) == 0)
    {
      ioctl(0, TIOCGWINSZ, &win);
      get_entry(key);
      if (key[0] != 0)
	key_control(key, &config, tetri);
      if (++c >= 100 && config.brek == 0 && (c = -1) == -1)
	if (game_physics(&config, tetri))
	  end_game(&config, key);
      usleep(get_speed(config.speed, config.level));
    }
  endwin();
  return (0);
}
Exemple #11
0
void *
delete_hash (struct hash * hash, void * key)
{
	int hash_value;
	void * data;
	struct hashnode * ptr, * prev;

	if ((hash_value = calculate_hash (key)) < 0) 
		return NULL;

	prev = &hash->table[hash_value];
	
	pthread_mutex_lock (&hash->mutex[hash_value]);	

	for (ptr = prev->next; ptr != NULL; ptr = ptr->next) {
		if (compare_key (key, ptr->key) == 0)
			break;
		prev = ptr;
	}

	if (ptr == NULL) {
		pthread_mutex_unlock (&hash->mutex[hash_value]);	
		return NULL;
	}		

	prev->next = ptr->next;
	data = ptr->data;
	free (ptr);

	pthread_mutex_unlock (&hash->mutex[hash_value]);	

	return data;
}
Exemple #12
0
int
insert_hash (struct hash * hash, void * data, void * key)
{
	int hash_value;
	struct hashnode * node, * ptr, * prev;
	
	if ((hash_value = calculate_hash (key)) < 0) 
		return -1;

	prev = &hash->table[hash_value];
	pthread_mutex_lock (&hash->mutex[hash_value]);

	for (ptr = prev->next; ptr != NULL; ptr = ptr->next) {
		if (compare_key (key, ptr->key) == 0) {
			pthread_mutex_unlock (&hash->mutex[hash_value]);
			return -1;
		}
		prev = ptr;
	}
	
	node = (struct hashnode *) malloc (sizeof (struct hashnode));
	memset (node, 0, sizeof (struct hashnode));
	node->next = NULL;
	node->data = data;
	memcpy (node->key, key, HASH_KEY_LEN);
	prev->next = node;

	pthread_mutex_unlock (&hash->mutex[hash_value]);

	return 1;
}
void *
search_hash( struct hash *hash, void *key ) {
  assert( hash != NULL );
  assert( key != NULL );

  int hash_value;
  if ( ( hash_value = calculate_hash( key, hash->keylen ) ) < 0 ) {
    return NULL;
  }

  struct hashnode *ptr = &hash->table[ hash_value ];

  pthread_mutex_lock( &hash->mutex[ hash_value ] );

  for ( ptr = ptr->next; ptr != NULL; ptr = ptr->next ) {
    if ( compare_key( key, ptr->key, hash->keylen ) == 0 ) {
      pthread_mutex_unlock( &hash->mutex[ hash_value ] );
      return ptr->data;
    }
  }

  pthread_mutex_unlock( &hash->mutex[ hash_value ] );

  return NULL;
}
Exemple #14
0
void check_reversibility (const char * msg)
{
	Key * decode = keyNew ("user/test", KEY_VALUE, msg, KEY_END);

	CHexData * hd = calloc (1, sizeof (CHexData));
	hd->hd['\0'] = 1;
	hd->hd['\n'] = 1;
	hd->hd['\\'] = 1;
	hd->hd[' '] = 1;
	hd->hd['='] = 1;
	hd->hd[';'] = 1;
	hd->hd['#'] = 1;
	hd->escape = '\\';

	char buf[1000];
	hd->buf = buf;

	Key * encode = keyDup (decode);
	elektraHexcodeEncode (encode, hd);

	elektraHexcodeDecode (encode, hd);
	compare_key (encode, decode);

	elektraFree (hd);
	keyDel (decode);
	keyDel (encode);
}
static void test_mount()
{
	printf ("test mount backend\n");

	KDB *kdb = kdb_new();
	elektraMountBackend (kdb, b_new("user", "user"), 0);
	succeed_if (kdb->trie, "there should be a trie");

	Key *mp = keyNew ("user", KEY_VALUE, "user", KEY_END);
	Key *sk = keyNew ("user", KEY_VALUE, "user", KEY_END);

	succeed_if (kdb->split->size == 1, "size of split not correct");
	compare_key(mp, kdb->split->parents[0]);

	compare_key(elektraMountGetBackend (kdb, sk)->mountpoint, mp);
	compare_key(elektraMountGetMountpoint (kdb, sk), mp);

	keySetName (sk, "user/below");
	compare_key(elektraMountGetBackend (kdb, sk)->mountpoint, mp);
	compare_key(elektraMountGetMountpoint (kdb, sk), mp);

	keySetName (sk, "system");
	kdb->defaultBackend = b_new("", "default");
	succeed_if (elektraMountGetBackend (kdb, sk) == kdb->defaultBackend, "did not return default backend");

	keySetName (mp, "");
	keySetString (mp, "default");
	compare_key(elektraMountGetBackend (kdb, sk)->mountpoint, mp);
	compare_key(elektraMountGetMountpoint (kdb, sk), mp);

	keyDel (sk);
	keyDel (mp);

	kdb_del (kdb);
}
static void test_root()
{
	printf ("Test trie with root\n");

	Trie *trie = 0;
	trie = test_insert (trie, "", "root");
	trie = test_insert (trie, "user/tests/simple", "simple");

	exit_if_fail (trie, "trie was not build up successfully");

	Key *searchKey = keyNew("user", KEY_END);
	Key *rmp = keyNew("", KEY_VALUE, "root", KEY_END);
	Backend *backend = elektraTrieLookup(trie, searchKey);
	succeed_if (backend, "there should be the root backend");
	compare_key(backend->mountpoint, rmp);


	Key *mp = keyNew("user/tests/simple", KEY_VALUE, "simple", KEY_END);
	keySetName(searchKey, "user/tests/simple");
	backend = elektraTrieLookup(trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, mp);


	keySetName(searchKey, "user/tests/simple/below");
	Backend *b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);


	keySetName(searchKey, "user/tests/simple/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);

	// output_trie(trie);

	elektraTrieClose(trie, 0);
	keyDel (mp);
	keyDel (rmp);
	keyDel (searchKey);
}
Exemple #17
0
void check_reversibility (const char * msg)
{
	CCodeData * d = get_data ();
	char buf[1000];
	d->buf = buf;
	Key * decode = keyNew ("user/test", KEY_VALUE, msg, KEY_END);

	Key * encode = keyDup (decode);
	elektraCcodeEncode (encode, d);

	elektraCcodeDecode (encode, d);
	compare_key (encode, decode);

	elektraFree (d);
	keyDel (decode);
	keyDel (encode);
}
void inspect_element(HashTable* El_Table, unsigned* key) {

	HashEntryPtr * buck = El_Table->getbucketptr();
	for (int i = 0; i < El_Table->get_no_of_buckets(); i++)
		if (*(buck + i)) {
			HashEntryPtr currentPtr = *(buck + i);
			while (currentPtr) {
				Element *Curr_El = (Element*) (currentPtr->value);
				if (compare_key(Curr_El->pass_key(), key)) {
					cout << "this is something you have to avoid \n";
					exit(1);
				}

				currentPtr = currentPtr->next;
			}
		}
}
static void test_keyCopy_clearOverwriteKey (const size_t storagePlugin, const char * tmpFile)
{
	Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
	open_storage_plugin (storagePlugin);
	Plugin * plugin = plugins[storagePlugin];

	KeySet * ks = metaTestKeySet ();
	succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");
	succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful");

	Key * toCopy = keyNew ("user/tests/storage/newnewkey", KEY_VALUE, "new key", KEY_END);

	Key * found = ksLookupByName (ks, "user/tests/storage/b", KDB_O_POP);
	succeed_if (found, "did not find key");

	// currently, KDB_O_POP doest not clear the readonly name flag
	if (test_bit (found->flags, KEY_FLAG_RO_NAME))
	{
		clear_bit (found->flags, KEY_FLAG_RO_NAME);
	}

	// overwrite Key
	succeed_if (keyCopy (found, 0) == 0, "keyCopy: clear destination failed");
	succeed_if (keyCopy (found, toCopy) == 1, "keyCopy failed");
	compare_key (found, toCopy);
	keyDel (toCopy);

	// put key back into place
	ksAppendKey (ks, found);

	// write KeySet back to storage
	succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");
	succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful");

	found = ksLookupByName (ks, "user/tests/storage/newnewkey", 0);
	succeed_if (found, "did not find key");

	keyDel (parentKey);
	ksDel (ks);
	closeStoragePlugin (storagePlugin);
}
Exemple #20
0
/**
 * Internal: checks whether a key exists in a specific list
 *
 * Parameters:
 * - list: the list belonging to the index of the hashed key
 * - key: the element's key
 * - value_idx: pointer to store the value_idx in
 *
 * Returns:
 * - 1 if the key exists in the list, 0 if not
 */
static int find_bucket_from_list(qhi *hash, qhl *list, qhv key, qhb **bucket)
{
	if (!list->head) {
		// there is no bucket list for this hashed key
		return 0;
	} else {
		qhb *p = (qhb*) list->head;

		// loop over the elements in this bucket list to see if the key exists
		do {
			if (compare_key(hash, p, key)) {
				if (bucket) {
					*bucket = p;
				}
				return 1;
			}
			p = p->next;
		} while(p);
	}
	return 0;
}
void *
delete_hash( struct hash *hash, void *key ) {
  assert( hash != NULL );
  assert( key != NULL );

  int hash_value = -1;
  if ( ( hash_value = calculate_hash( key, hash->keylen ) ) < 0 ) {
    return NULL;
  }

  struct hashnode *prev = &hash->table[ hash_value ];

  pthread_mutex_lock( &hash->mutex[ hash_value ] );

  struct hashnode *ptr = NULL;
  for ( ptr = prev->next; ptr != NULL; ptr = ptr->next ) {
    if ( compare_key( key, ptr->key, hash->keylen ) == 0 ) {
      break;
    }
    prev = ptr;
  }

  if ( ptr == NULL ) {
    pthread_mutex_unlock( &hash->mutex[ hash_value ] );
    return NULL;
  }

  prev->next = ptr->next;
  void *data = ptr->data;
  free( ptr->key );
  free( ptr );

  hash->count--;

  pthread_mutex_unlock( &hash->mutex[ hash_value ] );

  return data;
}
int
insert_hash( struct hash *hash, void *data, void *key ) {
  assert( hash != NULL );
  assert( data != NULL );
  assert( key != NULL );

  int hash_value = -1;
  if ( ( hash_value = calculate_hash( key, hash->keylen ) ) < 0 ) {
    return -1;
  }

  struct hashnode *prev = &hash->table[ hash_value ];
  pthread_mutex_lock( &hash->mutex[ hash_value ] );

  for ( struct hashnode *ptr = prev->next; ptr != NULL; ptr = ptr->next ) {
    if ( compare_key( key, ptr->key, hash->keylen ) == 0 ) {
      pthread_mutex_unlock( &hash->mutex[ hash_value ] );
      return -1;
    }
    prev = ptr;
  }

  struct hashnode *node = ( struct hashnode * ) malloc( sizeof( struct hashnode ) );
  memset( node, 0, sizeof( struct hashnode ) );
  node->next = NULL;
  node->data = data;
  node->key = ( uint8_t * ) malloc( ( size_t ) hash->keylen );
  memcpy( node->key, key, ( size_t ) hash->keylen );
  prev->next = node;

  hash->count++;

  pthread_mutex_unlock( &hash->mutex[ hash_value ] );

  return 1;
}
void calc_jacobian_old(MeshCTX* meshctx, PropCTX* propctx) {

	int myid, numprocs;
	MPI_Comm_rank(MPI_COMM_WORLD, &myid);
	MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

	HashTable* El_Table = meshctx->el_table;
	HashTable* NodeTable = meshctx->nd_table;

	TimeProps* timeprops_ptr = propctx->timeprops;
	MapNames* mapname_ptr = propctx->mapnames;
	MatProps* matprops_ptr = propctx->matprops;

	int neigh_flag;
	HashEntryPtr* buck = El_Table->getbucketptr();
	HashEntryPtr currentPtr;
	DualElem* Curr_El = NULL;

	int iter = timeprops_ptr->iter;
	double tiny = GEOFLOW_TINY;

//this array holds ResFlag for element itself and its neighbors
	ResFlag resflag[EFF_ELL];
	reset_resflag(resflag);

#ifdef DEBUGFILE
	ofstream myfile;
	myfile.open("debug.txt",ios::app);
#endif

	for (int i = 0; i < El_Table->get_no_of_buckets(); i++) {
		if (*(buck + i)) {
			currentPtr = *(buck + i);
			while (currentPtr) {
				Curr_El = (DualElem*) (currentPtr->value);

				if (Curr_El->get_adapted_flag() > 0
				    && (Curr_El->get_ithelem() == 722 || Curr_El->get_ithelem() == 730
				        || Curr_El->get_ithelem() == 723 || Curr_El->get_ithelem() == 725
				        || Curr_El->get_ithelem() == 724 || Curr_El->get_ithelem() == 726
				        || Curr_El->get_ithelem() == 749 || Curr_El->get_ithelem() == 880
				        || Curr_El->get_ithelem() == 884 || Curr_El->get_ithelem() == 1329
				        || Curr_El->get_ithelem() == 1333)) {

					int boundary = 0;

					//this part handles if the Curr_El is a boundary element
					//cout<<"I am running do not worry"<<endl;
					for (int neighnum = 0; neighnum < 4; neighnum++)
						if (*(Curr_El->get_neigh_proc() + neighnum) == INIT) {
							boundary = 1;
							// this for the element that are on the boundary
							Curr_El->set_jacobian();
							break;
						}
					if (!boundary) {

						double state_vars[NUM_STATE_VARS], gravity[NUM_STATE_VARS];
						double d_gravity[DIMENSION], curvature[DIMENSION];
						double d_state_vars_old[NUM_STATE_VARS * DIMENSION];
						double prev_state_vars_old[NUM_STATE_VARS * DIMENSION];
						double *prev_state_vars = Curr_El->get_prev_state_vars();
						Curr_El->calc_stop_crit(matprops_ptr); //this function updates bedfric properties
						double bedfrict = Curr_El->get_effect_bedfrict();
						double dx[DIMENSION] = { *(Curr_El->get_dx()), *(Curr_El->get_dx() + 1) };
						double kactxy[DIMENSION];
						double orgSrcSgn[DIMENSION];
						int check_stop[DIMENSION] = { 0, 0 };

						for (int ind = 0; ind < NUM_STATE_VARS; ++ind)
							gravity[ind] = *(Curr_El->get_gravity() + ind);

						for (int ind = 0; ind < DIMENSION; ++ind) {

							d_gravity[ind] = *(Curr_El->get_d_gravity() + ind);
							curvature[ind] = *(Curr_El->get_curvature() + ind);

						}

						for (int ind = 0; ind < NUM_STATE_VARS * DIMENSION; ++ind)
							d_state_vars_old[ind] = *(Curr_El->get_d_state_vars() + ind);

						for (int ind = 0; ind < NUM_STATE_VARS * DIMENSION; ++ind)
							prev_state_vars_old[ind] = *(Curr_El->get_prev_state_vars() + ind);

						if (timeprops_ptr->iter < 51)
							matprops_ptr->frict_tiny = 0.1;
						else
							matprops_ptr->frict_tiny = 0.000000001;

						orgSourceSgn(Curr_El, matprops_ptr->frict_tiny, orgSrcSgn);

						double fluxold[4][NUM_STATE_VARS];
						record_flux(El_Table, NodeTable, Curr_El->pass_key(), matprops_ptr, myid, fluxold);

						double dt = timeprops_ptr->dt.at(iter - 1);	//at final time step we do not need the computation of adjoint and we always compute it for the previouse time so we need iter.
						double dtdx = dt / dx[0];
						double dtdy = dt / dx[1];

						double org_res[NUM_STATE_VARS];

						int gggflag = 0;

						if (*(Curr_El->pass_key()) == KEY0 && *(Curr_El->pass_key() + 1) == KEY1 && iter == ITER)
							gggflag = 1;

						residual(org_res, Curr_El->get_state_vars(), prev_state_vars, fluxold[0], //4
						    fluxold[1], fluxold[2], fluxold[3], dtdx, dtdy, dt, d_state_vars_old, //7
						    (d_state_vars_old + NUM_STATE_VARS), curvature, //2
						    matprops_ptr->intfrict, //1
						    bedfrict, gravity, d_gravity, *(Curr_El->get_kactxy()), //4
						    matprops_ptr->frict_tiny, orgSrcSgn, 0./*=increment*/, //3
						    matprops_ptr->epsilon, check_stop); //2

						for (int side = 0; side < 4; side++)
							if (*(Curr_El->get_neigh_proc() + side) == INIT) // this is a boundary!
								for (int ind = 0; ind < NUM_STATE_VARS; ind++)
									*(Curr_El->get_state_vars() + ind) = 0;

						for (int ind = 0; ind < NUM_STATE_VARS; ++ind)
							state_vars[ind] = *(Curr_El->get_state_vars() + ind);

						for (int effelement = 0; effelement < EFF_ELL; effelement++) { //0 for the element itself, and the rest id for neighbour elements

#ifdef DEBUG
							int gggflag = 0;

							if (*(Curr_El->pass_key()) == KEY0 && *(Curr_El->pass_key() + 1) == KEY1
									&& iter == ITER && effelement == EFFELL)
							gggflag = 1;
#endif

							if (effelement == 0 && prev_state_vars[0] == 0.)

								//this is a void element so the residual vector does not change by changing it's values
								Curr_El->set_jacobianMat_zero(effelement);

							else if (effelement > 4
							    && compare_key((Curr_El->get_neighbors() + (effelement - 1) * KEYLENGTH),
							        (Curr_El->get_neighbors() + (effelement - 5) * KEYLENGTH)))

								Curr_El->set_jacobianMat_zero(effelement);

							else if (effelement != 0 && void_neigh_elem(El_Table, Curr_El, effelement))

								//this is a void neighbor element so the residual of the curr_el does not depend on this neighbor
								Curr_El->set_jacobianMat_zero(effelement);

							else if (effelement > 0 && *(Curr_El->get_neigh_proc() + (effelement - 1)) == INIT)
								Curr_El->set_jacobianMat_zero(effelement);

							else {

								for (int j = 0; j < NUM_STATE_VARS; j++) { //there is a problem here: I do not need to compute for first the component of adjoint

									double vec_res[NUM_STATE_VARS];
									double total_res[NUM_STATE_VARS] = { 0., 0., 0. };

									int scheme = 0;
									for (; scheme < 1; scheme++) {

										//this flag shows that the pileheight before adding the increment is below or above the GEOFLOW_TINY.
										//if it is below GEOFLOW_TINY then there is no need to update fluxes and kactxy
										int updateflux, srcflag;
										reset_resflag(resflag);

										// here we modify increment to one time compute forward and one time compute backward difference if it is necessary
										double signe = pow(-1., scheme);
										double incr = signe * INCREMENT;
										increment_state(El_Table, Curr_El, incr, effelement, j, &updateflux, &srcflag,
										    resflag);

										calc_flux_slope_kact(El_Table, NodeTable, Curr_El, matprops_ptr, myid,
										    effelement, updateflux, srcflag, resflag);

										//Attention make sure that NUM_STATE_VARS are selected correctly
										//Actually we just need 3, but there is an excessive for first adjoint
										//const int state_num=NUM_STATE_VARS-2;
										double flux[4][NUM_STATE_VARS];
										record_flux(El_Table, NodeTable, Curr_El->pass_key(), matprops_ptr, myid, flux);

#ifdef DEBUG
//										if (*(Curr_El->pass_key()) == KEY0 && *(Curr_El->pass_key() + 1) == KEY1
//										    && effelement == EFFELL && iter == ITER && j == J)
										flux_debug(Curr_El, fluxold[0], fluxold[2], fluxold[1], fluxold[3], flux[0],
												flux[2], flux[1], flux[3], effelement, j, iter, dt);
#endif

										double *d_state_vars = Curr_El->get_d_state_vars();

										//here we compute the residuals
										residual(vec_res, state_vars, prev_state_vars, flux[0],									//4
										    flux[1], flux[2], flux[3], dtdx, dtdy, dt, d_state_vars,								//7
										    (d_state_vars + NUM_STATE_VARS), curvature,									//2
										    matprops_ptr->intfrict,									//1
										    bedfrict, gravity, d_gravity, *(Curr_El->get_kactxy()),									//4
										    matprops_ptr->frict_tiny, orgSrcSgn, incr,									//3
										    matprops_ptr->epsilon, check_stop, srcflag, 0);									//2

#ifdef DEBUGFILE
										myfile << "Elem Key[0]= " << *(Curr_El->pass_key()) << "  Key[1]= "
										<< *(Curr_El->pass_key()) << " iter= " << iter << " eff_el= " << effelement
										<< " j= " << j << " residual[0]= " << vec_res[0] << " residual[1]= "
										<< vec_res[1] << " residual[2]= " << vec_res[2] << endl;
#endif

										//we have to return everything back
//										restore(El_Table, NodeTable, Curr_El, effelement, j, incr, fluxold,
//										    d_state_vars_old);
										restore(El_Table, NodeTable, Curr_El, matprops_ptr, effelement, j, myid, incr,
										    d_state_vars_old);

//										if (check_restore(prev_state_vars, d_state_vars, prev_state_vars_old,
//										    d_state_vars_old, flux, fluxold))
//											cout << "this would cause incorrect result" << endl;

										for (int ind = 0; ind < NUM_STATE_VARS; ind++)
											total_res[ind] += signe * vec_res[ind];

//											if (scheme == 0 && fabs(vec_res[0] / incr) < 5.
//													&& fabs(vec_res[1] / incr) < 5.
//													&& fabs(vec_res[2] / incr) < 5.)
//												//this means that forward difference is enough, and we do not need to compute central difference
										break;

									}

									double jacincr = INCREMENT; //= scheme == 0 ? increment : 2. * increment;

									Curr_El->set_jacobian(effelement, total_res, j,
									// following term is necessary to consider the scheme that whether it is forward difference or central difference
									    jacincr); //sets the propper components of the Jacobian for this element

								}
							}
						}
					}
				}
				currentPtr = currentPtr->next;
			}
		}
	}

#ifdef DEBUGFILE
	myfile.close();
#endif

}
static void test_endings()
{
	printf ("Test endings trie\n");

	for (int i=0; i<4; ++i)
	{

	Trie *trie = 0;
	switch (i)
	{
	case 0:
		trie = test_insert (trie, "user/endings/","slash");
		trie = test_insert (trie, "user/endings#","hash");
		trie = test_insert (trie, "user/endings ","space");
		trie = test_insert (trie, "user/endings\200","endings");
		break;
	case 1:
		trie = test_insert (trie, "user/endings#","hash");
		trie = test_insert (trie, "user/endings ","space");
		trie = test_insert (trie, "user/endings\200","endings");
		trie = test_insert (trie, "user/endings/","slash");
		break;
	case 2:
		trie = test_insert (trie, "user/endings ","space");
		trie = test_insert (trie, "user/endings\200","endings");
		trie = test_insert (trie, "user/endings/","slash");
		trie = test_insert (trie, "user/endings#","hash");
		break;
	case 3:
		trie = test_insert (trie, "user/endings\200","endings");
		trie = test_insert (trie, "user/endings ","space");
		trie = test_insert (trie, "user/endings#","hash");
		trie = test_insert (trie, "user/endings/","slash");
		break;
	}

	exit_if_fail (trie, "trie was not build up successfully");

	Key *searchKey = keyNew("user", KEY_END);
	Backend *backend = elektraTrieLookup(trie, searchKey);
	succeed_if (!backend, "there should be no backend");


	Key *mp = keyNew("user/endings", KEY_VALUE, "slash", KEY_END);
	keySetName(searchKey, "user/endings");
	backend = elektraTrieLookup(trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, mp);


	keySetName(searchKey, "user/endings#");
	keySetName(mp, "user/endings#");
	keySetString(mp, "hash");
	Backend *b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend != b2, "should be other backend");
	compare_key(b2->mountpoint, mp);


	keySetName(searchKey, "user/endings/_");
	keySetName(mp, "user/endings");
	keySetString(mp, "slash");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be the same backend");
	compare_key(b2->mountpoint, mp);


	keySetName(searchKey, "user/endings/X");
	keySetName(mp, "user/endings");
	keySetString(mp, "slash");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be the same backend");
	compare_key(b2->mountpoint, mp);


	keySetName(searchKey, "user/endings_");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (!b2, "there should be no backend");


	keySetName(searchKey, "user/endingsX");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (!b2, "there should be no backend");


	keySetName(searchKey, "user/endings!");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (!b2, "there should be no backend");


	keySetName(searchKey, "user/endings ");
	keySetName(mp, "user/endings ");
	keySetString(mp, "space");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend != b2, "should be other backend");
	compare_key(b2->mountpoint, mp);

	keySetName(searchKey, "user/endings\200");
	keySetName(mp, "user/endings\200");
	keySetString(mp, "endings");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend != b2, "should be other backend");
	compare_key(b2->mountpoint, mp);

	// output_trie(trie);

	elektraTrieClose(trie, 0);
	keyDel (mp);
	keyDel (searchKey);

	}
}
static void test_revmoreiterate()
{
	printf ("Test revmoreiterate trie\n");

	for (int i=0; i<5; ++i)
	{

	Trie *trie = 0;
	switch (i)
	{
	case 0:
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		trie = test_insert (trie, "system", "system");
		trie = test_insert (trie, "user", "user");
		break;
	case 1:
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "system", "system");
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "user", "user");
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		break;
	case 2:
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user", "user");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "system", "system");
		break;
	case 3:
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user", "user");
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "system", "system");
		break;
	case 4:
		trie = test_insert (trie, "system/tests/hosts/below", "sysbelow");
		trie = test_insert (trie, "system/tests/hosts", "syshosts");
		trie = test_insert (trie, "system/tests", "systests");
		trie = test_insert (trie, "system", "system");
		trie = test_insert (trie, "user/tests/hosts/below", "below");
		trie = test_insert (trie, "user/tests/hosts", "hosts");
		trie = test_insert (trie, "user/tests", "tests");
		trie = test_insert (trie, "user", "user");
		break;
	}

	KeySet *mps = set_mountpoints();

	exit_if_fail (trie, "trie was not build up successfully");

	Key *searchKey = keyNew(0);

	keySetName(searchKey, "user");
	Backend *backend = elektraTrieLookup(trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, ksLookupByName(mps, "user",0));
	// printf ("backend: %p\n", (void*)backend);


	keySetName(searchKey, "user/tests/hosts/other/below");
	Backend *b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, ksLookupByName(mps, "user/tests/hosts",0));
	// printf ("b2: %p\n", (void*)b2);


	keySetName(searchKey, "user/tests/hosts/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, ksLookupByName(mps, "user/tests/hosts",0));


	keySetName(searchKey, "user/tests/hosts/below");
	Backend *b3 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	compare_key(b3->mountpoint, ksLookupByName(mps, "user/tests/hosts/below",0));
	backend = b3;
	// printf ("b3: %p\n", (void*)b3);


	keySetName(searchKey, "user/tests/hosts/below/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	compare_key(b3->mountpoint, ksLookupByName(mps, "user/tests/hosts/below",0));

	keySetName(searchKey, "system");
	backend = elektraTrieLookup(trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, ksLookupByName(mps, "system",0));
	// printf ("backend: %p\n", (void*)backend);


	keySetName(searchKey, "system/tests/hosts/other/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, ksLookupByName(mps, "system/tests/hosts",0));
	// printf ("b2: %p\n", (void*)b2);


	keySetName(searchKey, "system/tests/hosts/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, ksLookupByName(mps, "system/tests/hosts",0));


	keySetName(searchKey, "system/tests/hosts/below");
	b3 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	compare_key(b3->mountpoint, ksLookupByName(mps, "system/tests/hosts/below",0));
	backend = b3;
	// printf ("b3: %p\n", (void*)b3);


	keySetName(searchKey, "system/tests/hosts/below/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	compare_key(b3->mountpoint, ksLookupByName(mps, "system/tests/hosts/below",0));

	/*
	printf ("---------\n");
	output_trie(trie);
	*/

	KeySet *mps_cmp = ksNew(0, KS_END);
	collect_mountpoints(trie, mps_cmp);
	succeed_if (ksGetSize(mps_cmp) == 8, "size should be 8");
	compare_keyset(mps, mps_cmp);

	ksDel (mps_cmp);
	ksDel (mps);

	elektraTrieClose(trie, 0);
	keyDel (searchKey);

	} // end for
}
static void test_reviterate()
{
	printf ("Test reviterate trie\n");

	Trie * trie = test_insert (0, "user/tests/hosts/below", "below");
	trie = test_insert (trie, "user/tests/hosts", "hosts");

	exit_if_fail (trie, "trie was not build up successfully");

	Key *searchKey = keyNew("user", KEY_END);
	Backend *backend = elektraTrieLookup(trie, searchKey);
	succeed_if (!backend, "there should be no backend");


	Key *mp = keyNew("user/tests/hosts", KEY_VALUE, "hosts", KEY_END);
	keySetName(searchKey, "user/tests/hosts");
	backend = elektraTrieLookup(trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, mp);
	// printf ("backend: %p\n", (void*)backend);


	keySetName(searchKey, "user/tests/hosts/other/below");
	Backend *b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);
	// printf ("b2: %p\n", (void*)b2);


	keySetName(searchKey, "user/tests/hosts/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);


	Key *mp2 = keyNew("user/tests/hosts/below", KEY_VALUE, "below", KEY_END);
	keySetName(searchKey, "user/tests/hosts/below");
	Backend *b3 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	succeed_if (backend != b3, "should be different backend");
	compare_key(b3->mountpoint, mp2);
	backend = b3;
	// printf ("b3: %p\n", (void*)b3);


	keySetName(searchKey, "user/tests/hosts/below/other/deep/below");
	b2 = elektraTrieLookup(trie, searchKey);
	succeed_if (b3, "there should be a backend");
	succeed_if (backend == b3, "should be same backend");
	compare_key(b3->mountpoint, mp2);

	KeySet *mps = ksNew(0, KS_END);
	collect_mountpoints(trie, mps);
	succeed_if (ksGetSize (mps) == 2, "not both mountpoints collected");
	compare_key(ksHead(mps), mp);
	compare_key(ksTail(mps), mp2);
	ksDel (mps);

	elektraTrieClose(trie, 0);

	keyDel (mp);
	keyDel (mp2);
	keyDel (searchKey);
}
//make this a Node and Element friend fucntion
void unrefine_interp_neigh_update(HashTable* El_Table, HashTable* NodeTable, int nump, int myid,
    void* OPU) {
	ElemPtrList<Element>* OtherProcUpdate = (ElemPtrList<Element>*) OPU;

	if (nump < 2)
		return;

	int *num_send = CAllocI1(nump), *num_recv = CAllocI1(nump), *isend = CAllocI1(nump);
	int ierr, iopu, iproc, ineigh, ison, ikey, neigh_proc; //iopu stands for i other processor update
	int send_tag = 061116; //2006 November 16, the day I coded this function.
	MPI_Request* request = new MPI_Request[2 * nump];
	Element* EmFather;
	Node *NdTemp;

	if (myid == TARGET_PROC)
		printf("myid=%d unref_interp_neigh_update 1.0\n", myid);
	fflush(stdout);

	for (iproc = 0; iproc < nump; iproc++)
		num_send[iproc] = num_recv[iproc] = isend[iproc] = 0;

	for (iopu = 0; iopu < OtherProcUpdate->get_num_elem(); iopu++) {
		EmFather = OtherProcUpdate->get(iopu);
		assert(EmFather);
		assert(EmFather->myprocess == myid);
		for (ineigh = 0; ineigh < 8; ineigh++) {
			neigh_proc = EmFather->neigh_proc[ineigh];
			if ((neigh_proc >= 0) && (neigh_proc != myid))
				num_send[neigh_proc]++;
		}
	}
	num_send[myid] = 0; //better paranoid then dead;

//send to each processor the number of his elements he has to update because of me
//receive from each processor the number of elements I have to update because of him
	MPI_Alltoall(num_send, 1, MPI_INT, num_recv, 1, MPI_INT, MPI_COMM_WORLD);

	if (myid == TARGET_PROC)
		for (iproc = 0; iproc < nump; iproc++) {
			printf("myid=%2d to/from proc %2d num_send=%6d num_recv=%6d\n", myid, iproc, num_send[iproc],
			    num_recv[iproc]);
			fflush(stdout);
		}
	MPI_Barrier(MPI_COMM_WORLD);
	if ((myid != TARGET_PROC) && (TARGET_PROC < nump) && (TARGET_PROC > 0)) {
		printf("myid=%2d to/from proc %2d num_send=%6d num_recv=%6d\n", myid,
		TARGET_PROC, num_send[TARGET_PROC], num_recv[TARGET_PROC]);
		fflush(stdout);
	}
	MPI_Barrier(MPI_COMM_WORLD);
	/*
	 for(iproc=0;iproc<nump;iproc++)
	 printf("myid=%d neighproc=%d numsend=%d numrecv=%d\n",
	 myid,iproc,num_send[iproc],num_recv[iproc]);
	 exit(0);
	 */
	num_recv[myid] = 0; //better paranoid then dead;

	int max_num_send = 0, max_num_recv = 0;

	for (iproc = 0; iproc < nump; iproc++) {
		if (num_send[iproc] > max_num_send)
			max_num_send = num_send[iproc];
		if (num_recv[iproc] > max_num_recv)
			max_num_recv = num_recv[iproc];
	}

	unsigned **send, **recv;

	if (max_num_send > 0)
		send = CAllocU2(nump, 4 * KEYLENGTH * max_num_send);
	if (max_num_recv > 0)
		recv = CAllocU2(nump, 4 * KEYLENGTH * max_num_recv);

	for (iproc = 0; iproc < nump; iproc++)
		if ((iproc != myid) && (num_recv[iproc] > 0))
			ierr = MPI_Irecv((void *) recv[iproc], 4 * KEYLENGTH * num_recv[iproc],
			MPI_UNSIGNED, iproc, send_tag + iproc, MPI_COMM_WORLD, (request + nump + iproc));

	if (myid == TARGET_PROC)
		printf("myid=%d unref_interp_neigh_update 2.0\n", myid);
	fflush(stdout);

	for (iopu = 0; iopu < OtherProcUpdate->get_num_elem(); iopu++) {
		EmFather = OtherProcUpdate->get(iopu);
		assert(EmFather);
		for (ineigh = 0; ineigh < 8; ineigh++) {
			neigh_proc = EmFather->neigh_proc[ineigh];
			if ((neigh_proc >= 0) && (neigh_proc != myid)) {

				switch (ineigh) {
					case 0:
					case 7:
						ison = 0;
						break;
					case 1:
					case 4:
						ison = 1;
						break;
					case 2:
					case 5:
						ison = 2;
						break;
					case 3:
					case 6:
						ison = 3;
						break;
					default:
						assert(0);
				}

				NdTemp = (Node*) NodeTable->lookup(EmFather->node_key[ineigh % 4 + 4]);
				assert(NdTemp);

				if (EmFather->neigh_gen[ineigh] - 1 == EmFather->generation)
					NdTemp->info = S_C_CON;

				for (ikey = 0; ikey < KEYLENGTH; ikey++) {
					//The element I want my neighbor to update
					send[neigh_proc][(4 * isend[neigh_proc] + 0) * KEYLENGTH + ikey] =
					    EmFather->neighbor[ineigh][ikey];
					//the OLDSON who will introduce his NEWFATHER to his
					//neighbor on another processor
					send[neigh_proc][(4 * isend[neigh_proc] + 1) * KEYLENGTH + ikey] =
					    EmFather->son[ison][ikey];
					//the NEWFATHER element
					send[neigh_proc][(4 * isend[neigh_proc] + 2) * KEYLENGTH + ikey] = EmFather->key[ikey];
					send[neigh_proc][(4 * isend[neigh_proc] + 3) * KEYLENGTH + ikey] = NdTemp->key[ikey];
				}

				isend[neigh_proc]++;
			}
		}
	}
	for (iproc = 0; iproc < nump; iproc++)
		assert(isend[iproc] == num_send[iproc]);

	CDeAllocI1(isend);

	if (myid == TARGET_PROC)
		printf("myid=%d unref_interp_neigh_update 3.0\n", myid);
	fflush(stdout);

	for (iproc = 0; iproc < nump; iproc++)
		if ((iproc != myid) && (num_send[iproc] > 0))
			ierr = MPI_Isend((void *) send[iproc], 4 * KEYLENGTH * num_send[iproc],
			MPI_UNSIGNED, iproc, send_tag + myid, MPI_COMM_WORLD, (request + iproc));

	if (myid == TARGET_PROC)
		printf("myid=%d unref_interp_neigh_update 4.0\n", myid);
	fflush(stdout);

	int NumProcsNotRecvd, ifrecvd, nodeorder;
	MPI_Status status;
	Element *EmTemp;
	if (max_num_recv > 0)
		do {

			for (iproc = 0; iproc < nump; iproc++)
				if ((iproc != myid) && (num_recv[iproc] > 0)) {
					if (myid == TARGET_PROC)
						printf("myid=%d iproc=%2d unref_interp_neigh_update 5.0\n", myid, iproc);
					fflush(stdout);

					//only check processors I haven't already handled
					ifrecvd = 0;
					//printf("myid=%d before Test",myid); fflush(stdout);
					MPI_Test(request + nump + iproc, &ifrecvd, &status);
					//printf("myid=%d after Test",myid); fflush(stdout);
					if (ifrecvd) {
						if (myid == TARGET_PROC)
							printf("myid=%d iproc=%2d unref_interp_neigh_update 6.0\n", myid, iproc);
						fflush(stdout);

						//I have just received new data from a neighboring processor
						//I need to update some elements on my interprocessor
						//boundary

						nodeorder = 0; //initialize to zero

						for (iopu = 0; iopu < num_recv[iproc]; iopu++) {
							//one by one check my Element's that my neighbor processor
							//says I need to update

							//Hi I'm EmTemp
							EmTemp = (Element*) El_Table->lookup(&(recv[iproc][(4 * iopu + 0) * KEYLENGTH]));

							//my old neighbor will introduce his NEWFATHER to me
							for (ineigh = 0; ineigh < 8; ineigh++)
								if (compare_key(EmTemp->neighbor[ineigh],
								    &(recv[iproc][(4 * iopu + 1) * KEYLENGTH])))
									break;
							assert(ineigh < 8); //I don't know this Element pretending to be
							//my neighbor, I'm calling the FBI to report a suspicious
							//person... err.. suspicious Element
							int ineighmod4 = ineigh % 4;

							if (EmTemp->adapted == OLDSON) {
								//I'm moving out too so I'll introduce my NEWFATHER to my
								//neighbor's NEWFATHER who my neighbor just introduced to me

								//we can use my father's key directly instead of having to
								//use get_father() because we know that my father's key
								//was assigned to me in unrefine_elements()
								EmFather = (Element*) El_Table->lookup(EmTemp->father);
								assert(EmFather);

								//which means my father will only have 1 neighbor on that side
								EmFather->neigh_proc[ineighmod4 + 4] = -2;

								for (ikey = 0; ikey < KEYLENGTH; ikey++)
									EmFather->neighbor[ineighmod4][ikey] = EmFather->neighbor[ineighmod4 + 4][ikey] =
									    recv[iproc][(4 * iopu + 2) * KEYLENGTH + ikey];

								//I know my neighbor on the other processor is the same
								//generation as me because we were both unrefined and only
								//one of us would have been able to unrefine if we were of
								//different generations, that means our NEWFATHERs are the
								//same generation as each other too
								EmFather->neigh_gen[ineighmod4] = EmFather->neigh_gen[ineighmod4 + 4] =
								    EmFather->generation;

								//all the other neighbor information remains the same but
								//must delete 2 nodes I'll do 1 now and the other one was
								//just done previous or will be deleted next
								NdTemp = (Node *) NodeTable->lookup(EmTemp->node_key[ineighmod4 + 4]);
								if (NdTemp) {
									NodeTable->remove(NdTemp->key, 0, stdout, myid, 12);
									delete NdTemp;
								}
								NdTemp = (Node *) NodeTable->lookup(EmFather->node_key[ineighmod4 + 4]);
								NdTemp->info = SIDE;

							} else if (EmTemp->adapted >= NOTRECADAPTED) {
								nodeorder = 0;

								//my neighbor on the other processor was of either my
								//generation or one generation younger/higher than me,
								//that makes
								//his father either one generation lower than me or of
								//my generation. Either way his FATHER will be the only
								//neighbor I have on that side

								EmTemp->neigh_proc[ineighmod4 + 4] = -2;

								for (ikey = 0; ikey < KEYLENGTH; ikey++)
									EmTemp->neighbor[ineighmod4 + 4][ikey] = EmTemp->neighbor[ineighmod4][ikey] =
									    recv[iproc][(4 * iopu + 2) * KEYLENGTH + ikey];

								EmTemp->neigh_gen[ineighmod4 + 4] = EmTemp->neigh_gen[ineighmod4] =
								    EmTemp->neigh_gen[ineighmod4] - 1;
								//(recv[iproc][(4*iopu+3)*KEYLENGTH+0]?-1:1)*
								//(recv[iproc][(4*iopu+3)*KEYLENGTH+1]);

								//all the other neighbor information remains the same but may need
								//to delete some nodes and update side node
								//titan doesn't use node order but for a continuous galerkin code
								//you may need to reset the node order here, which would be extra
								//information to be communicated accross.  If you enforce the
								//minimum generation to be zero then you only need 1 unsigned
								//number to hold the generation or you could use a union of
								//int and unsigned an the first bit of the unsigned would be the
								//sign of the int so you wouldn't need 2 unsigneds to communicate
								//the generation.
								NdTemp = (Node *) NodeTable->lookup(EmTemp->node_key[ineighmod4 + 4]);
								assert(NdTemp);
								if (EmTemp->neigh_gen[ineighmod4] == EmTemp->generation)
									NdTemp->info = SIDE;
								else {	 //my neighbor was my generation but his father moved in
									NdTemp->info = S_S_CON;

									NdTemp = (Node*) NodeTable->lookup(recv[iproc] + (4 * iopu + 3) * KEYLENGTH);
									if (!NdTemp) {
										ElemBackgroundCheck(El_Table, NodeTable,
										    recv[iproc] + (4 * iopu + 3) * KEYLENGTH,
										    stdout);
										assert(NdTemp);
									}
									NdTemp->info = S_C_CON;
								}
							} else
								//EmTemp is missing... he may have been abducted
								//Call the FBI to report a missing person! err... make that
								//Call the FBI to report a missing Element!
								assert(0);

						}
						num_recv[iproc] = 0;
						if (myid == TARGET_PROC)
							printf("myid=%d iproc=%2d unref_interp_neigh_update 7.0\n", myid, iproc);
						fflush(stdout);

					}
				}
			if (myid == TARGET_PROC)
				printf("myid=%d unref_interp_neigh_update 8.0\n", myid);
			fflush(stdout);

			NumProcsNotRecvd = 0;
			for (iproc = 0; iproc < nump; iproc++)
				if ((iproc != myid) && (num_recv[iproc] > 0))
					NumProcsNotRecvd++;

		} while (NumProcsNotRecvd > 0);
	if (myid == TARGET_PROC)
		printf("myid=%d unref_interp_neigh_update 9.0\n", myid);
	fflush(stdout);

	if (max_num_recv > 0)
		CDeAllocU2(recv);
	CDeAllocI1(num_recv);

	if (myid == TARGET_PROC)
		printf("myid=%d unref_interp_neigh_update 10.0\n", myid);
	fflush(stdout);

	MPI_Barrier(MPI_COMM_WORLD);

	if (max_num_send > 0)
		CDeAllocU2(send);
	CDeAllocI1(num_send);
	delete[] request;

	if (myid == TARGET_PROC)
		printf("myid=%d unref_interp_neigh_update 11.0\n", myid);
	fflush(stdout);

	MPI_Barrier(MPI_COMM_WORLD);

	return;
}
//make this an element friend function
void unrefine_neigh_update(HashTable* El_Table, HashTable* NodeTable, int myid, void* NFL) {

	ElemPtrList<Element>* NewFatherList = (ElemPtrList<Element>*) NFL;

	int iupdate, ineigh, isonA, isonB, ineighme, ikey;
	Element *EmNeigh, *EmFather;

//loop through the NEWFATHER elements
	for (iupdate = 0; iupdate < NewFatherList->get_num_elem(); iupdate++) {

		//I'm a NEWFATHER I'm going to update my neighbors with
		//my information and if he's a NEWFATHER too I'm going
		//to and update my information about him
		EmFather = NewFatherList->get(iupdate);
		assert(EmFather); //Help I've been abducted call the FBI!!!
		/*
		 unsigned elemdebugkey[2]={ 695892755,2973438897};
		 if(compare_key(EmFather->pass_key(),elemdebugkey)){
		 printf("myid=%d unrefine():refine_neigh_update: EmFather={%10u,%10u}\n",
		 myid,elemdebugkey[0],elemdebugkey[1]);
		 ElemBackgroundCheck(El_Table,NodeTable,elemdebugkey,stdout);
		 printf("it's 4 sons are\n");
		 for(int ison=0;ison<4;ison++) {
		 printf("***ison=%d {%10u,%10u} \n",ison,
		 EmFather->getson()+ison*KEYLENGTH+0,
		 EmFather->getson()+ison*KEYLENGTH+1);
		 ElemBackgroundCheck(El_Table,NodeTable,EmFather->getson()+ison*KEYLENGTH,stdout);
		 }
		 }
		 */

		for (ineigh = 0; ineigh < 8; ineigh++)
			if (EmFather->neigh_proc[ineigh] == myid) {
				//only update the information of on processor neighbors in
				//this function.

				EmNeigh = (Element*) El_Table->lookup(EmFather->neighbor[ineigh]);
				assert(EmNeigh); //Somebody has abducted my neighbor call the FBI!!!

				if (EmNeigh->adapted != NEWFATHER) {
					//If I knew my neighbor was a NEWFATHER that means
					//my neighbor already updated his and my neighbor
					//information about each other

					if (EmNeigh->adapted == OLDSON) {
						//I am introduced to a NEWFATHER neighbor by his OLDSON
						EmNeigh = (Element*) El_Table->lookup(EmNeigh->father);
						assert(EmNeigh); //Somebody has abducted my neighbor call the FBI!!!
					}

					//One of my OLDSONs will introduce my neighbor to me
					isonA = ineigh % 4;
					isonB = (isonA + 1) % 4;

					for (ineighme = 0; ineighme < 4; ineighme++)
						if (compare_key(EmNeigh->neighbor[ineighme], EmFather->son[isonA])
						    || compare_key(EmNeigh->neighbor[ineighme], EmFather->son[isonB]))
							break;
					if (!(ineighme < 4))
						printf("DANGER\n");
					assert(ineighme < 4);

					//Give my neighbor my contact information
					EmNeigh->neigh_gen[ineighme] = EmNeigh->neigh_gen[ineighme + 4] = EmFather->generation;

					EmNeigh->neigh_proc[ineighme + 4] = -2;

					if (EmNeigh->adapted == NEWFATHER) {
						//if my neighbor is a NEWFATHER, I need to update my
						//information about him too
						EmFather->neigh_gen[ineigh] = EmFather->neigh_gen[ineigh + 4] = EmNeigh->generation;

						EmFather->neigh_proc[ineigh + 4] = -2;

						//EmNeigh is inside this if() so only one loop through
						//KEYLENGTH is made, it saves on overhead
						for (ikey = 0; ikey < KEYLENGTH; ikey++) {
							EmFather->neighbor[ineigh][ikey] = EmFather->neighbor[ineigh + 4][ikey] =
							    EmNeigh->key[ikey];
							EmNeigh->neighbor[ineighme][ikey] = EmNeigh->neighbor[ineighme + 4][ikey] =
							    EmFather->key[ikey];
						}
					} else
						//EmNeigh is inside this if() so only one loop through
						//KEYLENGTH is made, it saves on overhead
						for (ikey = 0; ikey < KEYLENGTH; ikey++)
							EmNeigh->neighbor[ineighme][ikey] = EmNeigh->neighbor[ineighme + 4][ikey] =
							    EmFather->key[ikey];
				}
			}
	}

	return;
}
static void test_modules()
{
	printf ("Test mounting with modules\n");

	KDB *kdb = kdb_new();
	Key *errorKey = keyNew(0);
	KeySet *modules = modules_config();
	succeed_if (elektraMountOpen(kdb, root_config(), modules, errorKey) == 0, "could not buildup mount");
	succeed_if (elektraMountDefault(kdb, modules, errorKey) == 0, "could not mount default backend");
	succeed_if (elektraMountModules(kdb, modules, errorKey) == 0, "could not mount modules");

	succeed_if(output_warnings (errorKey), "warnings found");
	succeed_if(output_error (errorKey), "error found");

	succeed_if (kdb->split->size == 8, "size of split not correct");
	Key *mp = keyNew("spec", KEY_VALUE, "root", KEY_END);
	compare_key(mp, kdb->split->parents[0]);
	keySetName(mp, "dir"); keySetString (mp, "root");
	compare_key(mp, kdb->split->parents[1]);
	keySetName(mp, "user"); keySetString (mp, "root");
	compare_key(mp, kdb->split->parents[2]);
	keySetName(mp, "system"); keySetString (mp, "root");
	compare_key(mp, kdb->split->parents[3]);
	/* we cannot exactly know where resolver+dump is located
	 *(depending on alphabet)
	keySetName(mp, "system/elektra/modules/"KDB_DEFAULT_RESOLVER); keySetString (mp, "modules");
	compare_key(mp, kdb->split->parents[4]);
	*/
	keySetName(mp, "system/elektra"); keySetString (mp, "default");
	compare_key(mp, kdb->split->parents[5]);

	keySetName(mp, "user/tests/simple"); keySetString (mp, "simple");
	compare_key(mp, kdb->split->parents[4]);

	exit_if_fail (kdb->trie, "trie was not build up successfully");

	// output_trie (kdb->trie);

	Key *searchKey = keyNew("", KEY_END);
	Key *rmp = keyNew("", KEY_VALUE, "root", KEY_END);
	elektraKeySetName(rmp, "/", KEY_CASCADING_NAME);
	Backend *b2 = 0;

	keySetName (searchKey, "user");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, rmp);


	Backend *backend = 0;
	keySetName(searchKey, "user/tests/simple");
	backend = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, mp);


	keySetName(searchKey, "user/tests/simple/below");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);


	keySetName(searchKey, "user/tests/simple/deep/below");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);

	Key *dmp = keyNew ("", KEY_VALUE, "default", KEY_END);
	keySetName(searchKey, "system/elektra");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (b2 == kdb->defaultBackend, "should be the default backend");
	compare_key(b2->mountpoint, dmp);

	keySetName(searchKey, "system/elektra/below");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (b2 == kdb->defaultBackend, "should be the default backend");
	compare_key(b2->mountpoint, dmp);

	Key *mmp = keyNew ("system/elektra/modules", KEY_VALUE, "modules", KEY_END);
	keyAddBaseName (mmp, "default");

	/*
	keySetName(searchKey, "system/elektra/modules/default");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (b2 != kdb->defaultBackend, "should not be the default backend");
	compare_key(b2->mountpoint, mmp);
	*/

	keyDel (mmp);
	keyDel (dmp);
	keyDel (mp);
	keyDel (rmp);

	keyDel (searchKey);

	kdb_del (kdb);
	keyDel (errorKey);
	ksDel (modules);
}
static void test_default()
{
	printf ("Test mounting with default\n");

	KDB *kdb = kdb_new();
	Key *errorKey = keyNew(0);
	KeySet *modules = modules_config();
	succeed_if (elektraMountOpen(kdb, root_config(), modules, errorKey) == 0, "could not buildup mount");
	succeed_if (elektraMountDefault(kdb, modules, errorKey) == 0, "could not mount default backend");

	succeed_if (kdb->split->size == 6, "size of split not correct");
	Key *mp = keyNew("spec", KEY_VALUE, "root", KEY_END);
	compare_key(mp, kdb->split->parents[0]);
	keySetName(mp, "dir"); keySetString (mp, "root");
	compare_key(mp, kdb->split->parents[1]);
	keySetName(mp, "user"); keySetString (mp, "root");
	compare_key(mp, kdb->split->parents[2]);
	keySetName(mp, "system"); keySetString (mp, "root");
	compare_key(mp, kdb->split->parents[3]);
	keySetName(mp, "system/elektra"); keySetString (mp, "default");
	compare_key(mp, kdb->split->parents[5]);

	// must be last, needed later
	keySetName(mp, "user/tests/simple"); keySetString (mp, "simple");
	compare_key(mp, kdb->split->parents[4]);

	succeed_if(output_warnings (errorKey), "warnings found");
	succeed_if(output_error (errorKey), "error found");

	exit_if_fail (kdb->trie, "trie was not build up successfully");

	// output_trie (kdb->trie);

	Key *searchKey = keyNew("", KEY_END);
	Key *rmp = keyNew("", KEY_VALUE, "root", KEY_END);
	elektraKeySetName(rmp, "/", KEY_CASCADING_NAME);
	Backend *b2 = 0;

	keySetName (searchKey, "user");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	compare_key(b2->mountpoint, rmp);


	Backend *backend = 0;
	keySetName(searchKey, "user/tests/simple");
	backend = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (backend, "there should be a backend");
	compare_key(backend->mountpoint, mp);


	keySetName(searchKey, "user/tests/simple/below");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);


	keySetName(searchKey, "user/tests/simple/deep/below");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (backend == b2, "should be same backend");
	compare_key(b2->mountpoint, mp);

	Key *dmp = keyNew ("", KEY_VALUE, "default", KEY_END);
	keySetName(searchKey, "system/elektra");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (b2 == kdb->defaultBackend, "should be the default backend");
	compare_key(b2->mountpoint, dmp);

	keySetName(searchKey, "system/elektra/below");
	b2 = elektraTrieLookup(kdb->trie, searchKey);
	succeed_if (b2, "there should be a backend");
	succeed_if (b2 == kdb->defaultBackend, "should be the default backend");
	compare_key(b2->mountpoint, dmp);

	keyDel (dmp);
	keyDel (mp);
	keyDel (rmp);

	keyDel (searchKey);

	kdb_del (kdb);
	keyDel (errorKey);
	ksDel (modules);
}