For Users
Download Plug-ins
Desktop Search Forum
For Developers
Plug-in Development
Download SDK
Developer Guide
Index API
Query API
Display API
Script API
Communication API
Plug-in Design Guidelines
Plug-in Tutorials
Using Wizard
Using Helper Framework
Using ActiveX
Action API
Event API
Plug-in Installer
Submit Software
Developer Forum
Desktop Blog
|
Contents
Getting
Started
Registering With
The Query API
Native Plug-in
Registration
Script Plug-in
Registration
Query
Objects
Query Methods for Native Plug-Ins
Query Methods for Script Plug-Ins
QueryEx Query
Objects
QueryEx for Native Plug-Ins
QueryEx for Script Plug-Ins
Individual
Search Result Objects
Individual Search Result
Objects for Native Plug-Ins
Individual Search Result
Objects for Script Plug-Ins
Item
Versions
Item Versions
for Native Plug-Ins
Item Versions
for Script Plug-Ins
HTTP/XML-Based Query
API (obsolete)
Getting
Started
Requesting a
Desktop Search
Desktop Search
Results
Getting Started
Google Desktop indexes, caches, and searches content on your
computer. Through the Desktop Software Development Kit's
Query APIs, your applications can
send search queries directly to Google Desktop and process its search results.
The Query API described in the first
part of this document was introduced with Google Desktop
3. We cover both how to use it with native plug-ins and
with script-based plug-ins, and assume that you are
familiar with the general principles of how to write
Desktop plug-ins.
The latter part of this document describes the
previously used methods for issuing Desktop search queries using
HTTP and XML. While still usable at the moment, we do not plan to
further develop this type of Query API and may eventually
deprecate it. This material was included in case you are working
with a previously written plug-in which used this
approach. You should not use this approach in any new
plug-ins.
Registering With The Query API
You can only use the Query API if you have
registered with it and thus obtained a Query API registration
cookie. Note that this is in addition to the general registration
of your plug-in with Google Desktop.
There are two types of Query API registration cookies,
read-only and read-write. Usually, you'll only
need a read-only cookie. The read-write cookie is only needed when
you remove an item from the Google Desktop index.
We recommend that your plug-in encrypt the registration
cookie when it saves it, and, of course, be able to decrypt it when
you pass it to the various Query API methods and objects.
You'll need a global identifier (GUID) for your
plug-in to pass to the registration method. You can use a tool such
as guidgen.exe to generate
one.
Native Plug-in Registration
If you are writing a native plug-in, the
following summarizes the registration interface and its
method. All method return values are of type
HRESULT .
interface IGoogleDesktopRegisterQueryPlugin: IDispatch
-
Note: Components are required to call this interface to
register themselves with the Google Desktop Query API before
they can make use of that API.
-
RegisterPlugin : Must be invoked by any
component to register with the Query API.
-
Arguments:
-
BSTR plugin_class : The
component's GUID or ProgID.
-
VARIANT_BOOL read_only :
If true , you can
do search queries but cannot delete items from the
index. A false
value gives you both read and write access, allowing
you to delete index items.
[out, retval] long* cookie : Returns the registration cookie. Save
this value, as you will have to use it whenever
you make a query or remove an item from the
Desktop index via the Query API.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure, such as
an unregistered component classID or appID,
component prohibited by policy, etc.
Script Plug-in Registration
If you are writing a script-based plug-in,
see register_script_sample.js
for a complete example of registering with the Query API using
JavaScript. The gist is the following code:
try {
// Instantiate the Google Desktop registrar component by creating
// an ActiveX registration object.
var registrar = new ActiveXObject("GoogleDesktop.Registrar");
// Give it our plug-in GUID and description
registrar.StartComponentRegistration(g_scriptSampleId, componentDescription);
// Ask for the specific registration object that gives us Query API access.
var regObj = registrar.GetRegistrationInterface("GoogleDesktop.QueryRegistration");
// Now ask that registration object to give us a cookie representing
// our Query API access. Note the read_only flag argument here;
// if false, then we're asking for read-write access instead of
// just read-only access.
cookie = regObj.RegisterPlugin(g_scriptSampleId, read_only);
// Now submit and hope the user will accept this component.
// If not, then an error will be thrown
registrar.FinishComponentRegistration();
} catch (e) {
// We hit an error
message("Couldn't register the script samples.\n" + new String(e.number) +
"\n" + e.description);
return 0;
}
Note that you need to save the cookie value, as
you will have to use it whenever you make a query or remove an
item from the Desktop index via the Query API.
Query Objects
The Query API has one root object,
IGoogleDesktopQueryAPI for
native plug-ins, GoogleDesktop.QueryAPI for script plug-ins, that supports two methods:
Query : Immediately executes the
specified desktop search query and returns a result object that
contains all the search results for the query.
QueryEx : Returns a query object
which does not (yet) actually execute the query. Instead, you can
tweak some custom parameters first, then execute the revised query.
When executed, it returns the same type of result object as
Query .
The Query
and QueryEx root object methods both
take the following arguments:
cookie : The security
cookie created when you registered your plug-in with the Query
API.
query : The search query string,
which can include the same
set of query operators that you could use
in a query typed into a Google Desktop search box.category : Optional string argument
that lets you restrict results to those of a particular type. Valid
values are email ,
web , im , file ,
contact ,
calendar ,
task ,
note ,
or journal .
ranking : Optional numeric
argument specifying whether the search results will be ranked by
date (RECENCY_RANKING = 1), the
default, or by relevance (RELEVANCE_RANKING = 0).
Query Methods for Native Plug-Ins
interface IGoogleDesktopQueryAPI: IDispatch
-
Query : Immediately takes the
specified search query and executes it with default option values.
-
Arguments:
-
long cookie : The
component's Query API security cookie.
-
BSTR query :
The search query string, which can contain any of
the
allowed Desktop search operators.
-
VARIANT category : [Optional]
-
VARIANT ranking : [Optional]
[out, retval] IGoogleDesktopQueryResultSet**
results : The search results from
having automatically executed a desktop search for the
search query.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
-
QueryEx : Returns a query object
that does not automatically execute a search. Instead, you
can alter the query's properties and exert finer control
over the search, and then execute the query.
-
Arguments:
-
long cookie : The
component's Query API security cookie.
-
BSTR query :
The search query string, which can contain any of
the allowed Desktop search operators.
-
VARIANT category : [Optional]
-
VARIANT ranking : [Optional]
[out, retval] IGoogleDesktopQuery** q)
: An unexecuted query object, which
you can alter the default properites and parameters of
before running a search on its search query.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
Query Methods for Script Plug-Ins
In JavaScript, you just create the base object and
then create and run the Query in one step.
// Instantiate the main query api object
var qapi = new ActiveXObject("GoogleDesktop.QueryAPI");
// Perform the query and get a recordset object back containing the
// search results.
var set = qapi.Query(cookie, search_string);
See the simple_query.js example for a detailed example.
QueryEx Query Objects
If you run the QueryEx()
method, it returns a Query object for which you can change any or all of
these four options before executing the query:
async : By setting this to
false , all result items are
fetched before the Execute()
method completes. The default value is
true .
filter_duplicates : By
setting to false , you'll get
all the items that match, including any duplicates of already
matched items. Default
is true .
match_all_terms : When set
to false , if there are
multiple query terms, any item matching just one of the query
terms is returned. Otherwise, a result must match all of the query
terms. Default is true .
blacklisting : By setting
to false , items in the search
results do not go through the default blacklisting filters.
Default is true .
If you turn this off, you'll most likely see spam email, secure
content, bad urls such as about:, res:, etc. in addition to
your good results.
In order to change an option value, use the
SetOption() method, one of four
methods associated with Query objects. These are:
SetOption : Takes arguments, in
this order, of what option to set and what value to set it
to.
GetOption : Takes an option name,
returns its value.
query : Takes no arguments,
returns a string containing the search query.
Execute : Once you've finished
setting the Query object's options, run this method to actually
run the search. Returns a query result set.
QueryEx for Native Plug-Ins
QueryEx 's returned object,
IGoogleDektopQuery , has the following
interface:
interface IGoogleDesktopQuery: IDispatch
-
SetOption : Set an option value.
-
Arguments:
-
BSTR name : Which option to
set.
-
VARIANT value :
What value to set the option to.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
-
GetOption : Get an option value.
-
Arguments:
-
BSTR name : Which option to
get the value of.
-
[out, retval] VARIANT* value :
The option's value.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
-
query : Get the search query string.
-
Arguments:
-
[out, retval] BSTR* ret :
The search query string.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
-
Execute : Execute the search as
specified by the QueryEx object's query string and option values.
-
Arguments:
-
[out, retval] IGoogleDesktopQueryResultSet**
results : Results from the search.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
QueryEx for Script Plug-Ins
The following code using
QueryEx comes from the
item_count.js example. It shows
the usual series of events when using
QueryEx ; call
QueryEx on the
base Query API object to get a Query object, set Query object
options with SetOption() , then
call Execute() on the Query object and
get back a recordset of the search results.
var q = new ActiveXObject("GoogleDesktop.QueryAPI");
// Call the QueryEx method so that we can turn off the asynchronous
// loading of record items.
var qx = q.QueryEx(g_securityCookie, query);
// Turn off the default asynchronous behavior.
qx.SetOption("async", false);
// Execute the query synchronously and get back a recordset object
var set = qx.Execute();
Result Objects
When you execute a Query or QueryEx , it
returns an result set object. This object contains individual result item
objects, each of which represents a single search result.
Unless you used QueryEx
and changed the default value of the Query object's
async option to
false from its default value
true before executing the
query, you can access search results before the search has completely
finished. To find out if a search has completed, check the resultset's
readystate property, which can
have three values:
GD_QRS_UNITIALIZED = 0 : Search
has not yet started.
GD_QRS_LOADING = 1 : Search
is still in progress.
GD_QRS_COMPLETE = 2 : Search
is complete, with all results received and in the resultset.
There are four methods associated with result set
objects:
readystate : Takes no arguments,
returns the current readystate
value.
count : Takes no arguments,
returns the total number of individual search result items in
the recordset. Note that this number will change as long as
results are still arriving. Until
readystate is
GD_QRS_COMPLETE , this value
is an estimate.
Next : Takes no arguments, returns
the next individual search result in the set. If results are
still arriving and Next() is
at the end of the current results, it will wait until the next
result arrives. If you reach the end of the results after all
results are in the recordset, Next() returns null .
available_count : Takes no arguments,
returns how many individual results can be fetched via calls to
next() without it blocking
while waiting for more results.
Result Objects for Native Plug-Ins
interface IGoogleDesktopQueryResultSet: IDispatch
-
Next : Returns the next individual
search result in the set. If results are still arriving, it
waits for the next result to arrive before returning it. If
called after reaching the final result, it returns
S_FALSE and
null .
-
Arguments:
[out, retval] IGoogleDesktopQueryResultItem**
next : An individual search result.
-
Returns:
-
S_OK if successful.
S_FALSE and
null if called after the
last result has already been returned.
-
Appropriate error on failure.
-
readystate : Returns the current
readystate value, which
can be
GD_QRS_UNINITIALIZED = 0
GD_QRS_LOADING = 1
(Still receiving results)
GD_QRS_COMPLETE = 2 (All results received)
-
Arguments:
-
[out, retval] QRSReadyState* state
: readystate
's value.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
count : Returns the total number
of individual search result items. Note that this number
will change so long as individual results are still
arriving. Until the readystate
value becomes GD_QRS_COMPLETE , this value is an estimate. After that, it is the
exact and total number of individual search results.
-
Arguments:
-
[out, retval] long* ret
: Number of results
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
available_count : Returns the
value of how many individual results can currently be
fetched via calls to next()
without blocking.
-
Arguments:
-
[out, retval] long* available_count
: Current remaining number of available
search results.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
Result Objects for Script Plug-Ins
To iterate through a result set's individual
results in JavaScript, you'd write something like:
var item;
while ((item = results.Next()) != null) {
// process item here
}
Individual Search Result Objects
Result item objects each contain a single search
result. The key method is GetProperty , which takes a property name and returns its value for the
result. The complete list of valid property names is quite long; the
ones you'll probably use most often are
content ,
uri ,
summary , and for email
from , to , and subject .
In order to avoid errors due to trying to get a value for a
property that doesn't exist for a result due to its type (i.e. a file
won't have a from property), you
should first use the schema method
to determine the result's type. The following schemas are defined in
the Desktop SDK IDL:
- "web"
- "text"
- "media"
- "office"
- "file"
- "calendar"
- "contact"
- "email"
- "im"
- "note"
- "journal"
- "task"
- "shortcut"
If you try to get a value for a property the result
doesn't have, an error is returned. For scripts, that means an
exception is thrown, so remember to use exception handling in your
script plug-ins.
There are four methods associated with result item
objects:
GetProperty : Takes a property
name argument, returns that property's value.
schema : Takes no arguments,
returns the name of the item's schema.
versions : Takes no arguments, returns
either a list of emails in this item's thread (if the item is an
email) or a list of all file versions (if the item is a file) in
the Desktop index. These are returned as a document versions object.
RemoveFromIndex : Takes one
argument, which if true
(the default value)
removes this item and all its versions from the Desktop index.
If false , only this
individual item is removed.
Remember, you must have a read-write Query API
registration cookie for this method to work. If you don't have
one, you'll get an "Access Denied" error.
The complete property set is:
width | primary_fax | status | business_phone | duration |
bcc | business_fax | mail_header | channels | home_address |
mail_flags | importance | author |
department | display_name |
company | keywords | height | other_phone |
job_title |
text_content | home_phone | office_location |
data_rate | total_work |
received | personal_home_page | start_date | flags | event_id |
business_home_page | genre | participants |
country | birthday |
info_tip | date_completed | other_data |
track_number | companies |
interaction_period | cookie_raw | thumbnail |
categories | conversation_id |
profession | percent_complete | bit_rate |
thumbnail_format | pager |
year_published | end_date | artist |
assistant | due_date |
start_time | date | native_size | doc_id |
to |
home_fax | format | owner | replyto |
mobile_phone |
original_date | comment | timestamp |
machine_name | lyrics |
email1 | web_page | email3 | folder_name |
primary_phone |
bookmarked | length | type | title |
mail_id |
wedding_anniversary | message_time | company_name |
buddy_name | location |
content | component_id | last_modified_time |
shortcut_target | internet_shortcut_name |
cc | company_phone | subject |
business_address | album_title |
attendees | spouse | language | nickname |
other_address |
uri | from | cookie | component_guid |
hobbies |
recurrence_pattern | organizer | email2 |
im_address | manager_name |
children_names | actual_work | user_name |
Individual Search Result Items for Native Plug-ins
The following is the interface for
IGoogleDesktopQueryResultItem ,
the native plug-in individual result item.
interface IGoogleDesktopQueryResultItem: IDispatch
-
GetProperty : Looks up and returns
property values.
-
Arguments:
BSTR prop_name :
Property name to look up the value of.
[out, retval] VARIANT* value : Value of the property argument for this result.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
-
RemoveFromIndex : Removes either
only this item or all versions of this item from the Desktop
index (for email items, the latter means removing all messages
in its thread). Note that you must have a read-write Query API
registration cookie for this method to work; if not you'll get
an "Access Denied" error.
-
Arguments:
VARIANT_BOOL remove_all_related_versions
: If
VARIANT_TRUE , all
versions are removed. If
VARIANT_FALSE ,
only this single item is removed.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
-
schema : Returns the name of the
item's schema.
-
Arguments:
[out, retval] BSTR* schema_name : Name of this item's schema
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
-
versions : Returns either a list
of emails in this item's thread (if the item is an email) or
a list of all file versions (if the item is a file) in the
Desktop index.
-
Arguments:
[out, retval] IGoogleDesktopDocumentVersions**
ret : List of item's versions or
other messages in its thread.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
Individual Search Result Items for Script Plug-ins
The following code from the
lucky.js example shows how to
get various properties from each individual result item in a result
set. The message() method is a
basic output method defined early in the script.
//Get the next individual search result item from the recordset
var item = set.Next()
if (item != null) {
// First output the URI of the item we found
message(item("uri"));
// Now output the text representation of the content
message(item("text_content"));
// Alternatively, we could output the content in its native form
// message(item("content"));
} else {
message("no item found!");
}
The remove_from_index.js example shows first how to build a query whose results
are restricted by being a specific filename in a specific folder, as
well as a script that removes from the Desktop index all result items
from a search query.
Item Versions
The result item's version property requires a bit of explanation. Its value is a
document versions object, which is a collection of individual query
result items. These are the same individual result items described
in the previous section; in other words, an individual search result
object can contain other individual result objects in its
version property.
For an email message, its version contents are the other
email messages in the same thread. For a file, its version contents
are any other versions of that file, either from an earlier or a later
time, indexed by Desktop.
The method of accessing individual versions is different from how
individual results are gotten from a search result recordset. The
count property's value is
the number of versions in the document versions object.
The Item() method takes a 0-based
index value and returns the result item object at that location.
Note that the versions are not ordered other than by their index
value; version 0 is not necessarily the earliest or latest version,
version 1 may be earlier or later than version 0, etc.
Item Versions in Native Plug-ins
interface IGoogleDesktopDocumentVersions: IDispatch
-
count : Number of separate
versions in this object.
-
Arguments:
[out, retval] long* ret : Number of indexed versions of this item.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
-
Item : Takes an index value and
returns the result item stored at that location in the
document versions list.
-
Arguments:
long index
: Index value of the version to be
returned.
[out, retval] IGoogleDesktopQueryResultItem**
ret : The item at the position
provided by the index argument.
-
Returns:
-
S_OK if successful.
-
Appropriate error on failure.
Item Versions in Script Plug-ins
The versions collection has one function,
Item(index) and one property,
count , which function as described
above.
HTTP/XML-Based Query API
Getting Started
From here to the end of the document,
we cover how to use the former HTTP/XML-based Query
API. As stated in the beginning, this is for reference use
only for existing plug-ins that used this approach. Any
new plug-ins should use the new Query API described
previously.
To issue GD HTTP/XML search queries
you will need to know, in addition
to the information in this document:
-
How to issue an HTTP request.
-
How to process an XML-format HTTP response.
Requesting a Desktop Search
Your application requests a desktop search by sending an HTTP
request that includes a &format=xml parameter
to Google Desktop. For example, to search for "Google" you'd send something
like:
http://127.0.0.1:4664/search&s=1ftR7c_hVZKYvuYS-RWnFHk91Z0?q=Google&format=xml
To break this down:
-
http://127.0.0.1:4664/ is the localhost address and
GD port. search&s=1ftR7c_hVZKYvuYS-RWnFHk91Z0
is the search command and a security token. ?q=Google
is the query term(s) parameter.
-
If you want to search for more than one term, separate the terms
with
+ s. For example, to search for both "Google" and "GD", use:
?q=Google+GD
-
If you want to search for a specific phrase, separate the terms
with
+ s and surround the phrase with %22 s.
For example, to search for the phrase "Google Desktop", use: ?q=%22Google+Desktop%22
To search for the two phrases "Google Desktop" and "Copyright 2005", use
?q=%22Google+Desktop%22+%22Copyright+2005%22
-
&format=xml specifies that the HTTP response
returns the search results in XML format, as described in the next section.
Note that these requests
only
do a desktop search, not both a web and desktop search.The search query URL,
including your security token, is stored in the registry at:
HKEY_CURRENT_USER\Software\Google\Google Desktop\API\search_url
To use the example above, the stored query URL would be something
like:
http://127.0.0.1:4664/search&s=1ftR7c_hVZKYvuYS-RWnFHk91Z0?q=
To create a query, all you have to do is append your query terms
and the final&format=xml parameter to
the stored query URL.
By default, an HTTP search response will only return the first
ten results. You can specify a larger number by appending the &num=
parameter, followed by the maximum number of results you'd like returned, to
your query. There is no problem if the maximum number argument value is greater
than the total number of search results; only the total number of results is
returned, with no null "results".
You can also specify at what point in the results the returned
ones start. For example, if you're using the default value of 10 returned
results and want to get back results 11-20 instead of the default results 1-10,
append the &start= parameter, followed
by the position you want the results to start from. In this example, you'd
specify &start=1 0 to
indicate you want your returned results to start with the one after overall
result 10. The &start= and
&num= parameters can both be used in a single query.
Desktop Search Results
When it receives a search request with the &format=xml
parameter, GD returns results in an XML format. For example:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<results count="24945">
<result>
<category>file</category>
<id>46384</id>
<title>SDK Developer Documentation</title>
<url>C:\Documents and Settings\me\My
Documents\developerguide.html~</url>
<time>127543068856350000</time>
<snippet>SDK Developer Documentation <b>Google</b> Desktop
SDK Developer Guide For Users Download Plug-ins Desktop Search Forum For
Developers</snippet>
<icon>/file.gif</icon>
<cache_url>http://127.0.0.1:4664/... </cache_url>
</result>
...
</results>
The one meta- results tag is <results> ,
which contains the total number of items that matched the query as the value of
a count parameter; e.g. <results
count=42> . This will be the largest number of
possible <result> ...</result>
entries in the <results> element.
However, if the number of returned results (which defaults to at most 10 if you
don't specify an &num= parameter with a
larger value) is different from the count value,
the number of returned <result> ...</result>
entries will be the smaller of the two conflicting values.
For example, let's say the <count>
value is 42. But you didn't give an &num=
argument in the query. So, despite there being 42 items that matched the query,
the XML response will only contain 10 <result> ...</result>
entries. If the <count> value was 6,
which is smaller than the default 10 value, the XML response will only contain
6 <result> ...</result>
entries.
If you want to be sure to obtain all search results, your
component will have to parse out the <count>
value and then issue additional HTTP GD search requests to retrieve that many
results via use of either the &start= or
&num= parameters.
Each <result> may
include the following fields, which may appear in any order. Which fields
appear will depend on the result type; for example, the <from>
entry should only show up in email or chat results. Each tag will
contain a value; any tags not containing a value are not shown.
-
<category> contains the result's type, one of:
-
email
-
chat
-
web
-
file
-
contact
-
calendar
-
task
-
journal
-
note
-
<id> is the result's GD internal
identifier.
-
<title> is the result's title, which
varies depending on its type, for example:
-
Web page: the page's title.
-
Email: the message's Subject:.
-
File: its filename.
-
Chat: a line from the chat.
-
<url> is the result's URL. For files and web
pages, this is the usual path to the result. For chats and email messages,
Google Desktop generates a URL for the location where it has stored its cached
copy.
-
<time> is the time
value from the event that put this content into GD. Usually this will be the
time the content was indexed by GD, but, for example, it could also be a file's
last modified time. The format is per the Windows FILETIME structure; the
number of 100-nanosecond intervals since January 1, 1601 represented as a
64-bit number.
-
<snippet> is a snippet from the result's
content that contains at least one of the search terms.
-
<icon> is a Google Desktop-relative URL to an
icon representing this result or its type. This will either be one of the
standard Google Desktop Search result type icons (envelope for email, Word icon
for a Word file, etc.) or a favicon obtained from a website.
-
<thumbnail> is a relative URL to the icon for
this result at the GD webserver
-
<from> is the name of either the person an
email message was from, or the other party in an Instant Message chat.
-
<cache_url> is the Google Desktop-relative URL
of this result's internal cache page.
If you want to experiment with queries to see what their XML
format results look like, just do a desktop search from the browser. Then
append ?format=xml to the result's URL, hit
Enter, and the same results will display in XML format in the browser. Two
caveats: first, only the number of results that originally appeared on one
results page will show up in the browser in XML. So, for example, if only 10
HTML format results show up in the browser on one results page, only 10 XML
format results will appear in the browser, even if the value of <total-results>
is, say, 42. Second, your browser must include an XML viewer, which IE and
Firefox do by default.
Finally, note that the XML results do
not
include the search terms. If your application wants to also make use of the
search terms, as well as the results, it will have to keep track of what they
were.
|