]> Creatis software - bbtk.git/blob - kernel/src/bbtkPackage.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkPackage.cxx
1
2 /*=========================================================================                                                                               
3   Program:   bbtk
4   Module:    $RCSfile: bbtkPackage.cxx,v $
5   Language:  C++
6   Date:      $Date: 2009/10/16 08:52:12 $
7   Version:   $Revision: 1.32 $
8 =========================================================================*/
9
10 /* ---------------------------------------------------------------------
11
12 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
13 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 *
15 *  This software is governed by the CeCILL-B license under French law and 
16 *  abiding by the rules of distribution of free software. You can  use, 
17 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
18 *  license as circulated by CEA, CNRS and INRIA at the following URL 
19 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
20 *  or in the file LICENSE.txt.
21 *
22 *  As a counterpart to the access to the source code and  rights to copy,
23 *  modify and redistribute granted by the license, users are provided only
24 *  with a limited warranty  and the software's author,  the holder of the
25 *  economic rights,  and the successive licensors  have only  limited
26 *  liability. 
27 *
28 *  The fact that you are presently reading this means that you have had
29 *  knowledge of the CeCILL-B license and that you accept its terms.
30 * ------------------------------------------------------------------------ */                                                                         
31
32 /**
33  *\file
34  *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered.
35  */
36 #include "bbtkPackage.h"
37 #include "bbtkComplexBlackBoxDescriptor.h"
38 #include "bbtkMessageManager.h"
39 #include "bbtkConfigurationFile.h"
40 #include <fstream>
41 #include <time.h>
42 #include "bbtkUtilities.h"
43
44 namespace bbtk
45 {
46   
47
48
49   //==========================================================================
50   /// Creates a new package
51   Package::Pointer Package::New(const std::string& name,
52                                 const std::string& author,
53                                 const std::string& description,
54                                 const std::string& version) 
55   {
56     bbtkDebugMessage("object",1,"##> Package::New('"<<name<<"',...)"
57                      <<bbtkendl);
58     Package::Pointer p = MakePointer(new Package(name,
59                                                author,
60                                                description,
61                                                version));
62     bbtkDebugMessage("object",2,"<## Package::New('"<<name<<"',...)"
63                      <<bbtkendl);
64     return p;
65   }
66   //==========================================================================
67
68   //==========================================================================
69   /// Ctor with the name of the package
70   Package::Package(const std::string& name,
71                    const std::string& author,
72                    const std::string& description,
73                    const std::string& version) 
74     :
75     mDynamicLibraryHandler(0),
76     mName(name),
77     mAuthor(author),
78     mDescription(description),
79     mVersion(version)
80   {
81     bbtkDebugMessage("object",2,"==> Package('"<<name<<"',...)"
82                      <<bbtkendl);
83     std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_temp_dir();
84     char c = default_doc_dir.c_str()[strlen(default_doc_dir.c_str())-1];
85     std::string url = default_doc_dir; 
86     if (c != '/' && c !='\\') url = url + "/";
87     url = url +  "temp_dir/" + name + "/index.html";    
88     
89     SetDocURL(url);
90     SetDocRelativeURL("Relative url not set");
91
92     /*
93     std::string relurl(BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH));
94     relurl += "/packages/"+name+"/bbdoc/index.html";
95     std::string url = ConfigurationFile::GetInstance().Get_url()
96       + relurl; 
97     SetDocURL(url);
98     SetDocRelativeURL(relurl);   
99     */
100
101     //    std::cout  << "   url=["<<url<<"]"<<std::endl;
102     //    std::cout  << "relurl=["<<relurl<<"]"<<std::endl;
103     bbtkDebugMessage("object",2,"<== Package::Package('"<<name<<"',...) OK"
104                      <<bbtkendl);
105
106   }
107   //==========================================================================
108
109
110
111   //==========================================================================
112   /// Dtor
113   Package::~Package()
114   {
115     bbtkDebugMessage("object",2,"==> ~Package(\""<<mName<<"\")"<<bbtkendl);
116   }
117   //==========================================================================
118
119
120   //==========================================================================
121   void PackageReleaseBlackBoxDescriptorInternal(Package::WeakPointer pack,
122                                                 const std::string& descname)
123   {
124     // Try to release descriptor
125     std::string packname = pack.lock()->GetName();
126     
127     bbtkDebugMessage("package",5,"--- Releasing descriptor '"
128                      <<packname<<"::"<<descname<<"'"<<bbtkendl);
129     
130     
131     Package::DescriptorMapType::iterator desc = 
132       pack.lock()->GetDescriptorMap().find(descname);
133     if (desc ==  pack.lock()->GetDescriptorMap().end())
134       {
135         bbtkDebugMessage("package",5,
136                          "    Descriptor has already been released"
137                                  <<bbtkendl);
138         return;
139                   }
140     //    bbtkDebugMessage("package",3,
141     //               "    Trying unreferencing it ... "<<std::endl);
142     BlackBoxDescriptor::WeakPointer pdesc = desc->second;
143     desc->second.reset();
144     // if it is dead : remove it 
145     if (pdesc.expired()) 
146       {
147         bbtkDebugMessage("package",2," ==> '"<<packname<<"::"<<descname<<"' Descriptor expired"<<bbtkendl);
148         if (pack.expired()) 
149           {
150             bbtkDebugMessage("package",2,
151                                          "     ... and caused its package death"
152                              <<bbtkendl);
153             return;
154           } // pack.expired
155         desc = pack.lock()->GetDescriptorMap().find(descname);
156         if (desc !=  pack.lock()->GetDescriptorMap().end())       pack.lock()->GetDescriptorMap().erase(desc);
157       }   else    {  //pdesc.expired
158       bbtkDebugMessage("package",5,"    ... Descriptor still alive ("
159                        <<pdesc.use_count()<<" refs)"
160                        <<bbtkendl);
161       pack.lock()->GetDescriptorMap()[descname] = pdesc.lock();
162     } // pdesc.expired
163   }
164   //==========================================================================
165
166
167   //==========================================================================
168   /// Release
169   void Package::Release(Package::WeakPointer pack)
170   {
171     std::string packname = pack.lock()->mName;
172     bbtkDebugMessage("package",1,"==> Package::Release('"<<
173                      packname<<"')"<<bbtkendl);
174
175     long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
176     long ndesc = pack.lock()->GetDescriptorMap().size();
177     long nrefs = pack.use_count();
178
179     bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
180                      <<ndesc<<" descr / dyn="
181                      <<dyn<<std::endl);
182
183     // A package is "free" from any external reference iff :
184     // i) It is not dynamically loaded and nrefs == ndesc 
185     // (each desc references its package) or
186     // ii) It is dynamically loaded and nrefs == ndesc + 1
187     // (A dynamic library holds a static pointer on the package it contains
188     //  which is allocated when the PACKAGENAMEGetPackage() func is called,
189     //  and descallocated (reset) by PACKAGENAMEDeletePackage())
190     if (nrefs == ndesc + dyn) 
191       {
192         bbtkDebugMessage("package",5,
193                          " -> No more external ref : checking descriptors"
194                          <<bbtkendl);
195         // We must take care that removing refs on descriptors 
196         // can lead to their deletion which can in turn unref 
197         // internal boxes which can release their descriptors hence 
198         // call Package::ReleaseBlackBoxDescriptor 
199         // As a consequence during descriptors release :
200         // 1) The map can change dynamically : we cannot iterate over it 
201         //    as any iterator can become invalid
202         // 2) The package can auto-destruct : we must test its existence 
203         //    after each release
204         // We must also take care of not locking the package pointer 
205         // or any ref count check in Package::ReleaseBlackBoxDescriptor
206         // would be wrong
207
208         // The list of descriptors names at start
209         std::vector<std::string> descnamelist;
210         DescriptorMapType::iterator i;
211         for (i=pack.lock()->mDescriptorMap.begin();
212              i!= pack.lock()->mDescriptorMap.end();
213              ++i)
214           descnamelist.push_back(i->first);
215
216         // Iterator over the initial names
217         std::vector<std::string>::iterator descname;
218         for (descname=descnamelist.begin();
219              descname!=descnamelist.end();
220              ++descname)
221           {
222             // Is package still alive ?
223             if (pack.expired()) 
224               {
225                 bbtkDebugMessage("package",1,"--- Package::Release('"<<
226                                  packname
227                                  <<"') : package expired during release : bailing out"<<bbtkendl);
228                 break;
229               }
230             
231 #if defined(MACOSX)
232                   BlackBoxDescriptor::Pointer desc = pack.lock()->mDescriptorMap[*descname];
233                   if ( (dyn==0) || (boost::dynamic_pointer_cast<ComplexBlackBoxDescriptor>(desc)) )
234                   {
235                           PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
236                   } 
237 #else
238                   PackageReleaseBlackBoxDescriptorInternal(pack,*descname);
239 #endif
240
241           }
242
243         //
244         UnLoadDynamicLibrary(pack);
245         // Unload orphan dl packages 
246         Package::UnLoadReleasedDynamicallyLoadedPackages();
247         
248
249         
250         
251       }
252     
253 #ifdef BBTK_COMPILE_DEBUG_MESSAGES
254
255     bbtkDebugMessage("package",2,"<== Package::Release('"<<
256                      packname<<"')"<<bbtkendl);
257
258     if (!pack.expired())
259       {
260         long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
261         long ndesc = pack.lock()->GetDescriptorMap().size();
262         long nrefs = pack.use_count();
263         
264         bbtkDebugMessage("package",1," ... Package still alive ("
265                          <<nrefs<<" refs / "
266                          <<ndesc<<" descr / dyn="
267                          <<dyn<<")"<<std::endl);
268       }
269     else 
270       {
271         bbtkDebugMessage("package",1," ... Package has been released"
272                          <<std::endl);
273       }
274 #endif
275   }
276   //==========================================================================
277
278   //==========================================================================
279   /// "Releases" the package
280   /// Signals the package that it can free the given descriptor
281   /// if they are no more used and free itself if it is no
282   /// more used
283   /// Note : Any non-weak pointer on the package must have been freed
284   void Package::ReleaseBlackBoxDescriptor(Package::WeakPointer pack,
285                                           BlackBoxDescriptor::WeakPointer descr)
286   {
287     std::string packname = pack.lock()->mName;
288     std::string dname = descr.lock()->GetTypeName();    
289     bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<<
290                      packname<<"','"<<dname<<"') : refs="
291                      <<descr.use_count()<<bbtkendl);
292
293     long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
294     long ndesc = pack.lock()->GetDescriptorMap().size();
295     long nrefs = pack.use_count();
296
297     bbtkDebugMessage("package",5," "<<nrefs<<" refs / "
298                      <<ndesc<<" descr / dynamically loaded = "
299                      <<dyn<<std::endl);
300
301     // A package is "free" from any external reference iff :
302     // i) It is not dynamically loaded and nrefs == ndesc 
303     // (each desc references its package) or
304     // ii) It is dynamically loaded and nrefs == ndesc + 1
305     // (A dynamic library holds a static pointer on the package it contains
306     //  which is allocated when the PACKAGENAMEGetPackage() func is called,
307     //  and descallocated (reset) by PACKAGENAMEDeletePackage())
308     if (nrefs == ndesc + dyn) 
309       {
310 #if defined(MACOSX)
311                   //
312                   if (dyn==0)
313                           PackageReleaseBlackBoxDescriptorInternal(pack,dname);
314 #else
315                   PackageReleaseBlackBoxDescriptorInternal(pack,dname);
316 #endif  
317       }
318     
319     // If the package is released and dynamically loaded 
320     // then put it in the static list mReleasedDynamicallyLoadedPackages
321     UnLoadDynamicLibrary(pack,false);
322         
323     bbtkDebugMessage("package",4,"<== Package::ReleaseBlackBoxDescriptor('"<<
324                      packname<<"','"<<dname<<"'): refs="
325                      <<descr.use_count()<<bbtkendl);
326     /*
327     if (!pack.expired())
328       {
329         long dyn = pack.lock()->mDynamicLibraryHandler ? 1:0; 
330         long ndesc = pack.lock()->GetDescriptorMap().size();
331         long nrefs = pack.use_count();
332         
333         bbtkDebugMessage("package",3," ... Package still alive ("
334                          <<nrefs<<" refs / "
335                          <<ndesc<<" descr / dyn="
336                          <<dyn<<")"<<std::endl);
337       }
338     else 
339       {
340         bbtkDebugMessage("package",3,"   ... Package has been released"
341                          <<std::endl);
342       }  
343     */
344   }
345   //==========================================================================    
346
347   //==========================================================================
348   /// Opens a dynamic library which contains a bbtk package
349   /// Returns the handler 
350   /// Load the package management symbols from the lib
351   /// returns false if a problem occured hence can be used 
352   /// to test that a dyn lib is a valid bbtk package lib
353   /// NB : The BBTK version exported from the library 
354   ///      is tested against the current bbtk version
355   DynamicLibraryHandler Package::OpenDynamicLibrary
356   ( const std::string& libname,
357     const std::string& package_name,
358     DLGetPackageFunction& getpack,
359     DLDeletePackageFunction& delpack)
360   {
361     bbtkDebugMessage("package",3,"==> Package::OpenDynamicLibrary("
362                      <<libname<<")"<<std::endl);
363 #if defined(__GNUC__)
364
365     // Open shared lib
366     void *handler;
367     handler = dlopen(libname.c_str(), BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
368 //EED     handler = dlopen(libname.c_str(), RTLD_LAZY | RTLD_LOCAL );
369           
370     if (!handler)
371       {
372         bbtkMessage("package",2,
373                     "Could not open shared library [" <<libname<<"] : "
374                     <<dlerror() << std::endl);
375         return 0;
376       }
377
378     bbtkDebugMessage("package",3,"* Shared lib ["<<libname<<"] open"<<std::endl);
379
380     // Loads the Package bbtk version function 
381     std::string getvername(package_name);
382     getvername += 
383       BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
384     DLGetPackageBBTKVersionFunction getbbtkversion 
385       = (DLGetPackageBBTKVersionFunction)(dlsym(handler,getvername.c_str()));
386     if (!getbbtkversion)
387       {
388         bbtkDebugMessage("package",3,"***"<<std::endl);
389         bbtkMessage("package",2,
390                     "Shared library ["<<libname
391                     <<"] is not a valid bbtk package."
392                     <<" Symbol ["<<getvername<<"] :"<<dlerror()<< std::endl);
393         dlclose(handler);
394         return 0;
395       }
396
397     bbtkDebugMessage("package",3,"* Symbol ["<<getvername
398                      <<"] found"<<std::endl);
399     // version matches ?
400     if (getbbtkversion() != bbtk::GetVersion())
401       {
402         bbtkMessage("package",2,
403                     "Shared library ["<<libname
404                     <<"] was build with bbtk version "
405                     <<getbbtkversion()
406                     <<" but the current program runs with version "
407                     <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
408         dlclose(handler);
409         return 0;
410         
411       }
412
413     bbtkDebugMessage("package",3,"* Package bbtk version '"<<getbbtkversion()<<"' matches"<<std::endl);
414             // Loads the Package get function
415     std::string getpackname(package_name);
416     getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
417     getpack = (DLGetPackageFunction)(dlsym(handler, getpackname.c_str()));
418     if (!getpack)
419       {
420         bbtkMessage("package",2,
421                     "Shared library ["<<libname
422                     <<"] is not a valid bbtk package."
423                     <<" Symbol ["<<getpackname<<"] :"<<dlerror()<< std::endl);
424         dlclose(handler);
425         return 0;
426       }
427   
428     bbtkDebugMessage("package",3,"* Symbol ["<<getpackname<<"] found"<<std::endl);
429     // Loads the Package delete function
430                                           
431     std::string delpackname(package_name);
432     delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
433     delpack = (DLDeletePackageFunction)(dlsym(handler, delpackname.c_str()));
434     if (!delpack)
435       {
436         bbtkMessage("package",2,
437                     "Shared library ["<<libname
438                     <<"] is not a valid bbtk package."
439                     <<" Symbol ["<<delpackname<<"] :"<<dlerror()<< std::endl);
440         dlclose(handler);
441         return 0;
442       }
443     bbtkDebugMessage("package",3,"* Symbol ["<<delpackname<<"] found"<<std::endl);                
444 #elif defined(_WIN32)
445     
446     HINSTANCE handler;
447     
448     SetErrorMode(0);
449     // Open shared lib
450     handler = LoadLibrary(libname.c_str());
451     if (!handler)
452       {
453         bbtkMessage("package",2,
454                     "Could not open shared library [" <<libname<<"]"
455                     << std::endl);
456         DWORD dwErrorCode = 0;
457         dwErrorCode = GetLastError();
458         bbtkMessage("package",2,
459                 "Windows Error: [" << dwErrorCode <<"]"
460                 << std::endl);
461          
462         return 0;
463       }
464     
465     // Loads the Package bbtk version function 
466     std::string getvername(package_name);
467     getvername += 
468       BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_BBTK_VERSION_FUNCTION_NAME);
469     DLGetPackageBBTKVersionFunction getbbtkversion 
470       = (DLGetPackageBBTKVersionFunction)(GetProcAddress(handler,
471                                                         getvername.c_str()));
472     if (!getbbtkversion)
473       {
474         FreeLibrary(handler);
475         bbtkMessage("package",2,
476                     "Shared library ["<<libname
477                     <<"] is not a valid bbtk package."
478                     <<" Symbol ["<<getbbtkversion<<"] not found"<< std::endl);
479         return 0;
480       }
481     
482     // version matches ?
483     if (getbbtkversion() != bbtk::GetVersion())
484       {
485         FreeLibrary(handler);
486         bbtkMessage("package",2,
487                     "Shared library ["<<libname
488                     <<"] was build with bbtk version "
489                     <<getbbtkversion()
490                     <<" but the current program runs with version "
491                     <<bbtk::GetVersion()<<" : cannot load it"<<std::endl);
492         return 0;
493         
494       }
495
496      // Loads the Package get function
497     std::string getpackname(package_name);
498     getpackname += BBTK_STRINGIFY_SYMBOL(BBTK_GET_PACKAGE_FUNCTION_NAME);
499     getpack = (DLGetPackageFunction)(GetProcAddress(handler, getpackname.c_str()));
500     if (!getpack)
501       {
502         FreeLibrary(handler);
503         bbtkMessage("package",2,
504                     "Shared library ["<<libname
505                     <<"] is not a valid bbtk package."
506                     <<" Symbol ["<<getpackname<<"] not found"<< std::endl);
507         return 0;
508       }
509     
510     // Loads the Package delete function
511     std::string delpackname(package_name);
512     delpackname += BBTK_STRINGIFY_SYMBOL(BBTK_DEL_PACKAGE_FUNCTION_NAME);
513     delpack = (DLDeletePackageFunction)(GetProcAddress(handler, delpackname.c_str()));
514     if (!delpack)
515       {
516         FreeLibrary(handler);
517         bbtkMessage("package",2,
518                     "Shared library ["<<libname
519                     <<"] is not a valid bbtk package."
520                     <<" Symbol ["<<delpackname<<"] not found"<< std::endl);
521         return 0;
522       }
523                                          
524 #else
525     bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
526 #endif
527     
528     return handler;
529   }
530   //==========================================================================
531   
532   //==========================================================================
533   /// Loads a package from a dynamic library
534   Package::Pointer Package::CreateFromDynamicLibrary(const std::string& libname,
535                                                      const std::string& pkgname,
536                                                      const std::string& path)
537   {
538     bbtkDebugMessage("package",1,"==> Package::CreateFromDynamicLibrary("
539                      <<libname<<")"<<std::endl);
540
541     DLGetPackageFunction gf;
542     DLDeletePackageFunction df;
543     DynamicLibraryHandler h = Package::OpenDynamicLibrary(libname,
544                                                           pkgname,
545                                                           gf,df);
546     if (h==0) return Package::Pointer(); 
547     Package::Pointer p = gf();
548     p->mDynamicLibraryHandler = h;
549     p->mDLDeletePackageFunction = df;
550     
551     std::string separator =
552       ConfigurationFile::GetInstance().Get_file_separator ();
553     //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
554     std::string docreldoc = 
555       separator + "bbdoc" + separator + pkgname + separator + "index.html";
556     std::string reldoc = 
557       ".." + separator + ".." + docreldoc;
558     std::string doc = path + separator + ".." + separator
559       + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
560       + docreldoc;
561     
562     p->SetDocURL(doc);
563     p->SetDocRelativeURL(reldoc);
564     
565     bbtkDebugMessage("package",2,"<== Package::CreateFromDynamicLibrary("
566                      <<libname<<") .. OK"<<std::endl);
567     return p;
568   }
569   //==========================================================================
570
571
572
573
574   //==========================================================================
575   /// UnLoads the package dynamic library (if any)
576   void Package::UnLoadDynamicLibrary(Package::WeakPointer pack, bool doit)
577   {
578     if (pack.expired() || (!pack.lock()->mDynamicLibraryHandler))
579       return;
580     
581     
582     std::string packname = pack.lock()->GetName();
583     bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('"
584                      <<packname<<"')"
585                      <<std::endl);
586     
587     if (!pack.lock()->GetDescriptorMap().empty())
588       {
589         
590         bbtkDebugMessage("package",5,"   Package not empty ... abort"
591                          <<std::endl);
592         return;
593         /*
594         bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
595                         <<"DescriptorMap not empty "
596                         <<BBTK_INTERNAL_ERROR_MESSAGE);
597         */
598         
599       }
600
601     if (pack.use_count()!=1)
602       {
603         bbtkGlobalError("Package::UnLoadDynamicLibrary('"<<packname<<") : "
604                         <<"empty dl package with external refs"
605                         <<BBTK_INTERNAL_ERROR_MESSAGE);
606       } 
607
608     if (doit) 
609       {
610         UnLoad(pack);
611         bbtkDebugMessage("package",5,"==> dynamic library for package '"
612                          <<packname<<"' closed"
613                          <<std::endl);    
614       }
615     else 
616       {
617         mReleasedDynamicallyLoadedPackages.insert(pack);
618         bbtkDebugMessage("package",1,"==> package '"<<packname
619                          <<"' put in the 'to unload' list"
620                          <<std::endl);
621
622       }
623
624     bbtkDebugMessage("package",5,"<== Package::UnLoadDynamicLibrary('"
625                      <<packname<<"')"
626                      <<std::endl);
627     
628   }
629   //==========================================================================
630
631   //==========================================================================
632   /// UnLoads released packages that were loaded dynamically
633   /// see UnLoadDynamicLibrary and ReleaseBlackBoxDescriptor
634   void Package::UnLoadReleasedDynamicallyLoadedPackages()
635   {
636     bbtkDebugMessage("package",5,"==> Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
637
638     std::set<Package::WeakPointer>::iterator i;
639
640 //JCP- 21-04-09
641         if(mReleasedDynamicallyLoadedPackages.size()>0){
642                 for (i=mReleasedDynamicallyLoadedPackages.begin();
643                 i!=mReleasedDynamicallyLoadedPackages.end();
644                 ++i)
645                 {
646                 if (!i->expired()) UnLoad(*i);
647                 }
648         }
649 //JCP- 21-04-09
650     bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<<std::endl);
651   }
652   //==========================================================================
653
654   //==========================================================================
655   void Package::UnLoad(Package::WeakPointer pack)
656   {
657     std::string packname = pack.lock()->GetName();
658     bbtkDebugMessage("package",6,"==> Package::UnLoad("<<packname<<")"<<std::endl);
659
660     Package* p = pack.lock().get();
661     
662     DynamicLibraryHandler h = p->mDynamicLibraryHandler;
663     
664     // deletes the package
665     p->mDLDeletePackageFunction();
666     
667     // closes the dl handler
668 #if defined(__GNUC__)  
669           if (dlclose(h)!=0)
670           {
671                   printf("EED Package::UnLoad ERROR %s\n", packname.c_str() );
672                   bbtkWarning("Failed to close dynamic library for package '"<<packname
673                                           <<"'"<<std::endl);
674           }  
675           
676 #elif defined(_WIN32)
677     FreeLibrary(h);
678 #endif
679
680     bbtkDebugMessage("package",1,"==> dynamic library for package '"
681                      <<packname<<"' closed"
682                      <<std::endl);    
683     bbtkDebugMessage("package",6,"   ... dynamic library unloaded"<<std::endl);
684   }
685   //==========================================================================
686
687   //==========================================================================
688   /// Creates an instance of a black box of type <type> with name <name>
689   BlackBox::Pointer Package::NewBlackBox(const std::string& type, 
690                                          const std::string& name) const
691   {
692     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::NewBlackBox(\""<<type<<"\",\""<<name<<"\")"<<bbtkendl);
693     
694     DescriptorMapType::const_iterator i = mDescriptorMap.find(type);
695     if (i == mDescriptorMap.end())  
696     {
697            bbtkDebugDecTab("kernel",8);
698            return BlackBox::Pointer();
699     }
700     BlackBox::Pointer bb =i->second->NewBlackBox(name);
701     bbtkDebugDecTab("kernel",8);
702     return bb;   
703
704   }
705   //==========================================================================
706
707
708
709   //==========================================================================
710   /// Creates an instance of an adaptor of input type <typein> and 
711   /// output type <typeout>  with name <name>
712   BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein,
713                                 const DataInfo& typeout,
714                                 const std::string& name) const
715   {
716     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
717                         ">::NewAdaptor("
718                         <<typein<<","
719                         <<typeout<<",\""
720                         <<name<<"\")"<<bbtkendl);
721
722     AdaptorKey key(typein,typeout,
723                    BlackBoxDescriptor::DEFAULT_ADAPTOR);
724     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
725     if (i == mAdaptorMap.end())  
726       {
727         bbtkDebugDecTab("kernel",8);
728         return BlackBox::Pointer();
729       }
730     BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
731     bbtkDebugDecTab("kernel",8);
732     return bb;   
733
734   }
735   //==========================================================================
736
737   //==========================================================================
738   /// Creates an instance of an adaptor of input type <typein> and 
739   /// output type <typeout>  with name <name>
740   BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein,
741                                       const DataInfo& typeout,
742                                       const std::string& name) const
743   {
744     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
745                         ">::NewWidgetAdaptor("
746                         <<typein<<","
747                         <<typeout<<",\""
748                         <<name<<"\")"<<bbtkendl);
749
750     AdaptorKey key(typein,typeout,
751                    BlackBoxDescriptor::DEFAULT_GUI);
752     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
753     if (i == mAdaptorMap.end())  
754       {
755         bbtkDebugDecTab("kernel",8);
756         return BlackBox::Pointer();
757       }
758     BlackBox::Pointer bb =i->second.lock()->NewBlackBox(name);
759     bbtkDebugDecTab("kernel",8);
760     return bb;   
761
762   }
763   //==========================================================================
764
765
766
767   //==========================================================================
768   /// Returns true is the package contains 
769   /// an adaptor of input type <typein> and 
770   /// output type <typeout>
771   /// If successfull then adaptor contains the black box type name
772   bool Package::FindWidgetAdaptor(const DataInfo& typein,
773                                   const DataInfo& typeout,
774                                   std::string& adaptor) const
775   {
776     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
777                         ">::FindWidgetAdaptor("
778                         <<typein<<","
779                         <<typeout<<")"<<bbtkendl);
780    
781     AdaptorKey key(/*typein*/
782                    DataInfo(typeid(void),""),
783                    typeout,
784                    BlackBoxDescriptor::DEFAULT_GUI);
785     // First try to find a single widget adaptor
786     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
787     if (i == mAdaptorMap.end())  
788       {
789         bbtkDebugDecTab("kernel",8);
790         return false;
791       }
792     adaptor = i->second.lock()->GetTypeName();
793     bbtkDebugDecTab("kernel",8);
794     return true;   
795
796   }
797   //==========================================================================
798
799
800
801   //==========================================================================
802   /// Returns true is the package contains 
803   /// an adaptor of input type <typein> and 
804   /// output type <typeout>
805   /// If successfull then adaptor contains the black box type name
806   bool Package::FindAdaptor(const DataInfo& typein,
807                             const DataInfo& typeout,
808                             std::string& adaptor) const
809   {
810     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<
811                         ">::FindAdaptor("
812                         <<typein<<","
813                         <<typeout<<")"<<bbtkendl);
814     
815     AdaptorKey key(typein,typeout,
816                    BlackBoxDescriptor::DEFAULT_ADAPTOR);
817     AdaptorMapType::const_iterator i = mAdaptorMap.find(key);
818     if (i == mAdaptorMap.end())  
819       {
820         bbtkDebugDecTab("kernel",8);
821         return false;
822       }
823     adaptor = i->second.lock()->GetTypeName();
824     bbtkDebugDecTab("kernel",8);
825     return true;   
826
827   }
828   //==========================================================================
829
830
831   //==========================================================================
832   /// Registers a black box descriptor in the package
833   bool Package::Register(BlackBoxDescriptor::Pointer d) 
834   {
835     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\")"<<std::endl);
836     
837     DescriptorMapType::iterator i = mDescriptorMap.find(d->GetTypeName());
838     if (i!=mDescriptorMap.end())
839       {
840         bbtkWarning("Package<"<<GetName()<<"> : Trying to register box type <"
841                     <<d->GetTypeName()<<"> which is already in the package");
842         return false;
843       }
844
845     mDescriptorMap[d->GetTypeName()] = d;
846     //    d->Reference();
847     d->SetPackage(GetThisPointer<Package>());
848     
849     // If it is a default adaptor, also register it in the adaptors map
850     if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR )
851       {
852         bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<<std::endl);   
853         
854         TypeInfo typein = d->GetInputDescriptor("In")->GetTypeInfo();
855         TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
856         DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature());
857         DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
858         AdaptorKey key(infoin,infoout,d->GetKind());
859         
860         AdaptorMapType::const_iterator i;
861         i = mAdaptorMap.find(key);        
862         if (i == mAdaptorMap.end())  
863           {
864             mAdaptorMap[key] = d;
865           }
866         // If already an adaptor registered : error
867         else 
868           {
869             if (i->second.lock()->GetTypeName() != d->GetTypeName()) 
870               {
871                 bbtkError("Package <"<<GetName()<<
872                           "> : trying to register black box <"
873                           <<d->GetTypeName()
874                           <<"> as default adaptor but there is already a default adaptor registered (<"
875                           <<i->second.lock()->GetTypeName()<<">)");
876               }
877           }
878       }
879     // If it is a default adaptor, also register it in the adaptors map
880     else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI)
881       {
882         bbtkDebugMessage("kernel",8,"Package<"<<GetName()<<">::Register(\""<<d->GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<<std::endl);   
883         
884         TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo();
885         DataInfo infoin(typeid(void),"");
886         DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature());
887         AdaptorKey key(infoin,infoout,d->GetKind());
888
889         AdaptorMapType::const_iterator i;
890         i = mAdaptorMap.find(key);        
891         if (i == mAdaptorMap.end())  
892           {
893             mAdaptorMap[key] = d;
894           }
895         // If already an adaptor registered : error
896         else 
897           {
898             if (i->second.lock()->GetTypeName() != d->GetTypeName()) 
899               {
900                 bbtkError("Package <"<<GetName()<<
901                           "> : trying to register black box <"
902                           <<d->GetTypeName()
903                           <<"> as default widget adaptor but there is already a default adaptor registered (<"
904                           <<i->second.lock()->GetTypeName()<<">)");
905               }
906           }
907       }
908     
909
910     bbtkDebugDecTab("kernel",8);
911    
912     return true;
913   }
914   //==========================================================================
915   
916   //===================================================================
917   void Package::Check() const
918   {
919     bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
920                 <<" ["<<GetName()<<"]"<<std::endl);
921     DescriptorMapType::const_iterator i;
922     for (i=mDescriptorMap.begin();
923          i!=mDescriptorMap.end();
924          ++i) 
925       {
926         i->second->Check(true);
927       }
928     bbtkMessage("debug",1,"****** Checking Package "<<(void*)this
929                 <<" ["<<GetName()<<"] ... OK"<<std::endl);
930   }
931   //===================================================================
932
933
934   //==========================================================================
935   /// Changes the name of a black box type
936   void Package::ChangeDescriptorName( const std::string& oldname, const std::string& newname )
937   { 
938     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
939                         <<">::ChangeDescriptorName(\""<<oldname
940                         <<"\",\""<<newname<<"\")"<<std::endl);
941     // Looking into the bb map
942     DescriptorMapType::iterator i = mDescriptorMap.find(oldname);
943     if (i == mDescriptorMap.end())  
944       {
945          bbtkDebugDecTab("kernel",8);
946          bbtkError("ChangeDescriptorName : The package <"<<GetName()<<"> does not contains the black box <"<<oldname<<">");
947       }
948
949     i->second->SetTypeName(newname);
950     mDescriptorMap[newname] = i->second;
951     mDescriptorMap.erase(i);
952
953     bbtkDebugDecTab("kernel",8);    
954   }
955   //==========================================================================
956
957
958
959   //==========================================================================
960   void Package::PrintHelpListDescriptors(bool description, bool adaptors) const
961   {
962     unsigned int lmax = 0;
963     std::vector<std::string> names;
964     std::vector<std::string> kinds;
965     std::vector<std::string> descrs;
966
967     DescriptorMapType::const_iterator i;
968     for (i=mDescriptorMap.begin();
969          i!=mDescriptorMap.end();
970          ++i) 
971       {
972         if ( adaptors || 
973              ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) ) 
974           {
975             std::string name("  ");
976             name += i->second->GetTypeName();
977             names.push_back(name);
978
979             std::string kind;
980             if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR )
981               {
982                 kind = std::string("[A]");
983               }
984             else if ( i->second->GetKind() == 
985                       BlackBoxDescriptor::DEFAULT_ADAPTOR )
986               {
987                 kind = std::string("[DA]");
988               }
989             kinds.push_back(kind);
990
991             unsigned int l = name.size()+kind.size();
992             if (l>lmax) lmax = l;
993
994             std::string descr;
995             if (description) 
996               {
997                 descr += " : ";
998                 descr += i->second->GetDescription();
999               } 
1000             descrs.push_back(descr);
1001           }
1002       } 
1003     
1004
1005     std::string offs;
1006     offs.append(lmax+3,' ');
1007     std::vector<std::string>::iterator ni,ci,di;
1008     for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin();
1009          ni != names.end(); ++ni, ++ci, ++di)
1010       {
1011         std::string space;
1012         space.append(lmax - ni->size() - ci->size(),' ');
1013         bbtkMessage("help",1,*ni << space << *ci );
1014         std::string d(*di);
1015         unsigned int dmax = 75 - lmax;
1016         //      while (d.size() > dmax ) 
1017         //  {
1018         if (d.size()>dmax) 
1019           bbtkMessage("help",1,d.substr(0,dmax) << "..." << std::endl);
1020         else 
1021           bbtkMessage("help",1,d << std::endl);
1022         //    d = d.substr(dmax,d.size());
1023         //  }
1024       }
1025
1026   }
1027   //==========================================================================
1028
1029   //==========================================================================
1030   /// Displays the list of adaptors of the package
1031   void Package::PrintHelpListAdaptors(bool description) const
1032   {
1033     DescriptorMapType::const_iterator i;
1034     for (i=mDescriptorMap.begin();
1035          i!=mDescriptorMap.end();
1036          ++i) 
1037       {
1038         if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD ) 
1039           {
1040             bbtkMessage("help",1,
1041                         "  "<<i->second->GetTypeName());
1042             if ( i->second->GetKind() == 
1043                  BlackBoxDescriptor::DEFAULT_ADAPTOR )
1044               {
1045                 bbtkMessage("help",1,
1046                             " [default]");
1047               }  
1048             if (description) 
1049               {
1050                 bbtkMessage("help",1,
1051                             " : "<<i->second->GetDescription());
1052
1053               } 
1054             bbtkMessage("help",1,std::endl);
1055           }
1056       } 
1057     /*
1058     AdaptorMapType::const_iterator i;
1059     for (i=mAdaptorMap.begin();
1060          i!=mAdaptorMap.end();
1061          ++i) 
1062       {
1063         bbtkMessage("help",1,
1064                     "  "<<i->second->GetTypeName());
1065         if (detail_level>0) 
1066           {
1067             bbtkMessage("help",1,
1068                         " : "<<i->second->GetDescription());
1069   
1070           } 
1071         bbtkMessage("help",1,std::endl);
1072       }
1073     */ 
1074   }
1075   //==========================================================================
1076
1077   //==========================================================================
1078   /// Prints help on a black box descriptor
1079   void Package::PrintHelpDescriptor(const std::string& name, bool full) const
1080   {
1081     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1082                         <<">::PrintHelpDescriptor(\""
1083                         <<name<<"\")"<<bbtkendl);
1084
1085     DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1086     if (i == mDescriptorMap.end())  
1087       {
1088         bbtkDebugDecTab("kernel",8);
1089         bbtkError("The package <"<<GetName()<<"> does not contains the black box <"<<name<<">");
1090       }
1091     //    bbtkMessage("help",1,"["<<GetName()<<"] ");
1092     i->second->GetHelp(full);
1093     bbtkDebugDecTab("kernel",8);
1094
1095   }
1096   //==========================================================================
1097
1098
1099   //==========================================================================
1100   /// Returns true iff the package contains the box of name boxname
1101   bool Package::ContainsDescriptor(const std::string& name) const 
1102   {
1103     bbtkDebugMessageInc("kernel",8,"Package<"<<GetName()
1104                         <<">::ContainsDescriptor(\""
1105                         <<name<<"\")"<<bbtkendl);
1106     
1107     DescriptorMapType::const_iterator i = mDescriptorMap.find(name);
1108     if (i == mDescriptorMap.end())  
1109     {
1110       bbtkDebugDecTab("kernel",8);
1111       return false;
1112     }
1113     bbtkDebugDecTab("kernel",8);
1114     return true;
1115   }
1116   //==========================================================================
1117
1118
1119  
1120   //==========================================================================
1121   void Package::CreateHtmlPage(const std::string& filename,
1122                                const std::string& caller,
1123                                const std::string& source,
1124                                const std::string& custom_header,
1125                                const std::string& custom_title,
1126                                int detail, 
1127                                int level,
1128                                bool relative_link ) const
1129   {
1130     bbtkDebugMessageInc("kernel",9,"Package<"<<GetName()<<">::CreateHtmlPage(\""
1131                         <<filename<<"\")"<<bbtkendl);
1132
1133 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1133"<<std::endl;
1134
1135     //---------------------
1136     // Open output file
1137     std::ofstream s;
1138     s.open(filename.c_str());
1139     if (!s.good()) 
1140     {
1141        bbtkError("Package "<<GetName()<<" : CreateHtmlPage : could not open file '"<<filename<<"'");
1142     }
1143     
1144     //----------------------
1145     // Html head
1146     std::string title = "BBTK Package "+GetName()+" "+GetVersion(); 
1147
1148     if (custom_title.length() != 0) title = custom_title;
1149
1150     s << "<html lang=\"en\">\n";
1151     s << "<head>\n";
1152     s << "<title>" << title << "</title>\n";
1153     s << "<meta http-equiv=\"Content-Type\" content=\"text/html\">\n";
1154     s << "<meta name=\"description\" content=\""<<title<<"\">\n";
1155     s << "<meta name=\"generator\" content=\"\">\n";
1156     s << "<link title=\"Top\" rel=\"top\" href=\"#Top\">\n";
1157     //<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
1158     s << "<meta http-equiv=\"Content-Style-Type\" content=\"text/css\"><style type=\"text/css\"><!--\n";
1159     s << "pre.display { font-family:inherit }\n";
1160     s << "pre.format  { font-family:inherit }\n";
1161     s << "pre.smalldisplay { font-family:inherit; font-size:smaller }\n";
1162     s << "pre.smallformat  { font-family:inherit; font-size:smaller }\n";
1163     s << "pre.smallexample { font-size:smaller }\n";
1164     s << "pre.smalllisp    { font-size:smaller }\n";
1165     s << "span.sc    { font-variant:small-caps }\n";
1166     s << "span.roman { font-family:serif; font-weight:normal; } \n";
1167     s << "span.sansserif { font-family:sans-serif; font-weight:normal; }\n"; 
1168     s << "--></style>\n";
1169     s << "</head>\n";
1170     //----------------------
1171
1172     //----------------------
1173     // Html body
1174     s << "<body>\n";
1175     s << "<a name=\"Top\"></a>\n"; 
1176     
1177     //----------------------
1178     // Header
1179     if ( custom_header.length() != 0) 
1180       {
1181         if ( custom_header != "none" )
1182           { 
1183             std::ifstream in;
1184             in.open(custom_header.c_str());    
1185             if (!in.good()) 
1186               {
1187                 bbtkError("Could not open file \""<<custom_header<<"\"");
1188               }
1189             char buffer[512];
1190             while (!in.eof()) 
1191               {
1192                 in.getline(buffer,512);
1193                 std::string line(buffer);
1194                 s << line;
1195               }
1196             in.close();
1197             s << "<hr>\n";
1198            
1199             /*   
1200             s << "<object data=\"" << custom_header 
1201               << "\" type = \"text/html\"\"style=\"width: 1200px; height: 400px;\"> Warning: "
1202               << custom_header <<" could not be embedded.</object>\n";
1203             
1204             s << "<hr>\n";
1205             */
1206           }
1207       }
1208
1209     else 
1210       {
1211         s << "<h1 class=\"settitle\">"<<title<<"</h1>\n";
1212         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
1213         s << "<TR><TD style='vertical-align: top;'><b> Description </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
1214           << GetDescription() << "</TD></TR>\n";
1215         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
1216           << GetAuthor() << "</TD></TR>\n";
1217         s << "<TR><TD style='vertical-align: top;'><b> Author(s) </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'>  " 
1218           << GetCategory() << "</TD></TR>\n";
1219         s << "<TR><TD style='vertical-align: top;'><b> Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
1220           << GetVersion() << "</TD></TR>\n";
1221         s << "<TR><TD style='vertical-align: top;'><b> bbtk Version </b></TD><TD style='vertical-align: top;'> : </TD><TD style='vertical-align: top;'> " 
1222           << bbtk::GetVersion() << "</TD></TR>\n";
1223         s << "</TABLE>\n";
1224       }
1225 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1225"<<std::endl;
1226     //-------------------
1227     // Table of contents
1228     // Black boxes list
1229     //  s << "<div class=\"contents\">\n";
1230     s << "<p><b> Black Boxes : </b>\n";
1231     s << "<ul>\n";
1232
1233     s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
1234
1235     DescriptorMapType::const_iterator i;
1236 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1236"<<std::endl;
1237     for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i) {
1238                 if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD) 
1239                         continue;
1240         
1241                 std::string name = i->second->GetTypeName();
1242                 Utilities::html_format(name);
1243                 std::string descr = i->second->GetDescription();
1244                 //Utilities::html_format(descr);
1245 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1246"<<std::endl;
1246                 s << "<TR>";
1247                 s << "<TD style='vertical-align: top;'>";
1248                 s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
1249                 <<"\" href=\"#"<<name<<"\">"
1250                 <<name<<"</a>";
1251                 s << "</TD> ";
1252                 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1253                 s << "</TR>\n";
1254                 }    
1255                 s << "</TABLE>\n";
1256
1257
1258                 s << "</ul>\n";
1259                 s << "</div>\n";
1260     
1261                 //-------------------
1262                 // Adaptors list
1263                 if (mAdaptorMap.size()>0) 
1264                 {
1265                         //  s << "<div class=\"contents\">\n";
1266                         s << "<p><b> Adaptors : </b>\n";
1267                         s << "<ul>\n";
1268 //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1268"<<std::endl;
1269                         //    DescriptorMapType::const_iterator i;
1270                         s << "<p><TABLE cellspacing=0  cellpadding=3>\n";
1271                         for (i=mDescriptorMap.begin(); i!=mDescriptorMap.end();++i) 
1272                         {
1273                                 if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) 
1274                                         continue;
1275     
1276                                 std::string name = i->second->GetTypeName();
1277                                 Utilities::html_format(name);
1278                                 std::string descr = i->second->GetDescription();
1279                     
1280                                 s << "<TR>";
1281                                 s << "<TD style='vertical-align: top;'>";
1282                                 s << "&nbsp;&nbsp;&nbsp;<a name=\"toc_"<<name
1283                                   <<"\" href=\"#"<<name<<"\">"
1284                                   <<name<<"</a>";
1285                                 s << "</TD> ";
1286                                 s << " <TD style='vertical-align: top;'>" << descr << " </TD>";
1287                                 s << "</TR>\n";
1288                         }    
1289                         s << "</TABLE>\n";
1290
1291                         s << "</ul>\n";
1292                         s << "</div>\n";
1293                 }
1294     
1295     
1296     //  s << "<div class=\"node\">\n";
1297
1298     //    s << "<p><hr>\n";
1299     //    s << "<a name=\"Top\"></a>\n";
1300     //  s << "Top:&nbsp;<a rel=\"top\" accesskey=\"t\" href=\"#Top\">Top</a>\n";
1301     // s << "Previous:&nbsp;<a rel="previous" accesskey="p" href="#dir">(dir)</a>,
1302     // s << "Up:&nbsp;<a rel="up" accesskey="u" href="#dir">(dir)</a>
1303     
1304     //    s << "</div>\n";
1305
1306     //----------------------
1307     // Boxes doc
1308
1309     //-------------------
1310     // Computes output directory from filename to pass it to 
1311     // BlackBoxDescriptor::InsertHtmlHelp
1312                 std::string dir;
1313
1314                 std::string::size_type slash_position = filename.find_last_of("/\\");
1315
1316
1317                 if (slash_position != std::string::npos) {
1318                         if (slash_position == 0)
1319                          slash_position = 1;  
1320                         dir = filename.substr(0,slash_position);
1321                 }
1322
1323                 for (i=mDescriptorMap.begin();
1324                  i!=mDescriptorMap.end();
1325                  ++i) 
1326                 {
1327                         i->second->InsertHtmlHelp(s,detail,level,dir,relative_link);
1328                 }    
1329
1330     //----------------------
1331     // Footer 
1332     time_t rawtime;
1333     tm * ptm;
1334     time ( &rawtime );
1335     ptm = gmtime ( &rawtime );
1336
1337     s << "<p><hr>\n";
1338     s << "Automatically generated by <b>"<<caller<<"</b> "//from <b>"
1339       //      <<source<<"</b>
1340       <<"on "
1341       << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900 
1342       << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n";
1343     s << "</body></html>\n"; 
1344     s.close();
1345     //----------------------
1346
1347     // End
1348     bbtkDebugDecTab("kernel",9);
1349   }
1350   //==========================================================================
1351   
1352   //==========================================================================
1353   std::string  Package::GetObjectName() const 
1354   { 
1355     return std::string("Package '")+mName+std::string("'"); 
1356   }
1357   //==========================================================================
1358
1359   //==========================================================================
1360   std::string Package::GetObjectInfo() const 
1361   {
1362     std::stringstream i;
1363     i << "  - "<<mDescriptorMap.size() << " boxes" << std::endl;
1364     if (mDynamicLibraryHandler) 
1365       {
1366         i<< "  - Loaded from dynamic library"<<std::endl;
1367       }
1368     return i.str();
1369   }
1370   //==========================================================================
1371
1372
1373   //==========================================================================
1374   size_t  Package::GetObjectSize() const 
1375   {
1376     size_t s = Superclass::GetObjectSize();
1377     s += Package::GetObjectInternalSize();
1378     return s;
1379   }
1380   //==========================================================================
1381   //==========================================================================
1382   size_t  Package::GetObjectInternalSize() const 
1383   {
1384     size_t s = sizeof(Package);
1385     return s;
1386   }
1387   //==========================================================================
1388   //==========================================================================
1389   size_t  Package::GetObjectRecursiveSize() const 
1390   {
1391     size_t s = Superclass::GetObjectRecursiveSize();
1392     s += Package::GetObjectInternalSize();
1393     
1394     DescriptorMapType::const_iterator i;
1395     for (i = mDescriptorMap.begin(); i!=mDescriptorMap.end(); ++i )
1396       {
1397         s += i->second->GetObjectRecursiveSize();
1398       }
1399     return s;
1400   }
1401   //==========================================================================
1402   
1403   //==========================================================================
1404   std::set<Package::WeakPointer> 
1405   Package::mReleasedDynamicallyLoadedPackages;
1406   //==========================================================================
1407 }
1408