epoc32/include/mw/epos_cposlmmultidbsearch.h
branchSymbian2
changeset 2 2fe1408b6811
parent 1 666f914201fb
child 4 837f303aceeb
equal deleted inserted replaced
1:666f914201fb 2:2fe1408b6811
     1 epos_cposlmmultidbsearch.h
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: CPosLmMultiDbSearch class used to perform searches for landmarks or
       
    15 *				       landmark categories in multiple databases.
       
    16 *
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 #ifndef CPOSLMMULTIDBSEARCH_H
       
    22 #define CPOSLMMULTIDBSEARCH_H
       
    23 
       
    24 #include <e32base.h>
       
    25 #include <badesca.h>
       
    26 #include <epos_cposlandmarksearch.h>
       
    27 #include <epos_cposlmcategorymanager.h>
       
    28 
       
    29 class CPosLmSearchCriteria;
       
    30 class CPosLmDisplayData;
       
    31 class CPosLmMultiDbSearchOperation;
       
    32 class CPosLmMultiDbSortPref;
       
    33 class CPosLmMultiDbSearchItem;
       
    34 
       
    35 /**
       
    36 *  @ref CPosLmMultiDbSearch is used to perform searches for landmarks or
       
    37 *  landmark categories in multiple databases.
       
    38 *
       
    39 *  The client can specify which databases to search.
       
    40 *
       
    41 *  Some criterion classes are used for searching for landmarks (e.g.
       
    42 *  @ref CPosLmCategoryCriteria is used for searching for landmarks which
       
    43 *  contain a certain category) and some are used
       
    44 *  to search for landmark categories (e.g. @ref CPosLmCatNameCriteria is used
       
    45 *  to search for landmark categories by specifying a category name).
       
    46 *
       
    47 *  Searches can be run in incremental mode.
       
    48 *  @ref StartLandmarkSearchL and @ref StartCategorySearchL both return a
       
    49 *  @p CPosLmOperation object which is used to execute the search. If it is
       
    50 *  sufficient to run the search synchronously, the client only has to
       
    51 *  call @p CPosLmOperation::ExecuteL. If it is run incrementally the client can
       
    52 *  supervise the progress of the operation. The @p CPosLmOperation::NextStep
       
    53 *  function in the search operations cannot be executed synchronously using
       
    54 *  @p User::WaitForRequest. Doing so may cause the operation to hang.
       
    55 *  @p CPosLmOperation::NextStep must be run using an active object. The client
       
    56 *  can cancel the search by deleting the @p CPosLmOperation object.
       
    57 *
       
    58 *  By default, these functions start a new search, but the client can specify
       
    59 *  that only previous matches should be searched. This can be used to refine
       
    60 *  the search when there are many matches.
       
    61 *
       
    62 *  It is not allowed to search by category item ID in
       
    63 *  @ref CPosLmCategoryCriteria since an item ID is only valid in one landmark
       
    64 *  database.
       
    65 *
       
    66 *  It is only allowed to specify a named category, a global category,
       
    67 *  or no category. It is not allowed to search with @ref CPosLmIdListCriteria
       
    68 *  since an item ID is only valid in one landmark database. In both cases
       
    69 *  the search functions leave with error code @p KErrArgument.
       
    70 *
       
    71 *  During the search execution, a read-lock is acquired for each database.
       
    72 *  Only one search can be performed at a time by the single instance of
       
    73 *  the class. If a search is already running, the search function leaves
       
    74 *  with error code @p KErrInUse.
       
    75 *
       
    76 *  After search completion, the client can make a second search and specify
       
    77 *  that only the matches from the previous search shall be considered.
       
    78 *
       
    79 *  The client can also set a limit on how many search matches should be
       
    80 *  returned (see @ref SetMaxNumOfMatches).
       
    81 *
       
    82 *  The client retrieves the matches from the search by requesting an iterator
       
    83 *  (see @ref MatchIteratorL) or by using display data (see
       
    84 *  @ref SetDisplayData).
       
    85 *
       
    86 *  If @ref CPosLmMultiDbSearch is used, the client must call the global
       
    87 *  function @ref ReleaseLandmarkResources before terminating in order to
       
    88 *  release all used landmark resources, otherwise the client may receive
       
    89 *  an ALLOC panic.
       
    90 *
       
    91 *  @p NetworkServices capability is required for remote databases.
       
    92 *
       
    93 *  @lib eposlmmultidbsearch.lib
       
    94 *  @since S60 3.0
       
    95 *  @version $Revision: 1.17 $, $Date: 2005/07/07 13:40:10 $
       
    96 */
       
    97 class CPosLmMultiDbSearch : public CBase
       
    98     {
       
    99     public:  // Data types
       
   100 
       
   101         /**
       
   102         *  Struct containing a search error.
       
   103         */
       
   104         struct TSearchError
       
   105             {
       
   106             TUint iDatabaseIndex; /**<
       
   107                 The index of the database where the search has failed. The
       
   108                 database URI can be retrieved by calling @ref DatabaseUriPtr.*/
       
   109             TInt iErrorCode; /**<
       
   110                 The search error code for the database. */
       
   111             };
       
   112 
       
   113     public:  // Constructors and destructor
       
   114 
       
   115         /**
       
   116         * Two-phased constructor.
       
   117         *
       
   118         * Leaves with @p KErrArgument if the database list is empty.
       
   119         *
       
   120         * @param[in] aDatabaseList An array containing the URIs of the landmark
       
   121         *   databases to be used in the search.
       
   122         * @return A new instance of this class.
       
   123         */
       
   124         IMPORT_C static CPosLmMultiDbSearch* NewL( const CDesCArray&  aDatabaseList );
       
   125 
       
   126         /**
       
   127         * Destructor.
       
   128         */
       
   129         IMPORT_C virtual ~CPosLmMultiDbSearch();
       
   130 
       
   131     public: // New functions
       
   132 
       
   133         /**
       
   134         * Specifies the list of databases that should be used in the search.
       
   135         *
       
   136         * If this function is called and then @ref StartLandmarkSearchL or
       
   137         * @ref StartCategorySearchL is called with the flag
       
   138         * aSearchOnlyPreviousMatches set, new databases that were not a part
       
   139         * of the previous search will generate no matches.
       
   140         *
       
   141         * If the client specifies database(s) that do not exist,
       
   142         * @ref GetSearchError will report error code @p KErrNotFound for those
       
   143         * databases after the search is started.
       
   144         *
       
   145         * This function will leave with @p KErrInUse if called during a
       
   146         * search.
       
   147         *
       
   148         * If this function is called after a search has completed,
       
   149         * database indexes in the results may become invalid.
       
   150         *
       
   151         * If a database is removed from a previously set list, the search
       
   152         * result of that database is unavailable after this function
       
   153         * is called. Search errors are reset after this function is called.
       
   154         *
       
   155         * Leaves with @p KErrArgument if the database list is empty.
       
   156         *
       
   157         * @since S60 3.0
       
   158         * @param[in] aDatabaseList An array containing the URIs of the landmark
       
   159         *   databases to be used in the search.
       
   160         */
       
   161         IMPORT_C void SetDatabasesToSearchL( const CDesCArray&  aDatabaseList );
       
   162 
       
   163         /**
       
   164         * Returns the list of databases to search. Ownership is transferred
       
   165         * to the caller.
       
   166         *
       
   167         * @return The list of databases to search.
       
   168         */
       
   169         IMPORT_C CDesCArray* DatabasesToSearchL();
       
   170 
       
   171         /**
       
   172         * Sets the maximum number of search matches limit for each database.
       
   173         *
       
   174         * This function is used to limit the number of matches retrieved from
       
   175         * each database in the search operation. If the limit is set, the
       
   176         * search operation will stop when this limit is reached. By default
       
   177         * the maximum number of matches is unlimited.
       
   178         *
       
   179         * If a new value for maximum number of matches is set when a search is
       
   180         * ongoing, it will not affect the current search. The new maximum will
       
   181         * be utilized in the next search.
       
   182         *
       
   183         * @since S60 3.0
       
   184         * @param[in] aMaxNumOfMatches The maximum number of search matches for
       
   185         *   each landmark database involved in the search.
       
   186         */
       
   187         IMPORT_C void SetMaxNumOfMatches( TInt  aMaxNumOfMatches = KPosLmMaxNumOfMatchesUnlimited );
       
   188 
       
   189         /**
       
   190         * Starts a landmark search.
       
   191         *
       
   192         * If there are no previous matches and the client specifies that
       
   193         * previous matches should be used, this function leaves with error
       
   194         * code @p KErrArgument.
       
   195         *
       
   196         * If a search is already running, this function leaves with error
       
   197         * code @p KErrInUse.
       
   198         *
       
   199         * If the search criterion is not valid for landmark searching, this
       
   200         * function leaves with error code @p KErrArgument.
       
   201         *
       
   202         * If the search criterion is not supported, this function leaves
       
   203         * with error code @p KErrNotSupported.
       
   204         *
       
   205         * If @ref CPosLmIdListCriteria is used or @ref CPosLmCategoryCriteria
       
   206         * with item ID set, this function leaves with error code
       
   207         * @p KErrArgument.
       
   208         *
       
   209         * The client takes ownership of the returned operation object.
       
   210         *
       
   211         * This function requires @p ReadUserData capability.
       
   212         *
       
   213         * @since S60 3.0
       
   214         * @param[in] aCriteria The search criterion.
       
   215         * @param[in] aSearchOnlyPreviousMatches This flag may be used to perform a
       
   216         *   search within the results of previous search.
       
   217         * @returns A handle to the search operation.
       
   218         */
       
   219         IMPORT_C CPosLmOperation* StartLandmarkSearchL(
       
   220             const CPosLmSearchCriteria&  aCriteria,
       
   221             TBool  aSearchOnlyPreviousMatches = EFalse );
       
   222 
       
   223         /**
       
   224         * Starts a landmark search.
       
   225         *
       
   226         * This overload of the @ref StartLandmarkSearchL function lets the
       
   227         * client define the sort order for the search matches.
       
   228         *
       
   229         * Only sorting by landmark name is supported. If the client tries to
       
   230         * sort by another attribute, this function leaves with error code
       
   231         * @p KErrNotSupported.
       
   232         *
       
   233         * If there are no previous matches and the client specifies that
       
   234         * previous matches should be used, this function leaves with error
       
   235         * code @p KErrArgument.
       
   236         *
       
   237         * If a search is already running, this function will leave with error
       
   238         * code @p KErrInUse.
       
   239         *
       
   240         * If the search criterion is not valid for landmark searching, this
       
   241         * function leaves with error code @p KErrArgument.
       
   242         *
       
   243         * If the search criterion is not supported, this function will leave
       
   244         * with error code @p KErrNotSupported.
       
   245         *
       
   246         * If @ref CPosLmIdListCriteria is used or @ref CPosLmCategoryCriteria
       
   247         * with item ID set, this function leaves with error code
       
   248         * @p KErrArgument.
       
   249         *
       
   250         * The client takes ownership of the returned operation object.
       
   251         *
       
   252         * This function requires @p ReadUserData capability.
       
   253         *
       
   254         * @since S60 3.0
       
   255         * @param[in] aCriteria The search criterion.
       
   256         * @param[in] aSortPref A sort preference object.
       
   257         * @param[in] aSearchOnlyPreviousMatches This flag may be used to perform a
       
   258         *   search within the results of previous search.
       
   259         * @returns A handle to the search operation.
       
   260         */
       
   261         IMPORT_C CPosLmOperation* StartLandmarkSearchL(
       
   262             const CPosLmSearchCriteria&  aCriteria,
       
   263             const TPosLmSortPref&  aSortPref,
       
   264             TBool  aSearchOnlyPreviousMatches = EFalse );
       
   265 
       
   266         /**
       
   267         * Starts a search for landmark categories.
       
   268         *
       
   269         * If there are no previous matches and the client specifies that
       
   270         * previous matches should be used, this function leaves with error
       
   271         * code @p KErrArgument...
       
   272         *
       
   273         * The criterion, which defines if a landmark category is a match,
       
   274         * is passed as input to this function.
       
   275         *
       
   276         * If a search is already running, this function leaves with error
       
   277         * code @p KErrInUse.
       
   278         *
       
   279         * If the search criterion is not valid for landmark category searching,
       
   280         * this function leaves with error code @p KErrArgument.
       
   281         *
       
   282         * If the search criterion is not supported, this function leaves
       
   283         * with error code @p KErrNotSupported.
       
   284         *
       
   285         * The client takes ownership of the returned operation object.
       
   286         *
       
   287         * This function requires @p ReadUserData capability.
       
   288         *
       
   289         * @param[in] aCriteria The search criteria.
       
   290         * @param[in] aSortPref Sort preference for the search results.
       
   291         * @param[in] aSearchOnlyPreviousMatches This flag may be used to perform a
       
   292         *   search within the results of previous search.
       
   293         * @returns A handle to the search operation.
       
   294         */
       
   295         IMPORT_C CPosLmOperation* StartCategorySearchL(
       
   296             const CPosLmSearchCriteria&  aCriteria,
       
   297             CPosLmCategoryManager::TCategorySortPref  aSortPref,
       
   298             TBool  aSearchOnlyPreviousMatches = EFalse );
       
   299 
       
   300         /**
       
   301         * Returns the number of errors encountered during the search. This is
       
   302         * the same as number of databases in which the search has failed.
       
   303         *
       
   304         * @since S60 3.0
       
   305         * @return The number of errors encountered during the search.
       
   306         */
       
   307         IMPORT_C TUint NumOfSearchErrors() const;
       
   308 
       
   309         /**
       
   310         * Returns errors encountered in the search.
       
   311         *
       
   312         * The client specifies an index of the error to retrieve. The index must
       
   313         * be strictly less than @ref NumOfSearchErrors, otherwise this function
       
   314         * panics with code @p EPosInvalidIndex. Whenever a new search is started
       
   315         * this function must be called again to retrieve error codes, if any.
       
   316         *
       
   317         * @since S60 3.0
       
   318         * @param[in] aErrorIndex The index of the error to retrieve.
       
   319         * @param[out] aSearchError On return, contains the search error.
       
   320         */
       
   321         IMPORT_C void GetSearchError(
       
   322             TUint  aErrorIndex,
       
   323             TSearchError&  aSearchError ) const;
       
   324 
       
   325         /**
       
   326         * Returns the total number of matches so far in the search.
       
   327         *
       
   328         * This function can also be called during a search operation.
       
   329         *
       
   330         * @since S60 3.0
       
   331         * @return The number of search matches.
       
   332         */
       
   333         IMPORT_C TUint TotalNumOfMatches() const;
       
   334 
       
   335         /**
       
   336         * Returns the number of matches so far in the search for a
       
   337         * database specified by index.
       
   338         *
       
   339         * The index must be strictly less than @ref NumOfDatabasesToSearch,
       
   340         * otherwise this function will panic with code @p EPosInvalidIndex.
       
   341         * The URI of the database can be retrieved by calling
       
   342         * @ref DatabaseUriPtr.
       
   343         *
       
   344         * This function can also be called during a search operation.
       
   345         *
       
   346         * @param[in] aDatabaseIndex The index of the database to get number
       
   347         *   of search matches for.
       
   348         * @return The number of matches per database.
       
   349         */
       
   350         IMPORT_C TUint NumOfMatches( TUint aDatabaseIndex ) const;
       
   351 
       
   352         /**
       
   353         * Returns the number of databases involved in the search.
       
   354         *
       
   355         * @since S60 3.0
       
   356         * @return The number of databases involved in the search.
       
   357         */
       
   358         IMPORT_C TUint NumOfDatabasesToSearch() const;
       
   359 
       
   360         /**
       
   361         * Returns the URI of a database involved in the search.
       
   362         *
       
   363         * The client specifies an index of the database URI to retrieve. The
       
   364         * index must be strictly less than @ref NumOfDatabasesToSearch,
       
   365         * otherwise this function will panic with code @p EPosInvalidIndex.
       
   366         *
       
   367         * @since S60 3.0
       
   368         * @param[in] aDatabaseIndex The index of the database URI to retrieve.
       
   369         * @return A pointer to the database URI descriptor. This pointer is
       
   370         *   only valid until @ref SetDatabasesToSearch is called, or the
       
   371         *   @ref CPosLmMultiDbSearch object is destroyed, whichever happens
       
   372         *   first.
       
   373         */
       
   374         IMPORT_C TPtrC DatabaseUriPtr( TUint aDatabaseIndex ) const;
       
   375 
       
   376         /**
       
   377         * Creates an iterator object to iterate the matching landmarks or
       
   378         * categories from one of the databases involved in the search.
       
   379         *
       
   380         * The database to get search matches for is specified by index. The
       
   381         * index must be strictly less than @ref NumOfDatabasesToSearch,
       
   382         * otherwise this function will panic with code @p EPosInvalidIndex.
       
   383         * The URI of the database can be retrieved by calling
       
   384         * @ref DatabaseUriPtr.
       
   385         *
       
   386         * This function can also be called during a search in order to read the
       
   387         * matches encountered so far. Note that the iterator will not iterate
       
   388         * any new matches. If new matches are found, a new iterator needs to be
       
   389         * created to retrieve them. The previous matches will also be included.
       
   390         *
       
   391         * If the client has started a search, but no matches have been found
       
   392         * yet in the database, an empty iterator is returned.
       
   393         *
       
   394         * If a sort preference was specified when the search was started, the
       
   395         * landmarks or categories will be sorted when the search is complete
       
   396         * but the items are not necessarily sorted if this function is
       
   397         * called during a search.
       
   398         *
       
   399         * The client takes ownership of the returned iterator object.
       
   400         *
       
   401         * Note: The iterator iterates matches in @ref CPosLmMultiDbSearch.
       
   402         * It cannot be used after the search object has been deleted.
       
   403         *
       
   404         * @since S60 3.0
       
   405         * @param aDatabaseIndex The index of the database to get search matches
       
   406         *   for.
       
   407         * @return A search results iterator.
       
   408         */
       
   409         IMPORT_C CPosLmItemIterator* MatchIteratorL( TUint aDatabaseIndex );
       
   410 
       
   411         /**
       
   412         * Display data can be used as an alternative way to get result
       
   413         * from a database search. Landmarks or categories are added to the
       
   414         * display data collection during a search depending on the search type.
       
   415         *
       
   416         * This function may replace the combination of using
       
   417         * @ref MatchIteratorL and reading landmark or category data.
       
   418         * Result data is read already during the search and no duplicate
       
   419         * access to database is needed.
       
   420         *
       
   421         * The display data object will be reset each time a new search is
       
   422         * started. No items during the search are removed from the
       
   423         * collection. New found matches can be added every time next
       
   424         * search step is completed, see @ref CPosLmDisplayData::NewItemIndex.
       
   425         *
       
   426         * If the client sets display data during an ongoing search, this
       
   427         * function panics with code @p EPosSearchOperationInUse.
       
   428         *
       
   429         * The client owns the display data object. If the client deletes it
       
   430         * during a search, this may lead to unexpected errors. The client must
       
   431         * call @ref UnsetDisplayData before it deletes the display data object.
       
   432         *
       
   433         * Search results from all databases are collected in the same
       
   434         * displayable data collection. The @ref CPosLmDisplayItem::DatabaseIndex
       
   435         * may be used to know which database every displayable item belongs to.
       
   436         * The database index matches databases specified in this object,
       
   437         * see @ref DatabaseUriPtr.
       
   438         *
       
   439         * @param[in,out] aData The displayable data.
       
   440         */
       
   441         IMPORT_C void SetDisplayData( CPosLmDisplayData& aData );
       
   442 
       
   443         /**
       
   444         * Unsets display data. No further data will be added to the display
       
   445         * data set with @ref SetDisplayData.
       
   446         *
       
   447         * If the client unsets display data during an ongoing search, this
       
   448         * function panics with code @p EPosSearchOperationInUse.
       
   449         */
       
   450         IMPORT_C void UnsetDisplayData();
       
   451 
       
   452         /**
       
   453         * Retrieves the maximum number of search matches limit for each
       
   454         * database.
       
   455         *
       
   456         * By default the maximum number of matches is unlimited.
       
   457         *
       
   458         * @return The maximum number of search matches for each landmark
       
   459         *   database involved in the search or
       
   460         *   @p KPosLmMaxNumOfMatchesUnlimited if unlimited.
       
   461         */
       
   462         IMPORT_C TInt MaxNumOfMatches() const;
       
   463 
       
   464         /*
       
   465         * Tells if the database with the specified database index is to be
       
   466         * searched or not.
       
   467         *
       
   468         * @param aDatabaseIndex The index of the database.
       
   469         * @return ETrue if the database is to be searched, otherwise EFalse.
       
   470         */
       
   471         TBool ToBeSearched( TUint aDatabaseIndex ) const;
       
   472 
       
   473         /*
       
   474         * Gets a pointer to the database with the specified database index.
       
   475         *
       
   476         * @param aDatabaseIndex The index of the database.
       
   477         * @return A pointer to the landmark database.
       
   478         */
       
   479         CPosLandmarkDatabase* DatabaseL( TUint aDatabaseIndex );
       
   480 
       
   481         /*
       
   482         * Gets a pointer to the single search class for the database with the
       
   483         * specified database index.
       
   484         *
       
   485         * @param aDatabaseIndex The index of the database.
       
   486         * @return A pointer to the single search class.
       
   487         */
       
   488         CPosLandmarkSearch* SearcherL( TUint aDatabaseIndex );
       
   489 
       
   490         /*
       
   491         * This method must be called to notify this class when a search has
       
   492         * been started in the single search class corresponding to the
       
   493         * specified database index.
       
   494         *
       
   495         * @param aDatabaseIndex The index of the database.
       
   496         */
       
   497         void SearchStarted( TUint aDatabaseIndex );
       
   498 
       
   499         /*
       
   500         * This method must be called to notify this class when a search has
       
   501         * been executed (partly or completely) in the single search class
       
   502         * corresponding to the specified database index.
       
   503         *
       
   504         * @param[in] aDatabaseIndex The index of the database.
       
   505         * @param[in] aSortPref The sort pref for the search.
       
   506         */
       
   507         void SearchExecutedL(
       
   508             TUint aDatabaseIndex,
       
   509             const CPosLmMultiDbSortPref& aSortPref );
       
   510 
       
   511         /*
       
   512         * Adds a search error for the specified database index.
       
   513         *
       
   514         * @param aDatabaseIndex The index of the database.
       
   515         * @param aErrorCode The error code.
       
   516         */
       
   517         void AddSearchError( TUint aDatabaseIndex, TInt aErrorCode );
       
   518 
       
   519         /*
       
   520         * This function must be called by the CPosLmMultiDbSearchOperation
       
   521         * when the search operation has completed or has been cancelled.
       
   522         */
       
   523         void HandleSearchOperationCompleted();
       
   524 
       
   525     private:
       
   526 
       
   527         /**
       
   528         * C++ default constructor.
       
   529         */
       
   530         CPosLmMultiDbSearch();
       
   531 
       
   532         /**
       
   533         * By default Symbian 2nd phase constructor is private.
       
   534         */
       
   535         void ConstructL(const CDesCArray& aDatabaseList);
       
   536 
       
   537         void CloseDbsNotToSearch(const CDesCArray& aDatabaseList);
       
   538 
       
   539         CPosLmOperation* StartSearchL(
       
   540             const CPosLmSearchCriteria& aCriteria,
       
   541             CPosLmMultiDbSortPref* aSortPref,
       
   542             TBool aSearchOnlyPreviousMatches );
       
   543 
       
   544     private:    // Data
       
   545 
       
   546         TInt                    iMaxNumOfMatches;
       
   547         TInt                    iNewMaxNumOfMatches;
       
   548 
       
   549         CPosLmMultiDbSearchOperation* iMultiSearchOperation; // No ownership
       
   550 
       
   551         RPointerArray<CPosLmMultiDbSearchItem> iSearchItems;
       
   552 
       
   553         RArray<TSearchError>    iSearchErrors; // Can contain dummy errors.
       
   554         TUint                   iNoOfSearchErrors; // Number of valid errors.
       
   555 
       
   556         CPosLmDisplayData*      iClientDisplayData; // No ownership
       
   557 
       
   558     };
       
   559 
       
   560 #endif      // CPOSLMMULTIDBSEARCH_H
       
   561