private function deserializeHierarchy($values) {
    if ($this->isSerializedNode($values)) {
      // the values represent a node
      $result = $this->deserializeNode($values);
      $node = $result['node'];
      $values = $result['data'];
      $values[$node->getOID()->__toString()] = $node;
    }
    else {
      foreach ($values as $key => $value) {
        if (is_array($value) || is_object($value)) {
          // array/object value
          $result = $this->deserializeHierarchy($value);
          // flatten the array, if the deserialization result is only an array
          // with size 1 and the key is an oid (e.g. if a node was deserialized)
          if (is_array($result) && sizeof($result) == 1 && ObjectId::isValid(key($result))) {
            unset($values[$key]);
            $values[key($result)] = current($result);
          }
          else {
            $values[$key] = $result;
          }
        }
        else {
          // string value
          $values[$key] = $value;
        }
      }
    }
    return $values;
  }