__vdim_node *__vdim_insert(__vdim_node *tree, __vdim_node *inserting) {
   t_uuid rid,iid;
   __vdim_node *inserted;
   long CMP;
   if(tree==NULL) {
      return(inserting);
   } else {
   iid = inserting->id;
   rid = tree->id;
   CMP = CompareGuids(iid,rid);
   if(CMP<0) {
      inserted = __vdim_insert((__vdim_node *)tree->lesser, inserting);
      if (inserted!=NULL){
        tree->lesser = (__vdim_node *)inserting;
      }
      return(NULL);
   } else  if(CMP>0) {
      inserted = __vdim_insert((__vdim_node *)tree->greater, inserting);
      if (inserted!=NULL){
        tree->greater = (__vdim_node *)inserting;
      }
      return(NULL);
   } else {
      free(inserting); //already exists
   }
   }
  return(NULL);
}
__cdim_node *__cdim_recurse_find  (__cdim_node *parent,__cdim_node *node, t_uuid dimensionid){
  int CMP;
  if (node!=NULL){
    CMP = CompareGuids(dimensionid,node->dimensionid);
    if (CMP<0){
      return __cdim_recurse_find (node,node->lesser,dimensionid);
    }
    if (CMP>0){
      return __cdim_recurse_find (node,node->greater,dimensionid);
    }
    if (CMP==0){return node; }
  }
  return NULL;
}
__vdim_node *__vdim_recursefind(__vdim_node *tree, t_uuid id) {
   t_uuid rid ;
   long CMP;
   if(tree!=NULL){
   rid = tree->id;
   CMP = CompareGuids(id,rid);
   if(CMP==0){
     return(tree);
   } else {
     if(CMP<0){
      return(__vdim_recursefind((__vdim_node *)tree->lesser, id));
     } else  if(CMP>0) {
      return(__vdim_recursefind((__vdim_node *)tree->greater, id));
     }
   }
   }
  return(NULL); //if we get this far, we haven't found it.
}
__cdim_node *__cdim_recurse_find_insert  (__cdim_node *node, t_uuid dimensionid,__cdim_node *inserting){
  int CMP;
  if (node!=NULL){
    CMP = CompareGuids(dimensionid,node->dimensionid);
    if (CMP<0){
      if (node->lesser==NULL){
        node->lesser=inserting;
      } else {
        return __cdim_recurse_find_insert(node->lesser,dimensionid,inserting);
      }
    }
    if (CMP>0){
      if (node->greater==NULL){
        node->greater=inserting;
      } else {
        return __cdim_recurse_find_insert(node->greater,dimensionid,inserting);
      }
    }
    if (CMP==0){return node; }
  }
  return inserting;
}
__cdim_node *__cdim_find_dimension_node (__cdim_node *node,t_uuid dimensionid){
   __cdim_node *found,*result;
   int CMP;
   if (node!=NULL){
     found = __cdim_recurse_find(NULL,node,dimensionid);
     if (found!=NULL){
     CMP = CompareGuids(dimensionid,found->dimensionid);
     if (CMP!=0){
         result = __cdim_createnode();
         result->dimensionid = dimensionid;
         if (CMP>0){found->greater=node;}
         if (CMP<0){found->lesser=node;}
     } else {result=found;}
    } else {
      result = __cdim_createnode();
      result->dimensionid = dimensionid;
      __cdim_recurse_find_insert(node,dimensionid,result);
    }
   } else {
     result = __cdim_createnode();
     result->dimensionid = dimensionid;
   }
   return result;
}
//=============================================================================*
BAR_TypeLib::BAR_TypeLib(BAR_Callback& callback, const string& sLabel,
                         const IID& iidTlb,
                         const string& sTlbHost,
                         const string& sResourceIndex)
: m_callback(callback),
  m_sLabel(sLabel),
  m_iidTlb(iidTlb),
  m_pITlb(NULL),
  m_pTlbAttr(NULL)
{
    //=== search for type library host
    char* lpBuf = new char[1024];
    string sTlbPath;
    if ( 0 < ::SearchPath(NULL, sTlbHost.c_str(), NULL, 1024, lpBuf, NULL) )
    {
        sTlbPath = lpBuf;
    }
    else
    {
        Throw_RegisteringTlbFailed(E_FAIL, 
                                   wstring(L"could not find type library host")
                                   + L", name=" + ToWS(sTlbHost));
    }
    BAR_TRACE1(2, "found type library host, %s", sTlbPath.c_str());

    //=== load type library
    sTlbPath += "\\" + sResourceIndex;
    HRESULT hr = ::LoadTypeLib(CComBSTR(sTlbPath.c_str()).m_str, &m_pITlb);
    if ( FAILED(hr) )
    {
        Throw_RegisteringTlbFailed(hr, wstring(L"loading type library failed") 
                                       + L", path=" + ToWS(sTlbHost));
    }
    if ( m_pITlb == NULL )
    {
        Throw_FatalError(L"type library interface pointer is null");
    }

    //=== get tlb  attributes ... 
    hr = m_pITlb->GetLibAttr(&m_pTlbAttr);
    if ( FAILED(hr) )
    {
        Throw_RegisteringTlbFailed(hr, 
                                   wstring(L"could not access type library")
                                   + L" attributes, path=" 
                                   + ToWS(sTlbPath));
    }
    assert(m_pTlbAttr != NULL);
    if ( m_pTlbAttr == NULL )
    {
        Throw_FatalError(L"typelibrary attribute pointer is null");
    }

    //=== convert found and expected guid into strings
    CompareGuids(m_pTlbAttr->guid, m_iidTlb);

    //=== register type library
    const wchar_t* wsTlbPath = CComBSTR(sTlbPath.c_str()).m_str;
    hr = ::RegisterTypeLib(m_pITlb, (wchar_t*)wsTlbPath, NULL);
    if ( FAILED(hr) )
    {
        Throw_RegisteringTlbFailed(hr, wstring(L"path=") + ToWS(sTlbPath));
    }

    //== finished
    BAR_TRACE(2, "registering type library succeeded");
}