dwg_handle_name (Dwg_Data *restrict dwg, const char *restrict table,
                 const BITCODE_H restrict handle)
{
  BITCODE_BL i, num_entries = 0;
  BITCODE_H ctrl = NULL, *hdlv = NULL;
  Dwg_Object *obj;
  Dwg_Object_APPID_CONTROL *_obj; // just some random generic type
  Dwg_Header_Variables *vars = &dwg->header_vars;

  if (!dwg || !table || !handle)
    return NULL;
  if (!handle->absolute_ref)
    return NULL;
  // look for the _CONTROL table, and search for name in all entries
  ctrl = dwg_ctrl_table (dwg, table);
  if (!ctrl)
    { // TODO: silently search table_control. header_vars can be empty
      LOG_TRACE ("dwg_handle_name: Empty header_vars table %s\n", table);
      return 0;
    }
  obj = dwg_resolve_handle (dwg, ctrl->absolute_ref);
  if (!obj)
    {
      LOG_TRACE ("dwg_handle_name: Could not resolve table %s\n", table);
      return 0;
    }
  //if (obj->type == DWG_TYPE_DICTIONARY)
  //  return dwg_find_dicthandle_objname (dwg, ctrl, name);
  if (!dwg_obj_is_control (obj))
    {
      LOG_ERROR ("dwg_handle_name: Could not resolve CONTROL object %s "
                 "for table %s",
                 obj->name, table);
      return 0;
    }
  _obj = obj->tio.object->tio.APPID_CONTROL; // just a random type
  dwg_dynapi_entity_value (_obj, obj->name, "num_entries", &num_entries, NULL);
  if (!num_entries)
    return NULL;
  dwg_dynapi_entity_value (_obj, obj->name, "entries", &hdlv, NULL);
  if (!hdlv)
    return NULL;
  for (i = 0; i < num_entries; i++)
    {
      char *hdlname, *name;
      Dwg_Object *hobj;
      Dwg_Object_APPID *_o;
      int isnew = 0;
      bool ok;

      if (!hdlv[i])
        continue;
      hobj = dwg_resolve_handle (dwg, hdlv[i]->absolute_ref);
      if (!hobj || !hobj->tio.object || !hobj->tio.object->tio.APPID)
        continue;
      if (hdlv[i]->absolute_ref != handle->absolute_ref)
        continue;
      _o = hobj->tio.object->tio.APPID;
      name = hobj->name;
      /* For BLOCK search the BLOCK entities instead.
         The BLOCK_HEADER has only the abbrevated name, but we want "*D30", not "*D" */
      if (strEQc (table, "BLOCK") && hobj->fixedtype == DWG_TYPE_BLOCK_HEADER)
        {
          Dwg_Object_BLOCK_HEADER *_bh = hobj->tio.object->tio.BLOCK_HEADER;
          Dwg_Object *bo = dwg_ref_object (dwg, _bh->block_entity);
          if (bo != NULL && bo->fixedtype == DWG_TYPE_BLOCK)
            {
              _o = (Dwg_Object_APPID *)bo->tio.entity->tio.BLOCK;
              name = bo->name;
            }
        }
      ok = dwg_dynapi_entity_utf8text (_o, name, "name", &hdlname, &isnew, NULL);
      LOG_HANDLE (" %s.%s[%d] => %s.name: %s\n", obj->name, "entries", i,
                  hobj->name, hdlname ? hdlname : "NULL");
      if (ok)
        {
          if (!isnew) return strdup (hdlname);
          else return hdlname;
        }
      else
        return NULL;
    }
  return NULL;
}
dwg_handle_name (Dwg_Data *restrict dwg, const char *restrict table,
                 const BITCODE_H restrict handle)
{
  BITCODE_BL i, num_entries = 0;
  BITCODE_H ctrl = NULL, *hdlv = NULL;
  Dwg_Object *obj;
  Dwg_Object_APPID_CONTROL *_obj;  
  Dwg_Header_Variables *vars = &dwg->header_vars;

  if (!dwg || !table || !handle)
    return NULL;
  if (!handle->absolute_ref)
    return NULL;
   
  ctrl = dwg_ctrl_table (dwg, table);
  if (!ctrl)
    {  
      LOG_TRACE ("dwg_handle_name: Empty header_vars table %s\n", table);
      return 0;
    }
  obj = dwg_resolve_handle (dwg, ctrl->absolute_ref);
  if (!obj)
    {
      LOG_TRACE ("dwg_handle_name: Could not resolve table %s\n", table);
      return 0;
    }
   
   
  if (!dwg_obj_is_control (obj))
    {
      LOG_ERROR ("dwg_handle_name: Could not resolve CONTROL object %s "
                 "for table %s",
                 obj->name, table);
      return 0;
    }
  _obj = obj->tio.object->tio.APPID_CONTROL;  
  dwg_dynapi_entity_value (_obj, obj->name, "num_entries", &num_entries, NULL);
  if (!num_entries)
    return NULL;
  dwg_dynapi_entity_value (_obj, obj->name, "entries", &hdlv, NULL);
  if (!hdlv)
    return NULL;
  for (i = 0; i < num_entries; i++)
    {
      char *hdlname, *name;
      Dwg_Object *hobj;
      Dwg_Object_APPID *_o;
      int isnew = 0;
      bool ok;

      if (!hdlv[i])
        continue;
      hobj = dwg_resolve_handle (dwg, hdlv[i]->absolute_ref);
      if (!hobj || !hobj->tio.object || !hobj->tio.object->tio.APPID)
        continue;
      if (hdlv[i]->absolute_ref != handle->absolute_ref)
        continue;
      _o = hobj->tio.object->tio.APPID;
      name = hobj->name;
       
      if (strEQc (table, "BLOCK") && hobj->fixedtype == DWG_TYPE_BLOCK_HEADER)
        {
          Dwg_Object_BLOCK_HEADER *_bh = hobj->tio.object->tio.BLOCK_HEADER;
          Dwg_Object *bo = dwg_ref_object (dwg, _bh->block_entity);
          if (bo != NULL && bo->fixedtype == DWG_TYPE_BLOCK)
            {
              _o = (Dwg_Object_APPID *)bo->tio.entity->tio.BLOCK;
              name = bo->name;
            }
        }
      ok = dwg_dynapi_entity_utf8text (_o, name, "name", &hdlname, &isnew, NULL);
      LOG_HANDLE (" %s.%s[%d] => %s.name: %s\n", obj->name, "entries", i,
                  hobj->name, hdlname ? hdlname : "NULL");
      if (ok)
        {
          if (!isnew) return strdup (hdlname);
          else return hdlname;
        }
      else
        return NULL;
    }
  return NULL;
}