Index: other-projects/gs2-java-client/trunk/ChangeLog
===================================================================
--- other-projects/gs2-java-client/trunk/ChangeLog	(revision 21017)
+++ other-projects/gs2-java-client/trunk/ChangeLog	(revision 21017)
@@ -0,0 +1,952 @@
+2001-05-28 13:19  say1
+
+	* ChangeLog, org/nzdl/gsdl/SimpleGraphicalClient/CSFrame.java,
+	org/nzdl/gsdl/SimpleGraphicalClient/ChangeLogDialog.java,
+	org/nzdl/gsdl/SimpleGraphicalClient/Constants.java,
+	org/nzdl/gsdl/SimpleGraphicalClient/FileDialog.java,
+	org/nzdl/gsdl/SimpleGraphicalClient/Makefile: generalised
+	ChangeLogDialog ==>> FileDialog to allow viewing of the ChangeLog,
+	the GPL or the interface
+
+2001-05-23 23:10  say1
+
+	* org/nzdl/gsdl/: SimpleGraphicalClient/DocumentInfoDialog.java,
+	SimpleGraphicalClient/Makefile,
+	SimpleGraphicalClient/SearchPanel.java, hli/Query.java,
+	service/Makefile, service/NzdlDocumentInfo.java,
+	service/NzdlServiceClient.java: added the NzdlDocumentInfo and
+	DocumentInfoDialog classes, mainly to inform myself about how the
+	metadata works so I can understand the new metadata changes.
+
+2001-05-23 14:41  say1
+
+	* ChangeLog: updated ChangeLog
+
+2001-05-05 10:49  say1
+
+	* org/nzdl/gsdl/Makefile: removed classifications
+
+2001-04-26 10:06  say1
+
+	* ChangeLog, org/nzdl/gsdl/service/NzdlServiceClient.java: updated
+	ChangeLog
+
+2001-04-18 00:53  bas6
+
+	* org/nzdl/gsdl/service/package.html: modified simple example in
+	org/nzdl/gsdl/service/package.html to connect to remote servers
+
+2001-04-15 11:33  daven
+
+	* org/nzdl/gsdl/service/: NzdlCollectionInfo.java,
+	NzdlResultSet.java: correct a bug in the term frequency code from
+	yesterday that lost some items. Added comments.
+
+2001-04-15 11:32  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CollectionInfoDialog.java,
+	SearchPanel.java: use new APIs in service.*
+
+2001-04-14 17:30  daven
+
+	* org/nzdl/gsdl/service/NzdlCollectionInfo.java: altered new method
+	name for greater clarity
+
+2001-04-14 17:29  daven
+
+	* org/nzdl/gsdl/util/NzdlConstants.java: treat Greenstone terms as
+	constants, e.g. collectionextra, iconcollectionsmall.
+
+2001-04-14 17:28  daven
+
+	* org/nzdl/gsdl/service/NzdlCollectionInfo.java: added a new set of
+	accessor methods for collection information.  So, now you ask for
+	getLongCollectionName() from a NzdlCollectionInfo object rather
+	than using Maps and Sets of metadata. This should provide a tidier
+	API - it will certainly tidy up CollectionInfoDialog.java  The
+	methods are all in pairs with a boolean test and another to get the
+	data, e.g.  public boolean isLongCollectionName() public String
+	getLongCollectionName()
+
+2001-04-14 17:23  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CollectionInfoDialog.java,
+	SearchPanel.java: use the new collectionInfo methods rather than
+	getting the metadata via NzdlService
+
+2001-04-14 12:38  daven
+
+	* org/nzdl/gsdl/util/NzdlConstants.java:  tidied up
+
+2001-04-14 12:37  daven
+
+	* org/nzdl/gsdl/service/: NzdlResponse.java, NzdlResultSet.java:
+	added method for sorting the term frequency Map so that we display
+	them in descending order, most frequent first. I suppose this could
+	be a preference - but someone else can do that :-)
+
+2001-04-14 12:35  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: Constants.java,
+	SearchPanel.java: altered display of term frequencies.
+
+2001-04-04 23:50  say1
+
+	* org/nzdl/gsdl/service/NzdlCrossCollectionWrapper.java: hopefully
+	that"s the only file i missed ...
+
+2001-04-04 23:44  say1
+
+	* ChangeLog, org/nzdl/gsdl/Proxy.java,
+	org/nzdl/gsdl/service/Makefile,
+	org/nzdl/gsdl/service/NzdlMultiWayWrapper.java,
+	org/nzdl/gsdl/service/NzdlRequest.java,
+	org/nzdl/gsdl/service/NzdlServiceClient.java,
+	org/nzdl/gsdl/service/NzdlServiceServer.java,
+	org/nzdl/gsdl/service/NzdlWrapper.java: Cross collection searching
+
+2001-04-04 23:32  say1
+
+	* org/nzdl/gsdl/: SimpleGraphicalClient/SearchPanel.java,
+	service/NzdlResultSet.java: added line showing the query term
+	qrequencies
+
+2001-04-04 23:07  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: error
+	prevention for popup menu.
+
+2001-04-04 22:44  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: Berry.java,
+	BerryBasketModel.java, BerryBasketPanel.java, CSFrame.java,
+	CSModel.java, QueryHistoryItem.java, QueryHistoryModel.java,
+	Result.java, SearchPanel.java: turned on the BerryBasket. Try
+	right-clicking on a result in the results List to add one - no
+	delete yet. Re-sizing maybe improved as well - no guarantees yet
+	though.
+
+2001-04-04 15:01  say1
+
+	* ChangeLog, org/nzdl/gsdl/Makefile,
+	org/nzdl/gsdl/SimpleGraphicalClient/CSModel.java,
+	org/nzdl/gsdl/SimpleGraphicalClient/Makefile,
+	org/nzdl/gsdl/service/Makefile,
+	org/nzdl/gsdl/service/NzdlLogWrapper.java,
+	org/nzdl/gsdl/util/Makefile: changed JAVACOPTIONS. log files now
+	written to home directory. error catching in CSModel. ChangeLog.
+
+2001-04-04 11:29  say1
+
+	* ChangeLog, org/nzdl/gsdl/util/NzdlConstants.java,
+	org/nzdl/gsdl/util/NzdlPreferences.java,
+	org/nzdl/gsdl/util/NzdlServiceFactory.java: fixed properties
+	problem. saving IORs and properties in the users home directory.
+	ChangeLog
+
+2001-04-03 22:29  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: QueryHistoryItem.java,
+	QueryHistoryModel.java, SearchPanel.java: updated QueryHistory to
+	include options (stemming) and to display them..  however there is
+	a screen real estate problem :-( But checking in the underlying
+	support anyway. Will sort out display soon.
+
+2001-04-03 22:01  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: added
+	integrity checking for boolean/ranked preference
+
+2001-04-03 21:36  daven
+
+	* org/nzdl/gsdl/: SimpleGraphicalClient/CSFrame.java,
+	SimpleGraphicalClient/SearchPanel.java, util/NzdlConstants.java,
+	util/NzdlPreferences.java: retain state of non-explicit preferences
+	(e.g. casfolding, stemming)
+
+2001-04-03 17:22  say1
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/ChangeLogDialog.java: set the
+	ChangeLogDialog to be uneditable
+
+2001-04-03 17:08  say1
+
+	* ChangeLog, org/nzdl/gsdl/SimpleGraphicalClient/Constants.java,
+	org/nzdl/gsdl/SimpleGraphicalClient/PreferencesDialog.java,
+	org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java,
+	org/nzdl/gsdl/service/NzdlMultiWayWrapper.java,
+	org/nzdl/gsdl/util/NzdlConstants.java,
+	org/nzdl/gsdl/util/NzdlPreferences.java, ChangeLog: comments in
+	NzdlPreferences. Moved some constants from
+	SimpleGraphicalClient/Constants to util/NzdlConstants so everyone
+	could play with them. Made NzdlMultiWayWrapper dynamically
+	load-balancing, with a rebalance on every getCollectionSet
+
+2001-04-03 15:45  say1
+
+	* org/nzdl/gsdl/: Makefile, Proxy.java, SimpleServer.java,
+	service/NzdlMultiWayWrapper.java, util/NzdlServiceFactory.java:
+	renamed SimpleServer.java Proxy.java. Fixed bug in
+	NzdlServiceFactory.java. Fixed NzdlMultiWayWrapper.java so i only
+	found a single instance of each collection
+
+2001-04-03 13:08  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/ChangeLogDialog.java: tidied
+	up ChangeLogDialog  appearance
+
+2001-04-03 12:54  say1
+
+	* ChangeLog,
+	org/nzdl/gsdl/SimpleGraphicalClient/ChangeLogDialog.java: added the
+	ChangeLogDialog.java file
+
+2001-04-03 02:31  say1
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/CSModel.java: testing
+	collections with ping
+
+2001-04-03 01:12  say1
+
+	* ChangeLog, Makefile,
+	org/nzdl/gsdl/SimpleGraphicalClient/CSFrame.java,
+	org/nzdl/gsdl/SimpleGraphicalClient/Constants.java,
+	org/nzdl/gsdl/SimpleGraphicalClient/Makefile: added lots of
+	Changelog stuff
+
+2001-04-02 23:32  say1
+
+	* Makefile, org/nzdl/gsdl/Makefile,
+	org/nzdl/gsdl/util/NzdlConstants.java,
+	org/nzdl/gsdl/util/NzdlCorbaFactory.java: removed ptp code from
+	Makefiles. fixed minor constants problem.
+
+2001-04-02 21:32  daven
+
+	* org/nzdl/gsdl/service/NzdlQuery.java: added isStemming and
+	isCaseFolding as accessor methods to provide symmetry with the new
+	set methods.  Didn't delete the string versions - but I don't see a
+	good reason to keep them...
+
+2001-04-02 21:22  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: Constants.java,
+	QueryHistoryModel.java, SearchPanel.java: added ranked and boolean
+	searching options to the interface.
+
+2001-04-02 18:09  daven
+
+	* org/nzdl/gsdl/util/NzdlConstants.java:  stemming and case folding
+	using new boolean API.
+
+2001-04-02 18:09  daven
+
+	* org/nzdl/gsdl/: SimpleGraphicalClient/SearchPanel.java,
+	service/NzdlQuery.java: stemming and case folding using new boolean
+	API.
+
+2001-04-02 17:53  daven
+
+	* org/nzdl/gsdl/service/NzdlQuery.java: added boolean version of
+	setCaseFolding method
+
+2001-04-02 17:52  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: added
+	stemming and cas folding options.
+
+2001-04-02 17:12  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: Constants.java,
+	QueryHistoryItem.java, QueryHistoryModel.java,
+	QueryHistoryPanel.java, SearchPanel.java: updated QueryHistory to
+	show time and num of hits. Removed restriction on number of hits
+	returned (which was 10).
+
+2001-04-02 15:57  say1
+
+	* corbaiface.idl: unchanged the idl file ...
+
+2001-03-31 22:44  say1
+
+	* corbaiface.idl, org/nzdl/gsdl/SearchAllCollections.java,
+	org/nzdl/gsdl/service/NzdlQueryHit.java,
+	org/nzdl/gsdl/service/NzdlResponse.java,
+	org/nzdl/gsdl/service/NzdlResultSet.java: changed corbaiface.idl
+	"long"->"long long" and propogated the chnages ... also added
+	comments to the idl file.
+
+2001-03-27 10:57  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: QueryHistoryModel.java,
+	QueryHistoryPanel.java, SearchPanel.java: Custom cell renderer for
+	the QueryHistoryPanel - with long collection names as tooltips.
+
+2001-03-26 19:07  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: Berry.java,
+	BerryBasketModel.java, BerryBasketPanel.java, CSFrame.java,
+	CSModel.java, CollectionInfoDialog.java, Constants.java,
+	Query.java, QueryHistoryItem.java, QueryHistoryModel.java,
+	QueryHistoryPanel.java, SearchPanel.java, TableMap.java,
+	TableSorter.java: added QueryHistory, tooltips on
+	collectionInfoButton. Altered CSModel to retain CollectionInfo
+	objects and longCollectionNames for performance. Added files for a
+	BerryBasket - to be turned on soon. Added sorting of the
+	QueryHistory via the TableMap and TableSorter files - from the Java
+	Swing tutorial - not sure about GPL status of these 2.
+
+2001-03-24 15:16  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CSFrame.java,
+	CollectionInfoDialog.java, Constants.java, PreferencesDialog.java,
+	SearchPanel.java: dynamically update display mode based on
+	preference changes. i.e. if the user switches to raw text mode the
+	document display should update on the exit of the prefences dialog,
+	not until the user selects a new result.  Altered the listhandler
+	in SearchPanel.java to simplify this and reduce occurrences of
+	multiple code.
+
+2001-03-22 15:48  say1
+
+	* Makefile, org/nzdl/gsdl/Makefile,
+	org/nzdl/gsdl/SimpleClient.java, org/nzdl/gsdl/hli/Collection.java,
+	org/nzdl/gsdl/hli/Document.java, org/nzdl/gsdl/hli/Makefile,
+	org/nzdl/gsdl/hli/Query.java, org/nzdl/gsdl/hli/Server.java,
+	org/nzdl/gsdl/service/NzdlCollectionInfo.java,
+	org/nzdl/gsdl/service/NzdlLogWrapper.java,
+	org/nzdl/gsdl/service/NzdlMultiWayWrapper.java,
+	org/nzdl/gsdl/service/NzdlServiceClient.java,
+	org/nzdl/gsdl/util/NzdlServiceFactory.java: change int-> long in a
+	number of places, new createNzdlService method taking only an IOR,
+	added the start of a hli (high level interface
+
+2001-03-21 10:50  paynter
+
+	* org/nzdl/gsdl/util/: NzdlPreferences.java,
+	NzdlServiceFactory.java: 
+	Tidying up debugging output.
+
+2001-03-21 10:36  paynter
+
+	* org/nzdl/gsdl/SimpleClient.java: 
+	Removed unnecessary function.
+
+2001-03-21 10:36  paynter
+
+	* org/nzdl/gsdl/SearchAllCollections.java: 
+	Updated handling of IOR keys.
+
+2001-03-20 19:16  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CollectionInfoDialog.java,
+	SearchPanel.java: improved collection information dialog with HTML
+	display of long collection descriptions
+
+2001-03-20 14:39  paynter
+
+	* org/nzdl/gsdl/SearchAllCollections.java: 
+	Get collection name and description.
+
+2001-03-20 13:55  paynter
+
+	* org/nzdl/gsdl/service/NzdlServiceClient.java: 
+	More of the same.
+
+2001-03-20 12:37  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/GMLDocument.java: parsing
+	instrumentation for structured documents
+
+2001-03-20 12:29  paynter
+
+	* org/nzdl/gsdl/service/NzdlServiceClient.java: 
+	Cleaned up debugging output a little.
+
+2001-03-20 11:22  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: error
+	checking and empty document handling
+
+2001-03-20 10:35  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: tidying and
+	error trapping for caret setting in empty documents
+
+2001-03-20 10:13  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CSFrame.java,
+	CollectionInfoDialog.java: tidying up CollectionInfoDialog
+
+2001-03-20 08:56  say1
+
+	* org/nzdl/gsdl/: SimpleClient.java,
+	SimpleGraphicalClient/CollectionInfoDialog.java,
+	SimpleGraphicalClient/Makefile, service/NzdlCollectionInfo.java:
+	fixed a pair of date bugs for Dave. classification updates
+
+2001-03-19 21:21  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CollectionInfoDialog.java,
+	PreferencesDialog.java, SearchPanel.java: added
+	CollectionInfoDialog.java to display collection level data
+
+2001-03-18 20:25  say1
+
+	* org/nzdl/gsdl/util/NzdlServiceFactory.java: fixed a buf when no
+	IORs were found ...
+
+2001-03-18 20:16  say1
+
+	* org/nzdl/gsdl/Makefile: initial commit of the classification
+	stuff. now appears to work, but is not integrated.
+
+2001-03-18 12:39  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: Constants.java,
+	PreferencesDialog.java, SearchPanel.java,
+	SimpleGraphicalClient.java: preference for displaying raw text or
+	HTML now working
+
+2001-03-18 10:44  daven
+
+	* org/nzdl/gsdl/util/NzdlServiceFactory.java: fixed multiple sever
+	bug (stuart from dave"s machine )
+
+2001-03-16 13:47  say1
+
+	* org/nzdl/gsdl/: SimpleServer.java,
+	SimpleGraphicalClient/Makefile,
+	SimpleGraphicalClient/PreferencesDialog.java,
+	service/NzdlMultiWayWrapper.java, util/Makefile,
+	util/NzdlPreferences.java, util/NzdlServiceFactory.java: added
+	NzdlPreferences.java and hooked it up in all the necessary places.
+	The PreferencesDialog doesn"t save \(yet\).
+
+2001-03-16 11:10  say1
+
+	* Makefile: removed diff
+
+2001-03-16 09:04  say1
+
+	* corbaiface.idl, org/nzdl/gsdl/service/NzdlCollectionInfo.java:
+	added comments to corbaiface.idl and an hostname accessor to
+	NzdlCollectionInfo
+
+2001-03-15 20:41  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/PreferencesDialog.java: prefs
+	dialog gui code
+
+2001-03-15 20:39  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CSFrame.java, CSModel.java,
+	Constants.java, GMLDocument.java, SearchPanel.java,
+	SimpleGraphicalClient.java: preferences dialog added
+
+2001-03-15 13:58  say1
+
+	* org/nzdl/gsdl/util/NzdlServiceFactory.java: fixed code after
+	previous commit ...
+
+2001-03-15 13:54  say1
+
+	* org/nzdl/gsdl/: service/NzdlMultiWayWrapper.java,
+	util/NzdlServiceFactory.java: added files i forgot to add before
+	...
+
+2001-03-15 11:47  say1
+
+	* org/nzdl/gsdl/util/NzdlIORs.java: removed
+	org/nzdl/gsdl/util/NzdlIORs.java
+
+2001-03-15 11:44  say1
+
+	* org/nzdl/gsdl/SimpleServer.java: helps is it compiles ...
+
+2001-03-15 11:41  say1
+
+	* org/nzdl/gsdl/: SimpleClient.java, SimpleServer.java,
+	SimpleGraphicalClient/SimpleGraphicalClient.java,
+	service/NzdlCollectionInfo.java, util/Makefile: renamed NzdlIORs to
+	NzdlServiceFactory updated server. update NzdlCollectionIn
+
+2001-03-14 15:15  say1
+
+	* org/nzdl/gsdl/: SimpleClient.java,
+	SimpleGraphicalClient/SimpleGraphicalClient.java, service/Makefile,
+	service/NzdlCollectionInfo.java, service/NzdlWrapper.java,
+	util/NzdlCorbaFactory.java, util/NzdlIORs.java: implemented
+	multiway wrapper to allow a client to connect to multiple servers
+	seamlessly
+
+2001-03-14 15:06  say1
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: regularised
+	borders
+
+2001-03-14 07:15  cs025
+
+	* org/nzdl/gsdl/service/NzdlResponse.java: Error in parsing of
+	metadata corrected; the values of metadata items were agglomerated
+	over a set of metadata items, rather than being cleared at the
+	start of each novel metadata item
+
+2001-03-14 04:01  cs025
+
+	* corbaiface.idl, org/nzdl/gsdl/service/NzdlServiceClient.java,
+	org/nzdl/gsdl/service/NzdlServiceServer.java: Changed ping
+	parameters and behaviour in C++; corresponding changes made in java
+	client.
+
+2001-03-13 13:42  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java:
+	instrumenting
+
+2001-03-13 13:03  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: return
+	scrolling to use setCaretPosition()
+
+2001-03-13 11:50  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: Result.java,
+	SearchPanel.java: killed bugs concerning 0 hits, instrumented code
+
+2001-03-13 11:49  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/GMLDocument.java: class to
+	represent GML Documents
+
+2001-03-13 07:38  bas6
+
+	* org/nzdl/gsdl/: SimpleServer.java, package.html,
+	SimpleGraphicalClient/package.html,
+	service/NzdlCollectionInfo.java, service/NzdlQuery.java,
+	service/NzdlQueryHit.java, service/NzdlRequest.java,
+	service/NzdlResponse.java, service/NzdlResultSet.java,
+	service/NzdlService.java, service/NzdlServiceClient.java,
+	service/package.html, util/NzdlConstants.java,
+	util/NzdlCorbaFactory.java, util/NzdlHosts.java,
+	util/NzdlIORs.java, util/package.html: Tidied up some comments &
+	added package.html to SimpleGraphical Client
+
+2001-03-12 22:57  say1
+
+	* org/nzdl/gsdl/: SimpleGraphicalClient/CSFrame.java,
+	SimpleGraphicalClient/Constants.java,
+	SimpleGraphicalClient/SearchPanel.java,
+	service/NzdlLogWrapper.java: logging fixes. clearing objects in the
+	GUI to ease garbage collection. menu item to force global garbage
+	collections.
+
+2001-03-12 14:32  say1
+
+	* org/nzdl/gsdl/service/NzdlCollectionInfo.java: added accessors
+	for HTTPPrefix and getHTTPDomain so Dave can do image work
+
+2001-03-12 13:23  say1
+
+	* org/nzdl/gsdl/: SimpleGraphicalClient/CSFrame.java,
+	SimpleGraphicalClient/CSModel.java,
+	SimpleGraphicalClient/Result.java,
+	SimpleGraphicalClient/ResultModel.java,
+	SimpleGraphicalClient/SearchPanel.java,
+	SimpleGraphicalClient/SimpleGraphicalClient.java,
+	service/NzdlQuery.java, service/NzdlQueryHit.java,
+	service/NzdlRequest.java, service/NzdlResponse.java,
+	service/NzdlResultSet.java, service/NzdlService.java,
+	service/NzdlServiceServer.java, util/NzdlCorbaFactory.java,
+	util/NzdlHosts.java, util/NzdlIORs.java: many changes to the import
+	lines ...
+
+2001-03-12 00:05  say1
+
+	* org/nzdl/gsdl/service/NzdlCacheWrapper.java: turned off the cache
+	miss spam ...
+
+2001-03-11 23:58  say1
+
+	* Makefile, README, org/nzdl/gsdl/Makefile,
+	org/nzdl/gsdl/service/Makefile,
+	org/nzdl/gsdl/service/NzdlCacheWrapper.java,
+	org/nzdl/gsdl/service/NzdlDocSaveWrapper.java,
+	org/nzdl/gsdl/service/NzdlLogWrapper.java,
+	org/nzdl/gsdl/service/NzdlServiceCachingClient.java,
+	org/nzdl/gsdl/service/NzdlServiceClient.java,
+	org/nzdl/gsdl/service/NzdlWrapper.java,
+	org/nzdl/gsdl/util/Makefile, org/nzdl/gsdl/util/NzdlIORs.java:
+	fixed Makefiles to stop deleting html files. Added the notion of a
+	Wrapper. Converted NzdlCachingServiceClient to NzdlCacheWrapper.
+	Added NzdlDocSaveWrapper. Added NzdlLogWrapper. Added functionality
+	to NzdlIORs to use these.
+
+2001-03-11 09:57  bas6
+
+	* overview.html, gnu/getopt/package.html,
+	org/nzdl/gsdl/package.html,
+	org/nzdl/gsdl/service/nzdl-service-package.png,
+	org/nzdl/gsdl/service/package.html,
+	org/nzdl/gsdl/util/package.html: Added overview.html. Added
+	package.html to: getopt, gsdl, ptp, service, util,
+	SimpleGraphicalClient. Added nzdl-service-package.png to service.
+
+2001-03-11 09:27  bas6
+
+	* Makefile, org/nzdl/gsdl/service/NzdlCollectionInfo.java,
+	org/nzdl/gsdl/service/NzdlQueryHit.java,
+	org/nzdl/gsdl/service/NzdlRequest.java,
+	org/nzdl/gsdl/service/NzdlResultSet.java,
+	org/nzdl/gsdl/service/NzdlService.java,
+	org/nzdl/gsdl/service/NzdlServiceClient.java,
+	org/nzdl/gsdl/util/NzdlConstants.java,
+	org/nzdl/gsdl/util/NzdlCorbaFactory.java: Added comments to
+	NzdlQueryHit, NzdlService, NzdlServiceClient, NzdlConstants. 
+	Modified Makefile (make docs) to include: SimpleGraphicalClient and
+	copy image for service package.html
+
+2001-03-10 16:11  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CSModel.java,
+	SearchPanel.java: minor performance tweaks, tidying, dead code
+	removal, comment removal
+
+2001-03-10 12:50  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: switch to
+	using JTextPane, HTMLDocument, EditorKit etc implementation
+
+2001-03-09 23:26  say1
+
+	* org/nzdl/gsdl/: SimpleGraphicalClient/SearchPanel.java,
+	service/NzdlResponse.java, service/NzdlServiceCachingClient.java,
+	util/NzdlIORs.java: caching NzdlService now works ...
+
+2001-03-09 21:46  say1
+
+	* org/nzdl/gsdl/service/: Makefile, NzdlServiceCachingClient.java:
+	started work on the caching client
+
+2001-03-09 19:19  say1
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: GUI size
+	changes
+
+2001-03-09 19:09  say1
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java: resolved
+	issues
+
+2001-03-09 19:00  say1
+
+	* org/nzdl/gsdl/: SimpleClient.java,
+	SimpleGraphicalClient/CSModel.java,
+	SimpleGraphicalClient/SearchPanel.java,
+	service/NzdlServiceClient.java: fixed bugs and added error checking
+	...
+
+2001-03-09 17:20  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: Result.java,
+	SearchPanel.java: dead code removal, performance improvements,
+	comment tidying 
+	-------------------------------------------------------------------
+	---
+
+2001-03-09 14:33  say1
+
+	* org/nzdl/gsdl/: SimpleGraphicalClient/CSModel.java,
+	SimpleGraphicalClient/SearchPanel.java,
+	SimpleGraphicalClient/SimpleGraphicalClient.java,
+	service/NzdlCollectionInfo.java: Added Model initialisation to
+	CSModel. Fixed the bug where empty collections appear. Fixed the
+	exception thrown on an empty doc set
+
+2001-03-09 13:28  say1
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CSFrame.java,
+	Constants.java, Makefile: tried to add a poll action ...
+
+2001-03-09 12:44  say1
+
+	* org/nzdl/gsdl/: Makefile, SimpleGraphicalClient/CSFrame.java,
+	SimpleGraphicalClient/CSModel.java,
+	SimpleGraphicalClient/Constants.java,
+	SimpleGraphicalClient/Makefile, SimpleGraphicalClient/Result.java,
+	SimpleGraphicalClient/ResultModel.java,
+	SimpleGraphicalClient/SearchPanel.java,
+	SimpleGraphicalClient/SimpleGraphicalClient.java: added Makefile
+	for dave"s stuff. added a few comments ...
+
+2001-03-09 12:07  daven
+
+	* org/nzdl/gsdl/SimpleGraphicalClient/: CSFrame.java, CSModel.java,
+	Constants.java, Result.java, ResultModel.java, SearchPanel.java,
+	SimpleGraphicalClient.java: added SimpleGraphicalClient, uses Java
+	1.3 Swing
+
+2001-03-09 11:49  say1
+
+	* org/nzdl/gsdl/util/NzdlIORs.java: bug fix
+
+2001-03-09 11:30  say1
+
+	* TODO, org/nzdl/gsdl/SimpleClient.java,
+	org/nzdl/gsdl/util/NzdlIORs.java: moved init stuff to NzdlIORs.
+	comments
+
+2001-03-08 14:34  say1
+
+	* org/nzdl/gsdl/util/NzdlIORs.java: helps if i add all the files
+	...
+
+2001-03-08 14:28  say1
+
+	* org/nzdl/gsdl/: SimpleClient.java, SimpleServer.java,
+	util/Makefile: proxying now appears to work ...
+
+2001-03-08 02:10  say1
+
+	* org/nzdl/gsdl/SimpleClient.java: getior now works properly
+
+2001-03-08 01:41  say1
+
+	* org/nzdl/gsdl/: SimpleClient.java,
+	service/NzdlServiceClient.java: fixed teh error where bad or old
+	IORs would cause a crash
+
+2001-03-07 16:26  say1
+
+	* org/nzdl/gsdl/: SimpleClient.java,
+	service/NzdlServiceClient.java: bug fixes
+
+2001-03-07 13:37  say1
+
+	* TODO, org/nzdl/gsdl/util/NzdlHosts.java: documentation updates
+
+2001-03-06 09:26  say1
+
+	* org/nzdl/gsdl/: Makefile, util/Makefile: extra docs
+
+2001-03-05 19:25  say1
+
+	* Makefile, corbaiface.idl,
+	org/nzdl/gsdl/SearchAllCollections.java,
+	org/nzdl/gsdl/SimpleClient.java, org/nzdl/gsdl/SimpleServer.java,
+	org/nzdl/gsdl/service/NzdlServiceClient.java,
+	org/nzdl/gsdl/service/NzdlServiceServer.java: updated for new idl
+	file. extra documenation. a little more PTP work
+
+2001-03-05 15:08  daven
+
+	* org/nzdl/gsdl/SimpleClient.java: spelling
+
+2001-03-05 12:01  say1
+
+	* org/nzdl/gsdl/Makefile: tinkered with makefiles. ptp now gettign
+	built by default
+
+2001-03-05 09:29  say1
+
+	* Makefile, org/nzdl/gsdl/Makefile: P2P work. still not complete
+
+2001-03-05 08:44  bas6
+
+	* org/nzdl/gsdl/service/: NzdlQuery.java, NzdlRequest.java,
+	NzdlResponse.java, NzdlResultSet.java, NzdlServiceServer.java:
+	Documenting NzdlQuery, NzdlResponse,  NzdlResultSet &
+	NzdlServiceServer (removed some extraneous @see comments)
+
+2001-03-03 09:22  bas6
+
+	* org/nzdl/gsdl/service/NzdlQuery.java: add comments to NzdlQuery
+
+2001-03-01 17:06  paynter
+
+	* Makefile: 
+	Changed Test rules.
+
+2001-03-01 17:06  paynter
+
+	* org/nzdl/gsdl/SearchAllCollections.java: 
+	Attempt to get collection metadata.
+
+2001-03-01 16:23  paynter
+
+	* org/nzdl/gsdl/Makefile: 
+	Cleaned up, added SearchAllCollections.
+
+2001-03-01 16:21  paynter
+
+	* Makefile: 
+	Added "make test"
+
+2001-03-01 16:11  paynter
+
+	* org/nzdl/gsdl/SearchAllCollections.java: 
+	A program to seach all the available collections for a query term.
+
+2001-03-01 16:04  say1
+
+	* GPL: added GPL file
+
+2001-03-01 14:05  paynter
+
+	* Makefile, org/nzdl/gsdl/Makefile,
+	org/nzdl/gsdl/SimpleClient.java, org/nzdl/gsdl/SimpleServer.java,
+	org/nzdl/gsdl/service/NzdlCollectionInfo.java,
+	org/nzdl/gsdl/service/NzdlQuery.java,
+	org/nzdl/gsdl/service/NzdlQueryHit.java,
+	org/nzdl/gsdl/service/NzdlRequest.java,
+	org/nzdl/gsdl/service/NzdlResponse.java,
+	org/nzdl/gsdl/service/NzdlResultSet.java,
+	org/nzdl/gsdl/service/NzdlService.java,
+	org/nzdl/gsdl/service/NzdlServiceClient.java,
+	org/nzdl/gsdl/service/NzdlServiceServer.java,
+	org/nzdl/gsdl/util/NzdlConstants.java,
+	org/nzdl/gsdl/util/NzdlCorbaFactory.java,
+	org/nzdl/gsdl/util/NzdlHosts.java: 
+	Updated main directory to org.nzdl.gsdl
+
+2001-03-01 14:03  say1
+
+	* README, TODO: added README, updated TODO ...
+
+2001-03-01 13:27  paynter
+
+	* gnu/getopt/Makefile: 
+	Clean docs properly.
+
+2001-03-01 13:27  say1
+
+	* Makefile: merged all docs into a single group
+
+2001-03-01 13:16  say1
+
+	* org/nzdl/gsdl/: SimpleServer.java,
+	service/NzdlServiceServer.java: maybe it will compile this time?
+
+2001-03-01 13:15  paynter
+
+	* gnu/getopt/Makefile: 
+	Proper compilation of Java
+
+2001-03-01 13:10  paynter
+
+	* Makefile: 
+	Make the GNU getopts package.
+
+2001-03-01 13:08  paynter
+
+	* gnu/getopt/: COPYING.LIB, ChangeLog, Getopt.java,
+	GetoptDemo.java, LongOpt.java, Makefile, MessagesBundle.properties,
+	MessagesBundle_cs.properties, MessagesBundle_de.properties,
+	MessagesBundle_fr.properties, MessagesBundle_no.properties, README:
+	
+	GNU Getopts code.
+
+2001-03-01 13:01  paynter
+
+	* Makefile: 
+	Add the top-level directory to the java CLASSPATH.
+
+2001-03-01 12:58  say1
+
+	* org/nzdl/gsdl/: SimpleClient.java, service/Makefile,
+	service/NzdlServiceClient.java, service/NzdlServiceImpl.java,
+	service/NzdlServiceServer.java, util/NzdlHosts.java: changes to get
+	it to compile ...
+
+2001-03-01 12:45  say1
+
+	* TODO, org/nzdl/gsdl/SimpleServer.java,
+	org/nzdl/gsdl/service/NzdlServiceImpl.java: server changes
+
+2001-02-28 15:30  paynter
+
+	* Makefile: 
+	Put javadoc documentation in its own directory.
+
+2001-02-27 16:15  say1
+
+	* Makefile, org/nzdl/gsdl/Makefile,
+	org/nzdl/gsdl/SimpleServer.java,
+	org/nzdl/gsdl/service/NzdlCollectionInfo.java,
+	org/nzdl/gsdl/util/NzdlCorbaFactory.java: started work on the Java
+	server. still many hacks.
+
+2001-02-27 11:24  say1
+
+	* Makefile: javadoc changes
+
+2001-02-26 01:07  say1
+
+	* org/nzdl/gsdl/SimpleClient.java: checked in Brett"s getIorKey
+	changes. i changed enough that any mistakes will be mine not his :)
+
+2001-02-25 21:37  say1
+
+	* org/nzdl/gsdl/: service/Makefile, util/Makefile,
+	util/NzdlHosts.java: incorperated the http IOR method (not really
+	tested)
+
+2001-02-25 17:25  say1
+
+	* Makefile: check currentness of corbaiface.idl
+
+2001-02-24 19:44  say1
+
+	* org/nzdl/gsdl/: SimpleClient.java, service/NzdlServiceImpl.java:
+	many changes to SimpleClient. a few changes to NzdlServiceImpl.
+
+2001-02-24 15:13  say1
+
+	* org/nzdl/gsdl/SimpleClient.java: put the SimpleClient in the
+	package
+
+2001-02-24 14:56  say1
+
+	* Makefile: make file change
+
+2001-02-23 16:22  paynter
+
+	* Makefile: 
+	Default rule is to make all.
+
+2001-02-23 16:03  say1
+
+	* Makefile, org/nzdl/gsdl/Makefile, org/nzdl/gsdl/service/Makefile,
+	org/nzdl/gsdl/util/Makefile: added Makefiles
+
+2001-02-23 15:53  paynter
+
+	* Makefile, corbaiface.idl, org/nzdl/gsdl/SimpleClient.java,
+	org/nzdl/gsdl/service/NzdlCollectionInfo.java,
+	org/nzdl/gsdl/service/NzdlQuery.java,
+	org/nzdl/gsdl/service/NzdlQueryHit.java,
+	org/nzdl/gsdl/service/NzdlRequest.java,
+	org/nzdl/gsdl/service/NzdlResponse.java,
+	org/nzdl/gsdl/service/NzdlResultSet.java,
+	org/nzdl/gsdl/service/NzdlService.java,
+	org/nzdl/gsdl/service/NzdlServiceImpl.java,
+	org/nzdl/gsdl/util/NzdlConstants.java,
+	org/nzdl/gsdl/util/NzdlCorbaFactory.java: Initial revision
+
+2001-02-23 15:53  paynter
+
+	* Makefile, corbaiface.idl, org/nzdl/gsdl/SimpleClient.java,
+	org/nzdl/gsdl/service/NzdlCollectionInfo.java,
+	org/nzdl/gsdl/service/NzdlQuery.java,
+	org/nzdl/gsdl/service/NzdlQueryHit.java,
+	org/nzdl/gsdl/service/NzdlRequest.java,
+	org/nzdl/gsdl/service/NzdlResponse.java,
+	org/nzdl/gsdl/service/NzdlResultSet.java,
+	org/nzdl/gsdl/service/NzdlService.java,
+	org/nzdl/gsdl/service/NzdlServiceImpl.java,
+	org/nzdl/gsdl/util/NzdlConstants.java,
+	org/nzdl/gsdl/util/NzdlCorbaFactory.java: Inital CVS version of
+	Aziz' Java Corba modules (which have been edited a little by a lot
+	of people).
+        
+
Index: other-projects/gs2-java-client/trunk/GPL
===================================================================
--- other-projects/gs2-java-client/trunk/GPL	(revision 21017)
+++ other-projects/gs2-java-client/trunk/GPL	(revision 21017)
@@ -0,0 +1,345 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: other-projects/gs2-java-client/trunk/Makefile
===================================================================
--- other-projects/gs2-java-client/trunk/Makefile	(revision 21017)
+++ other-projects/gs2-java-client/trunk/Makefile	(revision 21017)
@@ -0,0 +1,59 @@
+
+
+.PHONY: docs clean all distclean test
+
+# find the top-level directory of the java-client tree
+# and add it to the java CLASSPATH
+
+ifndef GSJCHOME
+    export GSJCHOME=$(PWD)
+endif
+
+ifdef CLASSPATH
+    export CLASSPATH += :$(GSJCHOME)
+else
+    export CLASSPATH = $(GSJCHOME)
+endif
+
+
+GREENSTONEIDLFILE=/home/nzdl/gsdl/lib/corbaiface.idl
+
+all : org/nzdl/gsdl/corba/gsdlInterface/corbaiface.java
+	(cd gnu/getopt && $(MAKE) all)
+	(cd org/nzdl/gsdl && $(MAKE) all)
+
+#remove -oldImplBase if using Java 1.3 
+org/nzdl/gsdl/corba/gsdlInterface/corbaiface.java : corbaiface.idl
+	idlj  -oldImplBase -verbose -fclient -pkgPrefix gsdlInterface org.nzdl.gsdl.corba corbaiface.idl
+	idlj  -oldImplBase -verbose -fserver -pkgPrefix gsdlInterface org.nzdl.gsdl.corba corbaiface.idl
+	javac org/nzdl/gsdl/corba/gsdlInterface/*.java
+
+
+# Generate documenmtation with Javadoc.
+# This command may use arguments not found in all versions of javadoc
+
+docs :
+	rm -rf docs
+	mkdir docs
+	javadoc -private -version -author -use -d docs -header "Documentation for the <a href=\"http://www.corba.org/\">CORBA</a> interface to the <a href=\"http://www.nzdl.org/\">NZDL</a>'s Greenstone Digital Library software." -footer "This software is distributed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\">GPL</a>" -windowtitle  "Greenstone Digital Library Software from the NZDL" -link "http://www.scms.waikato.ac.nz/help/reference/jdk1.2/docs/api/" gnu.getopt org.nzdl.gsdl org.nzdl.gsdl.service org.nzdl.gsdl.util org.nzdl.gsdl.corba.gsdlInterface org.nzdl.gsdl.SimpleGraphicalClient -overview overview.html
+	cp org/nzdl/gsdl/service/nzdl-service-package.png docs/org/nzdl/gsdl/service/
+	/home/say1/java/cvs2cl.pl 
+
+clean :
+	rm -f log.file.*
+	rm -f knownIORs.properties
+	(cd gnu/getopt && $(MAKE) clean)
+	(cd org/nzdl/gsdl && $(MAKE) clean)
+	rm -rf docs
+	rm -rf org/nzdl/gsdl/corba
+
+distclean : clean
+
+
+test : all
+	java -classpath "$(CLASSPATH)" org.nzdl.gsdl.SimpleClient -a
+
+many : all
+	java -classpath "$(CLASSPATH)" org.nzdl.gsdl.SearchAllCollections -q "marriage customs"
+	echo "This is causing a bunch of corba protocol errors for me.  How about you?"
+
Index: other-projects/gs2-java-client/trunk/README
===================================================================
--- other-projects/gs2-java-client/trunk/README	(revision 21017)
+++ other-projects/gs2-java-client/trunk/README	(revision 21017)
@@ -0,0 +1,92 @@
+README for the the NZDL Greenstone Java client
+
+This code is released under the Gnu Public Licence, as described in the 
+file GPL or on the web site http://www.gnu.org/
+
+
+The main authors of this code are:
+At the University of Waikato NZDL group http://www.nzdl.org:
+   David Bainbridge <davidb@cs.waikato.ac.nz>
+   Dave Nichols <dmn@cs.waikato.ac.nz>,
+   Brett Sheeran <bsheeran@xtra.co.nz> (bas6 in the cvs log)
+   Stuart Yeates <s.yeates@cs.waikato.ac.nz>
+
+Formerly with the NZDL group:
+   Aziz Mahoui <amahoui@yahoo.com>
+   Gordon W. Paynter <paynter@library.ucr.edu>
+
+Collaborators:
+   George Buchanan <g.buchanan@cs.ucl.ac.uk>
+
+************
+
+The NZDL Java-Client interface is a package for writing java applications to 
+communicate with the Greenstone Digital Library.
+
+The interface is through Common Object Reference Broker Architecture (CORBA).
+In order to communicate to Greenstone collections, this software requires that 
+the server machine has Corbaserver installed and running.
+
+************
+
+1. Introduction
+
+It is now possible to access Greenstone collections using the Corba 
+protocol and a Java client.
+
+**
+
+As a Java programmer it is not necessary to understand Corba at all - 
+as the Corba complexity has been reduced to a series of Java objects, 
+methods and interfaces.
+
+**
+
+To demonstrate how to use the Nzdl classes we have created an 
+application, SimpleGraphicalClient, which can query a Corba server 
+and display the resulting documents. This client is probably a 
+good starting point to using Java with the NZDL.
+
+
+2. Getting the code
+
+
+2.1 Getting the SimpleGraphicalClient application source code
+
+cvs -d :pserver:cvs_anon@cvs.scms.waikato.ac.nz:2402/usr/local/global-cvs/gsdl-src checkout java-client
+cd java-client
+make
+
+2.2 Getting the Server
+
+cvs :pserver:cvs_anon@cvs.scms.waikato.ac.nz:2402/usr/local/global-cvs/gsdl-src checkout gsdl
+cd gsdl
+./configure --enable-corba
+make
+make install
+
+(anything else??)
+
+3. Running the client
+
+It is important to get the directories correct - as Java 
+uses them to manage the namespace of the classes. So you 
+should have something that looks like:
+
+java-client/org/nzdl/gsdl/
+
+In this directory you will find:
+
+corba - directory, lots of nasty corba stuff, avoid
+service - the java classes you use, no need to look at this
+SimpleClient.java - early test application
+SimpleGraphicalClient - directory, the Java package
+
+Run:
+java org.nzdl.gsdl.SimpleGraphicalClient.SimpleGraphicalClient
+
+
+4. Running the server
+
+corbaserver -ORBNoCodeSets
+
Index: other-projects/gs2-java-client/trunk/TODO
===================================================================
--- other-projects/gs2-java-client/trunk/TODO	(revision 21017)
+++ other-projects/gs2-java-client/trunk/TODO	(revision 21017)
@@ -0,0 +1,12 @@
+Here are a list of things left to do in the Java client:
+
+1) Merge in Davids interface to the Standford code
+2) Some GUI's ...
+3) Work out why Collection name doesn't work.
+4) Get the p2p stuff going
+5) comments...
+6) ...
+
+a) find out what causes the "specified name does not exist" error 
+     message and how to fix it.
+b) ...
Index: other-projects/gs2-java-client/trunk/corbaiface.idl
===================================================================
--- other-projects/gs2-java-client/trunk/corbaiface.idl	(revision 21017)
+++ other-projects/gs2-java-client/trunk/corbaiface.idl	(revision 21017)
@@ -0,0 +1,230 @@
+// basic elements for text
+
+module gsdlInterface {
+
+typedef sequence<unsigned short> usString;
+
+typedef sequence<string> stringSeq;
+
+struct corbatext_t
+{ 
+  usString text;
+  unsigned short encoding;
+  unsigned long  length;
+};
+
+typedef sequence<corbatext_t> corbatext_tarray;
+
+typedef corbatext_tarray corbatext_tset;
+
+struct corbatext_tmap
+{
+  corbatext_tarray names;
+  corbatext_tarray values;
+};
+
+// standard error values
+
+enum corbaComError
+{ corbaNoError, 
+  corbaAuthenticationFailure, 
+  corbaProtocolError, 
+  corbaConfigurationError, 
+  corbaSystemProblem
+};
+
+//
+// getColInfo response
+//
+
+struct corbaShortColInfo
+{
+  corbatext_t name;
+  corbatext_t host;
+  long        response;
+};
+
+struct corbaColInfoResponse
+{
+  corbaShortColInfo shoftInfo;
+  boolean           isPublic;
+  boolean           isBeta;
+  unsigned long     buildDate;
+  corbatext_tarray  ccsCols;        // Added 05/04/2000
+  corbatext_tarray  languages;
+  unsigned long     numDocs;
+  unsigned long     numWords;
+  unsigned long     numBytes;
+  corbatext_tmap    collectionMeta;
+  corbatext_tmap    format;
+  corbatext_tmap    building;
+  corbatext_t       httpdomain ;    // Added 27/07/2000
+  corbatext_t       httpprefix;     // Added 27/07/2000
+  corbatext_t       receptionist;
+};
+
+//
+// getDocument request
+//
+
+struct corbaDocRequest
+{ 
+  corbatext_t OID;
+  corbatext_t docType;
+  corbatext_t docFormat;
+};
+
+//
+// getDocument response
+//
+
+struct corbaDocResponse
+{ 
+  corbatext_t doc;
+};
+
+enum corbaFilterType
+{
+  booleanType,
+  integerType,
+  enumeratedType,
+  stringType
+};
+
+enum corbaFilterRepeatable
+{
+  onePerQuery,
+  onePerTerm,
+  nPerTerm
+};
+
+struct corbaFilterOption
+{
+  corbatext_t           name;
+  corbaFilterType       type;
+  corbaFilterRepeatable repeatable;
+  corbatext_t           defaultValue;
+  corbatext_tarray      validValues;
+};
+
+typedef sequence<corbaFilterOption> corbaFilterOptionList;
+
+struct corbaFilterOptionsResponse
+{
+  corbaFilterOptionList options;
+  corbatext_tarray      names;
+};
+
+//
+// structures for filter call
+//
+
+struct corbaOptionValue
+{
+  corbatext_t name;
+  corbatext_t value;
+};
+
+typedef sequence<corbaOptionValue> corbaOptionValue_array;
+
+struct corbaFilterRequest
+{ 
+  corbatext_t            filter;
+  corbaOptionValue_array filterOptions;
+  corbatext_tarray       docSet;
+  long                   filterResultOptions;
+  corbatext_t            requestParams;
+  corbatext_t            refParams;
+  corbatext_tset         fields;
+  boolean                getParents;
+};
+
+struct corbaTermInfo
+{
+  corbatext_t      term;
+  long             frequency;
+  corbatext_tarray matchTerms;
+};
+
+typedef sequence<corbaTermInfo> corbaTermInfo_array;
+
+struct corbaMetadataInfo
+{
+  corbatext_t      params;
+  boolean          isRef;
+  corbatext_tarray values;
+  long             id;
+  long             parentid; // dodge for avoiding pointers for the moment
+};
+
+typedef sequence<corbaMetadataInfo> corbaMetadataInfo_array;
+
+struct corbaMetadataInfo_map
+{ 
+  corbatext_tarray        names;
+  corbaMetadataInfo_array values;
+};
+
+typedef sequence<long> corbaDocFreq_array;
+
+struct corbaResultDocInfo
+{
+  corbatext_t             OID;
+  long                    resultNum;
+  long                    ranking;
+  long                    termsMatched;
+  long                    phraseMatched;
+  corbaDocFreq_array      docFreq;
+  corbaMetadataInfo_map   metadata;
+  corbatext_t             classifierMetadataType;    // Added 05/04/2000
+  long                    classifierMetadataOffset;  // Added 05/04/2000
+  corbaMetadataInfo_array metaparents;
+};
+
+typedef sequence<corbaResultDocInfo> corbaResultDocInfo_array;
+
+enum corbaIsApprox
+{
+  resultExact,
+  resultApprox,
+  resultMany
+};
+
+struct corbaFilterResponse
+{
+  long                     numDocs;
+  corbaIsApprox            isApprox;
+  corbaTermInfo_array      termInfo;
+  corbaResultDocInfo_array docInfo;
+};
+
+interface corbaiface
+{
+  boolean   initialise(inout corbaComError error);
+  void      configure(in corbatext_t key, in corbatext_tarray cfgline,
+		      inout corbaComError error);
+  void      collectionList(inout corbatext_tarray collist,
+			   inout corbaComError error);
+  void      hasCollection(in corbatext_t corbaCollection, inout boolean has,
+		       inout corbaComError error);
+  void      ping(in corbatext_t collection, inout boolean wasSuccess, inout corbaComError error);
+  void      getDocument(in corbatext_t collection,
+			inout corbaDocRequest request, inout corbaDocResponse response,
+			inout corbaComError error);
+  void      getCollectInfo(in corbatext_t collection,
+			   inout corbaColInfoResponse response,
+			   inout corbaComError error);
+  void      getFilterInfo(in corbatext_t collection, 
+                          inout corbatext_tarray filterNames, 
+			  inout corbaComError error);
+  void      getFilterOptions(in corbatext_t collection,
+                             in corbatext_t option,
+                             inout corbaFilterOptionsResponse response,
+			     inout corbaComError error);
+  void      filter(in corbatext_t collection,
+		   in corbaFilterRequest request,
+                   inout corbaFilterResponse response,
+                   inout corbaComError error);
+};
+
+};
Index: other-projects/gs2-java-client/trunk/gnu/getopt/COPYING.LIB
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/COPYING.LIB	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/COPYING.LIB	(revision 21017)
@@ -0,0 +1,491 @@
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+    MA 02111-1307, USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
Index: other-projects/gs2-java-client/trunk/gnu/getopt/ChangeLog
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/ChangeLog	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/ChangeLog	(revision 21017)
@@ -0,0 +1,78 @@
+For release 1.0.7 (2000/02/02)
+
+Fixed an obscure POSIX compatibility issue.  When an optstring is "o:",
+then "-o -- foo" should result in -o having an optarg of "foo", not "--"
+as was previously returned.  This new parsing behavior is only enabled
+in POSIX compatibility mode.  Thank to Don Suit (dsuit@fc.hp.com) for
+reporting this and help in communicating proper POSIX behavior.
+
+For release 1.0.6 (1999/06/27)
+
+Added French language messages.  Thanks to Edouard G. Parmelan 
+(Edouard.Parmelan@quadratec.fr) for this contribution.
+
+For release 1.0.5 (1999/03/23)
+
+Fixed bug that caused getopt to throw a StringIndexOutOfBoundsException
+when an empty string ("") argument was encountered.  Thanks to 
+Steffen Siebert (siebert@logware.de) for this bug report and a patch.
+
+For release 1.0.4
+
+Added Norwegian language messages.  Thanks to Bjørn-Ove Heimsund 
+(s811@drone.ii.uib.no) for this contribution.
+
+For release 1.0.3
+
+Added German language messages.  Thanks to Bernhard Bablok 
+(bablokb@gmx.net) for this contribution.
+
+For release 1.0.2
+
+Prevent ArrayIndexOutOfBounds exception if "optstring" is null.  David Karr
+(dkarr@nmo.gtegsc.com) had a problem with this when commenting out options
+during debugging, so I have fixed it.
+
+For release 1.0.1
+
+Added Czech language messages.  Thanks to Roman Szturc (Roman.Szturc@vsb.cz)
+for this contribution.
+
+For release 1.0
+
+No changes.  Just increment release number to 1.0
+
+For release 0.9.2
+
+The sample code has been moved into a separate file called "GetoptDemo.java".
+This is so that it can be legally placed into the public domain and not
+subsumed into the LGPL as would be the case if it were in Getopt.java.
+While I do not encourage anyone to write proprietary software, I feel that
+there is no good purpose served in restricting what someone can do with
+a short example program.
+
+Modified the Makefile and various other files to support the change
+above.
+
+For release 0.9.1
+
+This release contains only minor fixes.  It's always possible it introduces
+some bugs though so unless you are keen on internationalization or are
+having a line separator problem, there is no need to upgrade from 0.9.
+
+-- Messages are now internationalized.  Thanks to Bill King 
+   (wrking@eng.sun.com) for this.
+
+-- Changes all print's to println's to avoid system dependent line
+   separators.
+
+-- All internal variables are now protected.  Several people suggested
+   doing this in response to my request for comments in the help file.
+   No one suggested keeping any variables public.
+
+-- Fixed parts of licensing that mentioned the regular GPL.  Getopt is
+   and always has been licensed under the LPGL.  Thanks to Arieh Markel 
+   (arieh.markel@sun.com) for pointing this out.
+
+
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/Getopt.java
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/Getopt.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/Getopt.java	(revision 21017)
@@ -0,0 +1,1338 @@
+/**************************************************************************
+/* Getopt.java -- Java port of GNU getopt from glibc 2.0.6
+/*
+/* Copyright (c) 1987-1997 Free Software Foundation, Inc.
+/* Java Port Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published 
+/* by  the Free Software Foundation; either version 2 of the License or
+/* (at your option) any later version.
+/*
+/* This program is distributed in the hope that it will be useful, but
+/* WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/* GNU Library General Public License for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; see the file COPYING.LIB.  If not, write to 
+/* the Free Software Foundation Inc., 59 Temple Place - Suite 330, 
+/* Boston, MA  02111-1307 USA
+/**************************************************************************/
+
+package gnu.getopt;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.PropertyResourceBundle;
+import java.text.MessageFormat;
+
+/**************************************************************************/
+
+/**
+  * This is a Java port of GNU getopt, a class for parsing command line
+  * arguments passed to programs.  It it based on the C getopt() functions
+  * in glibc 2.0.6 and should parse options in a 100% compatible manner.
+  * If it does not, that is a bug.  The programmer's interface is also
+  * very compatible.
+  * <p>
+  * To use Getopt, create a Getopt object with a argv array passed to the
+  * main method, then call the getopt() method in a loop.  It will return an
+  * int that contains the value of the option character parsed from the
+  * command line.  When there are no more options to be parsed, it
+  * returns -1.
+  * <p>
+  * A command line option can be defined to take an argument.  If an
+  * option has an argument, the value of that argument is stored in an
+  * instance variable called optarg, which can be accessed using the
+  * getOptarg() method.  If an option that requires an argument is
+  * found, but there is no argument present, then an error message is
+  * printed. Normally getopt() returns a '?' in this situation, but
+  * that can be changed as described below.
+  * <p>
+  * If an invalid option is encountered, an error message is printed
+  * to the standard error and getopt() returns a '?'.  The value of the
+  * invalid option encountered is stored in the instance variable optopt
+  * which can be retrieved using the getOptopt() method.  To suppress
+  * the printing of error messages for this or any other error, set
+  * the value of the opterr instance variable to false using the 
+  * setOpterr() method.
+  * <p>
+  * Between calls to getopt(), the instance variable optind is used to
+  * keep track of where the object is in the parsing process.  After all
+  * options have been returned, optind is the index in argv of the first
+  * non-option argument.  This variable can be accessed with the getOptind()
+  * method.
+  * <p>
+  * Note that this object expects command line options to be passed in the
+  * traditional Unix manner.  That is, proceeded by a '-' character. 
+  * Multiple options can follow the '-'.  For example "-abc" is equivalent
+  * to "-a -b -c".  If an option takes a required argument, the value
+  * of the argument can immediately follow the option character or be
+  * present in the next argv element.  For example, "-cfoo" and "-c foo"
+  * both represent an option character of 'c' with an argument of "foo"
+  * assuming c takes a required argument.  If an option takes an argument
+  * that is not required, then any argument must immediately follow the
+  * option character in the same argv element.  For example, if c takes
+  * a non-required argument, then "-cfoo" represents option character 'c'
+  * with an argument of "foo" while "-c foo" represents the option
+  * character 'c' with no argument, and a first non-option argv element
+  * of "foo".
+  * <p>
+  * The user can stop getopt() from scanning any further into a command line
+  * by using the special argument "--" by itself.  For example: 
+  * "-a -- -d" would return an option character of 'a', then return -1
+  * The "--" is discarded and "-d" is pointed to by optind as the first
+  * non-option argv element.
+  * <p>
+  * Here is a basic example of using Getopt:
+  * <p>
+  * <pre>
+  * Getopt g = new Getopt("testprog", argv, "ab:c::d");
+  * //
+  * int c;
+  * String arg;
+  * while ((c = g.getopt()) != -1)
+  *   {
+  *     switch(c)
+  *       {
+  *          case 'a':
+  *          case 'd':
+  *            System.out.print("You picked " + (char)c + "\n");
+  *            break;
+  *            //
+  *          case 'b':
+  *          case 'c':
+  *            arg = g.getOptarg();
+  *            System.out.print("You picked " + (char)c + 
+  *                             " with an argument of " +
+  *                             ((arg != null) ? arg : "null") + "\n");
+  *            break;
+  *            //
+  *          case '?':
+  *            break; // getopt() already printed an error
+  *            //
+  *          default:
+  *            System.out.print("getopt() returned " + c + "\n");
+  *       }
+  *   }
+  * </pre>
+  * <p>
+  * In this example, a new Getopt object is created with three params.
+  * The first param is the program name.  This is for printing error
+  * messages in the form "program: error message".  In the C version, this
+  * value is taken from argv[0], but in Java the program name is not passed
+  * in that element, thus the need for this parameter.  The second param is
+  * the argument list that was passed to the main() method.  The third
+  * param is the list of valid options.  Each character represents a valid
+  * option.  If the character is followed by a single colon, then that
+  * option has a required argument.  If the character is followed by two
+  * colons, then that option has an argument that is not required.
+  * <p>
+  * Note in this example that the value returned from getopt() is cast to
+  * a char prior to printing.  This is required in order to make the value
+  * display correctly as a character instead of an integer.
+  * <p>
+  * If the first character in the option string is a colon, for example
+  * ":abc::d", then getopt() will return a ':' instead of a '?' when it
+  * encounters an option with a missing required argument.  This allows the
+  * caller to distinguish between invalid options and valid options that
+  * are simply incomplete.
+  * <p>
+  * In the traditional Unix getopt(), -1 is returned when the first non-option
+  * charcter is encountered.  In GNU getopt(), the default behavior is to
+  * allow options to appear anywhere on the command line.  The getopt()
+  * method permutes the argument to make it appear to the caller that all
+  * options were at the beginning of the command line, and all non-options
+  * were at the end.  For example, calling getopt() with command line args
+  * of "-a foo bar -d" returns options 'a' and 'd', then sets optind to 
+  * point to "foo".  The program would read the last two argv elements as
+  * "foo" and "bar", just as if the user had typed "-a -d foo bar". 
+  * <p> 
+  * The user can force getopt() to stop scanning the command line with
+  * the special argument "--" by itself.  Any elements occuring before the
+  * "--" are scanned and permuted as normal.  Any elements after the "--"
+  * are returned as is as non-option argv elements.  For example, 
+  * "foo -a -- bar -d" would return  option 'a' then -1.  optind would point 
+  * to "foo", "bar" and "-d" as the non-option argv elements.  The "--"
+  * is discarded by getopt().
+  * <p>
+  * There are two ways this default behavior can be modified.  The first is
+  * to specify traditional Unix getopt() behavior (which is also POSIX
+  * behavior) in which scanning stops when the first non-option argument
+  * encountered.  (Thus "-a foo bar -d" would return 'a' as an option and
+  * have "foo", "bar", and "-d" as non-option elements).  The second is to
+  * allow options anywhere, but to return all elements in the order they
+  * occur on the command line.  When a non-option element is ecountered,
+  * an integer 1 is returned and the value of the non-option element is
+  * stored in optarg is if it were the argument to that option.  For
+  * example, "-a foo -d", returns first 'a', then 1 (with optarg set to
+  * "foo") then 'd' then -1.  When this "return in order" functionality
+  * is enabled, the only way to stop getopt() from scanning all command
+  * line elements is to use the special "--" string by itself as described
+  * above.  An example is "-a foo -b -- bar", which would return 'a', then
+  * integer 1 with optarg set to "foo", then 'b', then -1.  optind would
+  * then point to "bar" as the first non-option argv element.  The "--"
+  * is discarded.
+  * <p>
+  * The POSIX/traditional behavior is enabled by either setting the 
+  * property "gnu.posixly_correct" or by putting a '+' sign as the first
+  * character of the option string.  The difference between the two 
+  * methods is that setting the gnu.posixly_correct property also forces
+  * certain error messages to be displayed in POSIX format.  To enable
+  * the "return in order" functionality, put a '-' as the first character
+  * of the option string.  Note that after determining the proper 
+  * behavior, Getopt strips this leading '+' or '-', meaning that a ':'
+  * placed as the second character after one of those two will still cause
+  * getopt() to return a ':' instead of a '?' if a required option
+  * argument is missing.
+  * <p>
+  * In addition to traditional single character options, GNU Getopt also
+  * supports long options.  These are preceeded by a "--" sequence and
+  * can be as long as desired.  Long options provide a more user-friendly
+  * way of entering command line options.  For example, in addition to a
+  * "-h" for help, a program could support also "--help".  
+  * <p>
+  * Like short options, long options can also take a required or non-required 
+  * argument.  Required arguments can either be specified by placing an
+  * equals sign after the option name, then the argument, or by putting the
+  * argument in the next argv element.  For example: "--outputdir=foo" and
+  * "--outputdir foo" both represent an option of "outputdir" with an
+  * argument of "foo", assuming that outputdir takes a required argument.
+  * If a long option takes a non-required argument, then the equals sign
+  * form must be used to specify the argument.  In this case,
+  * "--outputdir=foo" would represent option outputdir with an argument of
+  * "foo" while "--outputdir foo" would represent the option outputdir
+  * with no argument and a first non-option argv element of "foo".
+  * <p>
+  * Long options can also be specified using a special POSIX argument 
+  * format (one that I highly discourage).  This form of entry is 
+  * enabled by placing a "W;" (yes, 'W' then a semi-colon) in the valid
+  * option string.  This causes getopt to treat the name following the
+  * "-W" as the name of the long option.  For example, "-W outputdir=foo"
+  * would be equivalent to "--outputdir=foo".  The name can immediately
+  * follow the "-W" like so: "-Woutputdir=foo".  Option arguments are
+  * handled identically to normal long options.  If a string follows the 
+  * "-W" that does not represent a valid long option, then getopt() returns
+  * 'W' and the caller must decide what to do.  Otherwise getopt() returns
+  * a long option value as described below.
+  * <p>
+  * While long options offer convenience, they can also be tedious to type
+  * in full.  So it is permissible to abbreviate the option name to as
+  * few characters as required to uniquely identify it.  If the name can
+  * represent multiple long options, then an error message is printed and
+  * getopt() returns a '?'.  
+  * <p>
+  * If an invalid option is specified or a required option argument is 
+  * missing, getopt() prints an error and returns a '?' or ':' exactly
+  * as for short options.  Note that when an invalid long option is
+  * encountered, the optopt variable is set to integer 0 and so cannot
+  * be used to identify the incorrect option the user entered.
+  * <p>
+  * Long options are defined by LongOpt objects.  These objects are created
+  * with a contructor that takes four params: a String representing the
+  * object name, a integer specifying what arguments the option takes
+  * (the value is one of LongOpt.NO_ARGUMENT, LongOpt.REQUIRED_ARGUMENT,
+  * or LongOpt.OPTIONAL_ARGUMENT), a StringBuffer flag object (described
+  * below), and an integer value (described below).
+  * <p>
+  * To enable long option parsing, create an array of LongOpt's representing
+  * the legal options and pass it to the Getopt() constructor.  WARNING: If
+  * all elements of the array are not populated with LongOpt objects, the
+  * getopt() method will throw a NullPointerException.
+  * <p>
+  * When getopt() is called and a long option is encountered, one of two
+  * things can be returned.  If the flag field in the LongOpt object 
+  * representing the long option is non-null, then the integer value field
+  * is stored there and an integer 0 is returned to the caller.  The val
+  * field can then be retrieved from the flag field.  Note that since the
+  * flag field is a StringBuffer, the appropriate String to integer converions
+  * must be performed in order to get the actual int value stored there.
+  * If the flag field in the LongOpt object is null, then the value field
+  * of the LongOpt is returned.  This can be the character of a short option.
+  * This allows an app to have both a long and short option sequence 
+  * (say, "-h" and "--help") that do the exact same thing.
+  * <p>
+  * With long options, there is an alternative method of determining 
+  * which option was selected.  The method getLongind() will return the
+  * the index in the long option array (NOT argv) of the long option found.
+  * So if multiple long options are configured to return the same value,
+  * the application can use getLongind() to distinguish between them. 
+  * <p>
+  * Here is an expanded Getopt example using long options and various
+  * techniques described above:
+  * <p>
+  * <pre>
+  * int c;
+  * String arg;
+  * LongOpt[] longopts = new LongOpt[3];
+  * // 
+  * StringBuffer sb = new StringBuffer();
+  * longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h');
+  * longopts[1] = new LongOpt("outputdir", LongOpt.REQUIRED_ARGUMENT, sb, 'o'); 
+  * longopts[2] = new LongOpt("maximum", LongOpt.OPTIONAL_ARGUMENT, null, 2);
+  * // 
+  * Getopt g = new Getopt("testprog", argv, "-:bc::d:hW;", longopts);
+  * g.setOpterr(false); // We'll do our own error handling
+  * //
+  * while ((c = g.getopt()) != -1)
+  *   switch (c)
+  *     {
+  *        case 0:
+  *          arg = g.getOptarg();
+  *          System.out.println("Got long option with value '" +
+  *                             (char)(new Integer(sb.toString())).intValue()
+  *                             + "' with argument " +
+  *                             ((arg != null) ? arg : "null"));
+  *          break;
+  *          //
+  *        case 1:
+  *          System.out.println("I see you have return in order set and that " +
+  *                             "a non-option argv element was just found " +
+  *                             "with the value '" + g.getOptarg() + "'");
+  *          break;
+  *          //
+  *        case 2:
+  *          arg = g.getOptarg();
+  *          System.out.println("I know this, but pretend I didn't");
+  *          System.out.println("We picked option " +
+  *                             longopts[g.getLongind()].getName() +
+  *                           " with value " + 
+  *                           ((arg != null) ? arg : "null"));
+  *          break;
+  *          //
+  *        case 'b':
+  *          System.out.println("You picked plain old option " + (char)c);
+  *          break;
+  *          //
+  *        case 'c':
+  *        case 'd':
+  *          arg = g.getOptarg();
+  *          System.out.println("You picked option '" + (char)c + 
+  *                             "' with argument " +
+  *                             ((arg != null) ? arg : "null"));
+  *          break;
+  *          //
+  *        case 'h':
+  *          System.out.println("I see you asked for help");
+  *          break;
+  *          //
+  *        case 'W':
+  *          System.out.println("Hmmm. You tried a -W with an incorrect long " +
+  *                             "option name");
+  *          break;
+  *          //
+  *        case ':':
+  *          System.out.println("Doh! You need an argument for option " +
+  *                             (char)g.getOptopt());
+  *          break;
+  *          //
+  *        case '?':
+  *          System.out.println("The option '" + (char)g.getOptopt() + 
+  *                           "' is not valid");
+  *          break;
+  *          //
+  *        default:
+  *          System.out.println("getopt() returned " + c);
+  *          break;
+  *     }
+  * //
+  * for (int i = g.getOptind(); i < argv.length ; i++)
+  *   System.out.println("Non option argv element: " + argv[i] + "\n");
+  * </pre>
+  * <p>
+  * There is an alternative form of the constructor used for long options
+  * above.  This takes a trailing boolean flag.  If set to false, Getopt
+  * performs identically to the example, but if the boolean flag is true
+  * then long options are allowed to start with a single '-' instead of
+  * "--".  If the first character of the option is a valid short option
+  * character, then the option is treated as if it were the short option.
+  * Otherwise it behaves as if the option is a long option.  Note that
+  * the name given to this option - long_only - is very counter-intuitive.
+  * It does not cause only long options to be parsed but instead enables
+  * the behavior described above.
+  * <p> 
+  * Note that the functionality and variable names used are driven from 
+  * the C lib version as this object is a port of the C code, not a 
+  * new implementation.  This should aid in porting existing C/C++ code,
+  * as well as helping programmers familiar with the glibc version to
+  * adapt to the Java version even if it seems very non-Java at times.
+  * <p>
+  * In this release I made all instance variables protected due to
+  * overwhelming public demand.  Any code which relied on optarg,
+  * opterr, optind, or optopt being public will need to be modified to
+  * use the appropriate access methods.
+  * <p>
+  * Please send all bug reports, requests, and comments to
+  * <a href="mailto:arenn@urbanophile.com">arenn@urbanophile.com</a>.
+  *
+  * @version 1.0.7
+  *
+  * @author Roland McGrath (roland@gnu.ai.mit.edu)
+  * @author Ulrich Drepper (drepper@cygnus.com)
+  * @author Aaron M. Renn (arenn@urbanophile.com)
+  *
+  * @see LongOpt
+  */
+public class Getopt extends Object
+{
+
+/**************************************************************************/
+
+/*
+ * Class Variables
+ */
+
+/** 
+  * Describe how to deal with options that follow non-option ARGV-elements.
+  *
+  * If the caller did not specify anything,
+  * the default is REQUIRE_ORDER if the property 
+  * gnu.posixly_correct is defined, PERMUTE otherwise.
+  *
+  * The special argument `--' forces an end of option-scanning regardless
+  * of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+  * `--' can cause `getopt' to return -1 with `optind' != ARGC.
+  *
+  * REQUIRE_ORDER means don't recognize them as options;
+  * stop option processing when the first non-option is seen.
+  * This is what Unix does.
+  * This mode of operation is selected by either setting the property
+  * gnu.posixly_correct, or using `+' as the first character
+  * of the list of option characters.
+  */
+protected static final int REQUIRE_ORDER = 1;
+
+/**
+  * PERMUTE is the default.  We permute the contents of ARGV as we scan,
+  * so that eventually all the non-options are at the end.  This allows options
+  * to be given in any order, even with programs that were not written to
+  * expect this.
+  */
+protected static final int PERMUTE = 2;
+
+/**
+  * RETURN_IN_ORDER is an option available to programs that were written
+  * to expect options and other ARGV-elements in any order and that care about
+  * the ordering of the two.  We describe each non-option ARGV-element
+  * as if it were the argument of an option with character code 1.
+  * Using `-' as the first character of the list of option characters
+  * selects this mode of operation.
+  */
+protected static final int RETURN_IN_ORDER = 3;
+
+/**************************************************************************/
+
+/*
+ * Instance Variables
+ */
+ 
+/**
+  * For communication from `getopt' to the caller.
+  * When `getopt' finds an option that takes an argument,
+  * the argument value is returned here.
+  * Also, when `ordering' is RETURN_IN_ORDER,
+  * each non-option ARGV-element is returned here.
+  */
+protected String optarg;
+
+/**
+  *  Index in ARGV of the next element to be scanned.
+  *  This is used for communication to and from the caller
+  *  and for communication between successive calls to `getopt'.
+  *
+  *  On entry to `getopt', zero means this is the first call; initialize.
+  *
+  *  When `getopt' returns -1, this is the index of the first of the
+  *  non-option elements that the caller should itself scan.
+  *
+  *  Otherwise, `optind' communicates from one call to the next
+  *  how much of ARGV has been scanned so far.  
+  */
+protected int optind = 0;
+
+/** 
+  * Callers store false here to inhibit the error message
+  * for unrecognized options.  
+  */
+protected boolean opterr = true;
+
+/** 
+  * When an unrecognized option is encountered, getopt will return a '?'
+  * and store the value of the invalid option here.
+  */
+protected int optopt = '?';
+
+/** 
+  * The next char to be scanned in the option-element
+  * in which the last option character we returned was found.
+  * This allows us to pick up the scan where we left off.
+  *
+  * If this is zero, or a null string, it means resume the scan
+  * by advancing to the next ARGV-element.  
+  */
+protected String nextchar;
+
+/**
+  * This is the string describing the valid short options.
+  */
+protected String optstring;
+
+/**
+  * This is an array of LongOpt objects which describ the valid long 
+  * options.
+  */
+protected LongOpt[] long_options;
+
+/**
+  * This flag determines whether or not we are parsing only long args
+  */
+protected boolean long_only;
+
+/**
+  * Stores the index into the long_options array of the long option found
+  */
+protected int longind;
+
+/**
+  * The flag determines whether or not we operate in strict POSIX compliance
+  */
+protected boolean posixly_correct;
+
+/**
+  * A flag which communicates whether or not checkLongOption() did all
+  * necessary processing for the current option
+  */
+protected boolean longopt_handled;
+
+/**
+  * The index of the first non-option in argv[]
+  */
+protected int first_nonopt = 1;
+
+/**
+  * The index of the last non-option in argv[]
+  */
+protected int last_nonopt = 1;
+
+/**
+  * Flag to tell getopt to immediately return -1 the next time it is
+  * called.
+  */
+private boolean endparse = false;
+
+/**
+  * Saved argument list passed to the program
+  */
+protected String[] argv;
+
+/**
+  * Determines whether we permute arguments or not
+  */
+protected int ordering;
+
+/**
+  * Name to print as the program name in error messages.  This is necessary
+  * since Java does not place the program name in argv[0]
+  */
+protected String progname;
+
+/**
+  * The localized strings are kept in a separate file
+  */
+private ResourceBundle _messages = PropertyResourceBundle.getBundle(
+                           "gnu/getopt/MessagesBundle", Locale.getDefault());
+
+/**************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+  * Construct a basic Getopt instance with the given input data.  Note that
+  * this handles "short" options only.
+  *
+  * @param progname The name to display as the program name when printing errors
+  * @param argv The String array passed as the command line to the program.
+  * @param optstring A String containing a description of the valid args for this program
+  */
+public
+Getopt(String progname, String[] argv, String optstring)
+{
+  this(progname, argv, optstring, null, false);
+}
+
+/**************************************************************************/
+
+/**
+  * Construct a Getopt instance with given input data that is capable of
+  * parsing long options as well as short.
+  *
+  * @param progname The name to display as the program name when printing errors
+  * @param argv The String array passed as the command ilne to the program
+  * @param optstring A String containing a description of the valid short args for this program
+  * @param long_options An array of LongOpt objects that describes the valid long args for this program
+  */
+public
+Getopt(String progname, String[] argv, String optstring, 
+       LongOpt[] long_options)
+{
+  this(progname, argv, optstring, long_options, false);
+}
+
+/**************************************************************************/
+
+/**
+  * Construct a Getopt instance with given input data that is capable of
+  * parsing long options and short options.  Contrary to what you might
+  * think, the flag 'long_only' does not determine whether or not we 
+  * scan for only long arguments.  Instead, a value of true here allows
+  * long arguments to start with a '-' instead of '--' unless there is a
+  * conflict with a short option name.
+  *
+  * @param progname The name to display as the program name when printing errors
+  * @param argv The String array passed as the command ilne to the program
+  * @param optstring A String containing a description of the valid short args for this program
+  * @param long_options An array of LongOpt objects that describes the valid long args for this program
+  * @param long_only true if long options that do not conflict with short options can start with a '-' as well as '--'
+  */
+public
+Getopt(String progname, String[] argv, String optstring, 
+       LongOpt[] long_options, boolean long_only)
+{
+  if (optstring.length() == 0)
+    optstring = " ";
+
+  // This function is essentially _getopt_initialize from GNU getopt
+  this.progname = progname;
+  this.argv = argv;
+  this.optstring = optstring;
+  this.long_options = long_options;
+  this.long_only = long_only;
+
+  // Check for property "gnu.posixly_correct" to determine whether to
+  // strictly follow the POSIX standard.  This replaces the "POSIXLY_CORRECT"
+  // environment variable in the C version
+  if (System.getProperty("gnu.posixly_correct", null) == null)
+    posixly_correct = false;
+  else
+    {
+      posixly_correct = true;
+      _messages = PropertyResourceBundle.getBundle("gnu/getopt/MessagesBundle",
+                                                   Locale.US);
+    }
+
+  // Determine how to handle the ordering of options and non-options
+  if (optstring.charAt(0) == '-')
+    {
+      ordering = RETURN_IN_ORDER;
+      if (optstring.length() > 1)
+        this.optstring = optstring.substring(1);
+    }
+  else if (optstring.charAt(0) == '+')
+    {
+      ordering = REQUIRE_ORDER;
+      if (optstring.length() > 1)
+        this.optstring = optstring.substring(1);
+    }
+  else if (posixly_correct)
+    {
+      ordering = REQUIRE_ORDER;
+    }
+  else
+    {
+      ordering = PERMUTE; // The normal default case
+    }
+}
+
+/**************************************************************************/
+ 
+/*
+ * Instance Methods
+ */
+
+/**
+  * In GNU getopt, it is possible to change the string containg valid options
+  * on the fly because it is passed as an argument to getopt() each time.  In
+  * this version we do not pass the string on every call.  In order to allow
+  * dynamic option string changing, this method is provided.
+  *
+  * @param optstring The new option string to use
+  */
+public void
+setOptstring(String optstring)
+{
+  if (optstring.length() == 0)
+    optstring = " ";
+
+  this.optstring = optstring;
+}
+
+/**************************************************************************/
+
+/**
+  * optind it the index in ARGV of the next element to be scanned.
+  * This is used for communication to and from the caller
+  * and for communication between successive calls to `getopt'.
+  *
+  * When `getopt' returns -1, this is the index of the first of the
+  * non-option elements that the caller should itself scan.
+  *
+  * Otherwise, `optind' communicates from one call to the next
+  * how much of ARGV has been scanned so far.  
+  */
+public int
+getOptind()
+{
+  return(optind);
+}
+
+/**************************************************************************/
+
+/**
+  * This method allows the optind index to be set manually.  Normally this
+  * is not necessary (and incorrect usage of this method can lead to serious
+  * lossage), but optind is a public symbol in GNU getopt, so this method 
+  * was added to allow it to be modified by the caller if desired.
+  *
+  * @param optind The new value of optind
+  */
+public void
+setOptind(int optind)
+{
+  this.optind = optind;
+}
+
+/**************************************************************************/
+
+/**
+  * Since in GNU getopt() the argument vector is passed back in to the
+  * function every time, the caller can swap out argv on the fly.  Since
+  * passing argv is not required in the Java version, this method allows
+  * the user to override argv.  Note that incorrect use of this method can
+  * lead to serious lossage.
+  *
+  * @param argv New argument list
+  */
+public void
+setArgv(String[] argv)
+{
+  this.argv = argv;
+}
+
+/**************************************************************************/
+
+/** 
+  * For communication from `getopt' to the caller.
+  * When `getopt' finds an option that takes an argument,
+  * the argument value is returned here.
+  * Also, when `ordering' is RETURN_IN_ORDER,
+  * each non-option ARGV-element is returned here.
+  * No set method is provided because setting this variable has no effect.
+  */
+public String
+getOptarg()
+{
+  return(optarg);
+}
+
+/**************************************************************************/
+
+/**
+  * Normally Getopt will print a message to the standard error when an
+  * invalid option is encountered.  This can be suppressed (or re-enabled)
+  * by calling this method.  There is no get method for this variable 
+  * because if you can't remember the state you set this to, why should I?
+  */
+public void
+setOpterr(boolean opterr)
+{
+  this.opterr = opterr;
+}
+
+/**************************************************************************/
+
+/**
+  * When getopt() encounters an invalid option, it stores the value of that
+  * option in optopt which can be retrieved with this method.  There is
+  * no corresponding set method because setting this variable has no effect.
+  */
+public int
+getOptopt()
+{
+  return(optopt);
+}
+
+/**************************************************************************/
+
+/**
+  * Returns the index into the array of long options (NOT argv) representing
+  * the long option that was found.
+  */
+public int
+getLongind()
+{
+  return(longind);
+}
+
+/**************************************************************************/
+
+/**
+  * Exchange the shorter segment with the far end of the longer segment.
+  * That puts the shorter segment into the right place.
+  * It leaves the longer segment in the right place overall,
+  * but it consists of two parts that need to be swapped next.
+  * This method is used by getopt() for argument permutation.
+  */
+protected void
+exchange(String[] argv)
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  String tem;
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+        {
+          // Bottom segment is the short one. 
+          int len = middle - bottom;
+          int i;
+
+          // Swap it with the top part of the top segment. 
+          for (i = 0; i < len; i++)
+            {
+              tem = argv[bottom + i];
+              argv[bottom + i] = argv[top - (middle - bottom) + i];
+              argv[top - (middle - bottom) + i] = tem;
+            }
+          // Exclude the moved bottom segment from further swapping. 
+          top -= len;
+        }
+      else
+        {
+          // Top segment is the short one.
+          int len = top - middle;
+          int i;
+
+          // Swap it with the bottom part of the bottom segment. 
+          for (i = 0; i < len; i++)
+            {
+              tem = argv[bottom + i];
+              argv[bottom + i] = argv[middle + i];
+              argv[middle + i] = tem;
+            }
+          // Exclude the moved top segment from further swapping. 
+          bottom += len;
+        }
+    }
+
+  // Update records for the slots the non-options now occupy. 
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/**************************************************************************/
+
+/**
+  * Check to see if an option is a valid long option.  Called by getopt().
+  * Put in a separate method because this needs to be done twice.  (The
+  * C getopt authors just copy-pasted the code!).
+  *
+  * @param longind A buffer in which to store the 'val' field of found LongOpt
+  *
+  * @return Various things depending on circumstances
+  */
+protected int
+checkLongOption()
+{
+  LongOpt pfound = null;
+  int nameend;
+  boolean ambig;
+  boolean exact;
+  
+  longopt_handled = true;
+  ambig = false;
+  exact = false;
+  longind = -1;
+
+  nameend = nextchar.indexOf("=");
+  if (nameend == -1)
+    nameend = nextchar.length();
+  
+  // Test all lnog options for either exact match or abbreviated matches
+  for (int i = 0; i < long_options.length; i++)
+    {
+      if (long_options[i].getName().startsWith(nextchar.substring(0, nameend)))
+        {
+          if (long_options[i].getName().equals(nextchar.substring(0, nameend)))
+            {
+              // Exact match found
+              pfound = long_options[i];
+              longind = i;
+              exact = true;
+              break;
+            }
+          else if (pfound == null)
+            {
+              // First nonexact match found
+              pfound = long_options[i];
+              longind = i;
+            }
+          else
+            {
+              // Second or later nonexact match found
+              ambig = true;
+            }
+        }
+    } // for
+  
+  // Print out an error if the option specified was ambiguous
+  if (ambig && !exact)
+    {
+      if (opterr)
+        {
+          Object[] msgArgs = { progname, argv[optind] };
+          System.err.println(MessageFormat.format(
+                             _messages.getString("getopt.ambigious"), 
+                             msgArgs));
+        }
+
+       nextchar = "";
+       optopt = 0;
+       ++optind;
+ 
+       return('?');
+    }
+ 
+  if (pfound != null)
+    {
+      ++optind;
+ 
+      if (nameend != nextchar.length())
+        {
+          if (pfound.has_arg != LongOpt.NO_ARGUMENT)
+            {
+              if (nextchar.substring(nameend).length() > 1)
+                optarg = nextchar.substring(nameend+1);
+              else
+                optarg = "";
+            }
+          else
+            {
+              if (opterr)
+                {
+                  // -- option
+                  if (argv[optind - 1].startsWith("--"))
+                    {
+                      Object[] msgArgs = { progname, pfound.name };
+                      System.err.println(MessageFormat.format(
+                                  _messages.getString("getopt.arguments1"), 
+                                  msgArgs));
+                    }
+                  // +option or -option
+                  else
+                    {
+                      Object[] msgArgs = { progname, new 
+                               Character(argv[optind-1].charAt(0)).toString(),
+                               pfound.name };
+                      System.err.println(MessageFormat.format(
+                               _messages.getString("getopt.arguments2"), 
+                               msgArgs));
+                    }
+                 }
+   
+              nextchar = "";
+              optopt = pfound.val;
+   
+              return('?');
+            }
+        } // if (nameend)
+      else if (pfound.has_arg == LongOpt.REQUIRED_ARGUMENT)
+        {
+          if (optind < argv.length)
+            {
+               optarg = argv[optind];
+               ++optind;
+            }
+          else
+            {
+              if (opterr)
+                {
+                  Object[] msgArgs = { progname, argv[optind-1] };
+                  System.err.println(MessageFormat.format(
+                                     _messages.getString("getopt.requires"), 
+                                     msgArgs));
+                }
+   
+              nextchar = "";
+              optopt = pfound.val;
+              if (optstring.charAt(0) == ':')
+                return(':');
+              else
+                return('?');
+            }
+        } // else if (pfound)
+   
+      nextchar = "";
+
+      if (pfound.flag != null)
+        {
+          pfound.flag.setLength(0);
+          pfound.flag.append(pfound.val);
+   
+          return(0);
+        }
+
+      return(pfound.val);
+   } // if (pfound != null)
+  
+  longopt_handled = false;
+
+  return(0);
+}
+
+/**************************************************************************/
+
+/**
+  * This method returns a char that is the current option that has been
+  * parsed from the command line.  If the option takes an argument, then
+  * the internal variable 'optarg' is set which is a String representing
+  * the the value of the argument.  This value can be retrieved by the
+  * caller using the getOptarg() method.  If an invalid option is found,
+  * an error message is printed and a '?' is returned.  The name of the
+  * invalid option character can be retrieved by calling the getOptopt()
+  * method.  When there are no more options to be scanned, this method
+  * returns -1.  The index of first non-option element in argv can be
+  * retrieved with the getOptind() method.
+  *
+  * @return Various things as described above
+  */
+public int
+getopt()
+{
+  optarg = null;
+
+  if (endparse == true)
+    return(-1);
+
+  if ((nextchar == null) || (nextchar.equals("")))
+    {
+      // If we have just processed some options following some non-options,
+      //  exchange them so that the options come first.
+      if (last_nonopt > optind)
+        last_nonopt = optind;
+      if (first_nonopt > optind)
+        first_nonopt = optind;
+
+      if (ordering == PERMUTE)
+        {
+          // If we have just processed some options following some non-options,
+          // exchange them so that the options come first.
+          if ((first_nonopt != last_nonopt) && (last_nonopt != optind))
+            exchange(argv);
+          else if (last_nonopt != optind)
+            first_nonopt = optind;
+
+          // Skip any additional non-options
+          // and extend the range of non-options previously skipped.
+          while ((optind < argv.length) && (argv[optind].equals("") ||
+            (argv[optind].charAt(0) != '-') || argv[optind].equals("-")))
+            {
+              optind++;
+            }
+          
+          last_nonopt = optind;
+        }
+
+      // The special ARGV-element `--' means premature end of options.
+      // Skip it like a null option,
+      // then exchange with previous non-options as if it were an option,
+      // then skip everything else like a non-option.
+      if ((optind != argv.length) && argv[optind].equals("--"))
+        {
+          optind++;
+
+          if ((first_nonopt != last_nonopt) && (last_nonopt != optind))
+            exchange (argv);
+          else if (first_nonopt == last_nonopt)
+            first_nonopt = optind;
+
+          last_nonopt = argv.length;
+
+          optind = argv.length;
+        }
+
+      // If we have done all the ARGV-elements, stop the scan
+      // and back over any non-options that we skipped and permuted.
+      if (optind == argv.length)
+        {
+          // Set the next-arg-index to point at the non-options
+          // that we previously skipped, so the caller will digest them.
+          if (first_nonopt != last_nonopt)
+            optind = first_nonopt;
+
+          return(-1);
+        }
+
+      // If we have come to a non-option and did not permute it,
+      // either stop the scan or describe it to the caller and pass it by.
+      if (argv[optind].equals("") || (argv[optind].charAt(0) != '-') || 
+          argv[optind].equals("-"))
+        {
+          if (ordering == REQUIRE_ORDER)
+            return(-1);
+
+            optarg = argv[optind++];
+            return(1);
+        }
+      
+      // We have found another option-ARGV-element.
+      // Skip the initial punctuation.
+      if (argv[optind].startsWith("--"))
+        nextchar = argv[optind].substring(2);
+      else
+        nextchar = argv[optind].substring(1);
+   }
+
+  // Decode the current option-ARGV-element.
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+  if ((long_options != null) && (argv[optind].startsWith("--")
+      || (long_only && ((argv[optind].length()  > 2) || 
+      (optstring.indexOf(argv[optind].charAt(1)) == -1)))))
+    {
+       int c = checkLongOption();
+
+       if (longopt_handled)
+         return(c);
+         
+      // Can't find it as a long option.  If this is not getopt_long_only,
+      // or the option starts with '--' or is not a valid short
+      // option, then it's an error.
+      // Otherwise interpret it as a short option.
+      if (!long_only || argv[optind].startsWith("--")
+        || (optstring.indexOf(nextchar.charAt(0)) == -1))
+        {
+          if (opterr)
+            {
+              if (argv[optind].startsWith("--"))
+                {
+                  Object[] msgArgs = { progname, nextchar };
+                  System.err.println(MessageFormat.format(
+                                   _messages.getString("getopt.unrecognized"), 
+                                   msgArgs));
+                }
+              else
+                {
+                  Object[] msgArgs = { progname, new 
+                                 Character(argv[optind].charAt(0)).toString(), 
+                                 nextchar };
+                  System.err.println(MessageFormat.format(
+                                 _messages.getString("getopt.unrecognized2"), 
+                                 msgArgs));
+                }
+            }
+
+          nextchar = "";
+          ++optind;
+          optopt = 0;
+    
+          return('?');
+        }
+    } // if (longopts)
+
+  // Look at and handle the next short option-character */
+  int c = nextchar.charAt(0); //**** Do we need to check for empty str?
+  if (nextchar.length() > 1)
+    nextchar = nextchar.substring(1);
+  else
+    nextchar = "";
+  
+  String temp = null;
+  if (optstring.indexOf(c) != -1)
+    temp = optstring.substring(optstring.indexOf(c));
+
+  if (nextchar.equals(""))
+    ++optind;
+
+  if ((temp == null) || (c == ':'))
+    {
+      if (opterr)
+        {
+          if (posixly_correct)
+            {
+              // 1003.2 specifies the format of this message
+              Object[] msgArgs = { progname, new 
+                                   Character((char)c).toString() };
+              System.err.println(MessageFormat.format(
+                            _messages.getString("getopt.illegal"), msgArgs));
+            }
+          else
+            {
+              Object[] msgArgs = { progname, new 
+                                   Character((char)c).toString() };
+              System.err.println(MessageFormat.format(
+                            _messages.getString("getopt.invalid"), msgArgs));
+            }
+        }
+
+      optopt = c;
+
+      return('?');
+    }
+
+  // Convenience. Treat POSIX -W foo same as long option --foo
+  if ((temp.charAt(0) == 'W') && (temp.length() > 1) && (temp.charAt(1) == ';'))
+    {
+      if (!nextchar.equals(""))
+        {
+          optarg = nextchar;
+        }
+      // No further cars in this argv element and no more argv elements
+      else if (optind == argv.length)
+        {
+          if (opterr)
+            {
+              // 1003.2 specifies the format of this message. 
+              Object[] msgArgs = { progname, new 
+                                   Character((char)c).toString() };
+              System.err.println(MessageFormat.format(
+                            _messages.getString("getopt.requires2"), msgArgs));
+            }
+
+          optopt = c;
+          if (optstring.charAt(0) == ':')
+            return(':');
+          else
+            return('?');
+        }
+      else
+        {
+          // We already incremented `optind' once;
+          // increment it again when taking next ARGV-elt as argument. 
+          nextchar = argv[optind];
+          optarg  = argv[optind];
+        }
+
+      c = checkLongOption();
+
+      if (longopt_handled)
+        return(c);
+      else
+        // Let the application handle it
+        {
+          nextchar = null;
+          ++optind;
+          return('W');
+        }
+    }
+
+  if ((temp.length() > 1) && (temp.charAt(1) == ':'))
+    {
+      if ((temp.length() > 2) && (temp.charAt(2) == ':'))
+        // This is an option that accepts and argument optionally
+        {
+          if (!nextchar.equals(""))
+            {
+               optarg = nextchar;
+               ++optind;
+            }
+          else
+            {
+              optarg = null;
+            }
+
+          nextchar = null;
+        }
+      else
+        {
+          if (!nextchar.equals(""))
+            {
+              optarg = nextchar;
+              ++optind;
+            }
+          else if (optind == argv.length)
+            {
+              if (opterr)
+                {
+                  // 1003.2 specifies the format of this message
+                  Object[] msgArgs = { progname, new 
+                                       Character((char)c).toString() };
+                  System.err.println(MessageFormat.format(
+                            _messages.getString("getopt.requires2"), msgArgs));
+                }
+
+              optopt = c;
+ 
+              if (optstring.charAt(0) == ':')
+                return(':');
+              else
+                return('?');
+            }
+          else
+            {
+              optarg = argv[optind];
+              ++optind;
+
+              // Ok, here's an obscure Posix case.  If we have o:, and
+              // we get -o -- foo, then we're supposed to skip the --,
+              // end parsing of options, and make foo an operand to -o.
+              // Only do this in Posix mode.
+              if ((posixly_correct) && optarg.equals("--"))
+                {
+                  // If end of argv, error out
+                  if (optind == argv.length)
+                    {
+                      if (opterr)
+                        {
+                          // 1003.2 specifies the format of this message
+                          Object[] msgArgs = { progname, new 
+                                               Character((char)c).toString() };
+                          System.err.println(MessageFormat.format(
+                             _messages.getString("getopt.requires2"), msgArgs));
+                        }
+
+                      optopt = c;
+ 
+                      if (optstring.charAt(0) == ':')
+                        return(':');
+                      else
+                        return('?');
+                    }
+
+                  // Set new optarg and set to end
+                  // Don't permute as we do on -- up above since we
+                  // know we aren't in permute mode because of Posix.
+                  optarg = argv[optind];
+                  ++optind;
+                  first_nonopt = optind;
+                  last_nonopt = argv.length;
+                  endparse = true;
+                }
+            }
+
+          nextchar = null;
+        }
+    }
+
+  return(c);
+}
+
+} // Class Getopt
+
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/GetoptDemo.java
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/GetoptDemo.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/GetoptDemo.java	(revision 21017)
@@ -0,0 +1,97 @@
+import gnu.getopt.LongOpt;
+import gnu.getopt.Getopt;
+
+/*
+ * This sample code was written by Aaron M. Renn and is a demonstration
+ * of how to utilize some of the features of the GNU getopt package.  This
+ * sample code is hereby placed into the public domain by the author and
+ * may be used without restriction.
+ */
+
+public class GetoptDemo
+{
+
+public static void
+main(String[] argv)
+{
+ int c;
+ String arg;
+ LongOpt[] longopts = new LongOpt[3];
+ // 
+ StringBuffer sb = new StringBuffer();
+ longopts[0] = new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h');
+ longopts[1] = new LongOpt("outputdir", LongOpt.REQUIRED_ARGUMENT, sb, 'o'); 
+ longopts[2] = new LongOpt("maximum", LongOpt.OPTIONAL_ARGUMENT, null, 2);
+ // 
+ Getopt g = new Getopt("testprog", argv, "-:bc::d:hW;", longopts);
+ g.setOpterr(false); // We'll do our own error handling
+ //
+ while ((c = g.getopt()) != -1)
+   switch (c)
+     {
+        case 0:
+          arg = g.getOptarg();
+          System.out.println("Got long option with value '" +
+                             (char)(new Integer(sb.toString())).intValue()
+                             + "' with argument " +
+                             ((arg != null) ? arg : "null"));
+          break;
+          //
+        case 1:
+          System.out.println("I see you have return in order set and that " +
+                             "a non-option argv element was just found " +
+                             "with the value '" + g.getOptarg() + "'");
+          break;
+          //
+        case 2:
+          arg = g.getOptarg();
+          System.out.println("I know this, but pretend I didn't");
+          System.out.println("We picked option " +
+                             longopts[g.getLongind()].getName() +
+                           " with value " + 
+                           ((arg != null) ? arg : "null"));
+          break;
+          //
+        case 'b':
+          System.out.println("You picked plain old option " + (char)c);
+          break;
+          //
+        case 'c':
+        case 'd':
+          arg = g.getOptarg();
+          System.out.println("You picked option '" + (char)c + 
+                             "' with argument " +
+                             ((arg != null) ? arg : "null"));
+          break;
+          //
+        case 'h':
+          System.out.println("I see you asked for help");
+          break;
+          //
+        case 'W':
+          System.out.println("Hmmm. You tried a -W with an incorrect long " +
+                             "option name");
+          break;
+          //
+        case ':':
+          System.out.println("Doh! You need an argument for option " +
+                             (char)g.getOptopt());
+          break;
+          //
+        case '?':
+          System.out.println("The option '" + (char)g.getOptopt() + 
+                           "' is not valid");
+          break;
+          //
+        default:
+          System.out.println("getopt() returned " + c);
+          break;
+     }
+ //
+ for (int i = g.getOptind(); i < argv.length ; i++)
+   System.out.println("Non option argv element: " + argv[i] + "\n");
+}
+
+} // Class GetoptDemo
+
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/LongOpt.java
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/LongOpt.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/LongOpt.java	(revision 21017)
@@ -0,0 +1,196 @@
+/**************************************************************************
+/* LongOpt.java -- Long option object for Getopt
+/*
+/* Copyright (c) 1998 by Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published 
+/* by  the Free Software Foundation; either version 2 of the License or
+/* (at your option) any later version.
+/*
+/* This program is distributed in the hope that it will be useful, but
+/* WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/* GNU Library General Public License for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; see the file COPYING.LIB.  If not, write to 
+/* the Free Software Foundation Inc., 59 Temple Place - Suite 330, 
+/* Boston, MA  02111-1307 USA
+/**************************************************************************/
+
+package gnu.getopt;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.PropertyResourceBundle;
+import java.text.MessageFormat;
+
+/**************************************************************************/
+
+/**
+  * This object represents the definition of a long option in the Java port
+  * of GNU getopt.  An array of LongOpt objects is passed to the Getopt
+  * object to define the list of valid long options for a given parsing
+  * session.  Refer to the getopt documentation for details on the
+  * format of long options.
+  * 
+  * @version 1.0.5
+  * @author Aaron M. Renn (arenn@urbanophile.com)
+  *
+  * @see Getopt
+  */
+public class LongOpt extends Object
+{
+
+/**************************************************************************/
+
+/*
+ * Class Variables
+ */
+
+/**
+  * Constant value used for the "has_arg" constructor argument.  This
+  * value indicates that the option takes no argument.
+  */
+public static final int NO_ARGUMENT = 0;
+
+/** 
+  * Constant value used for the "has_arg" constructor argument.  This
+  * value indicates that the option takes an argument that is required.
+  */
+public static final int REQUIRED_ARGUMENT = 1;
+
+/**
+  * Constant value used for the "has_arg" constructor argument.  This
+  * value indicates that the option takes an argument that is optional.
+  */
+public static final int OPTIONAL_ARGUMENT = 2;
+
+/**************************************************************************/
+
+/*
+ * Instance Variables
+ */
+
+/**
+  * The name of the long option
+  */
+protected String name;
+
+/**
+  * Indicates whether the option has no argument, a required argument, or
+  * an optional argument.
+  */
+protected int has_arg;
+
+/**
+  * If this variable is not null, then the value stored in "val" is stored
+  * here when this long option is encountered.  If this is null, the value
+  * stored in "val" is treated as the name of an equivalent short option.
+  */
+protected StringBuffer flag;
+
+/**
+  * The value to store in "flag" if flag is not null, otherwise the
+  * equivalent short option character for this long option.
+  */
+protected int val;
+
+/**
+  * Localized strings for error messages
+  */
+private ResourceBundle _messages = PropertyResourceBundle.getBundle(
+                            "gnu/getopt/MessagesBundle", Locale.getDefault());
+
+/**************************************************************************/
+
+/*
+ * Constructors
+ */
+
+/**
+  * Create a new LongOpt object with the given parameter values.  If the
+  * value passed as has_arg is not valid, then an exception is thrown.
+  *
+  * @param name The long option String.
+  * @param has_arg Indicates whether the option has no argument (NO_ARGUMENT), a required argument (REQUIRED_ARGUMENT) or an optional argument (OPTIONAL_ARGUMENT).
+  * @param flag If non-null, this is a location to store the value of "val" when this option is encountered, otherwise "val" is treated as the equivalent short option character.
+  * @param val The value to return for this long option, or the equivalent single letter option to emulate if flag is null.
+  * 
+  * @exception IllegalArgumentException If the has_arg param is not one of NO_ARGUMENT, REQUIRED_ARGUMENT or OPTIONAL_ARGUMENT.
+  */
+public
+LongOpt(String name, int has_arg, 
+        StringBuffer flag, int val) throws IllegalArgumentException
+{
+  // Validate has_arg
+  if ((has_arg != NO_ARGUMENT) && (has_arg != REQUIRED_ARGUMENT) 
+     && (has_arg != OPTIONAL_ARGUMENT))
+    {
+      Object[] msgArgs = { new Integer(has_arg).toString() };
+      throw new IllegalArgumentException(MessageFormat.format(
+                    _messages.getString("getopt.invalidValue"), msgArgs));
+    }
+
+  // Store off values
+  this.name = name;
+  this.has_arg = has_arg;
+  this.flag = flag;
+  this.val = val;
+}
+
+/**************************************************************************/
+
+/**
+  * Returns the name of this LongOpt as a String
+  *
+  * @return Then name of the long option
+  */
+public String
+getName()
+{
+  return(name);
+}
+
+/**************************************************************************/
+
+/**
+  * Returns the value set for the 'has_arg' field for this long option
+  *
+  * @return The value of 'has_arg'
+  */
+public int
+getHasArg()
+{
+  return(has_arg);
+}
+
+/**************************************************************************/
+
+/**
+  * Returns the value of the 'flag' field for this long option
+  *
+  * @return The value of 'flag'
+  */
+public StringBuffer
+getFlag()
+{
+  return(flag);
+}
+
+/**
+  * Returns the value of the 'val' field for this long option
+  *
+  * @return The value of 'val'
+  */
+public int
+getVal()
+{
+  return(val);
+}
+
+/**************************************************************************/
+
+} // Class LongOpt
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/Makefile
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/Makefile	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/Makefile	(revision 21017)
@@ -0,0 +1,23 @@
+# Makefile for Java port of GNU getopt
+
+
+CLASSFILES = Getopt.class  GetoptDemo.class  LongOpt.class
+
+all: $(CLASSFILES)
+
+docs: 
+	mkdir docs
+	javadoc -d docs -author -version -public Getopt.java LongOpt.java
+
+clean:
+	rm -rf *.class docs
+
+
+
+# Compile java classes
+JAVAC=javac
+JAVACOPTIONS= -deprecation -g:lines
+
+%.class: %.java
+	$(JAVAC) $(JAVACOPTIONS)  $<
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle.properties
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle.properties	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle.properties	(revision 21017)
@@ -0,0 +1,33 @@
+/**************************************************************************
+/* MessagesBundle.properties -- English language error messages
+/*
+/* Copyright (c) 1998 by William King (wrking@eng.sun.com) and
+/*                       Aaron M. Renn (arenn@urbanophile.com)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by  the Free Software Foundation; either version 2 of the License or
+/* (at your option) any later version.
+/*
+/* This program is distributed in the hope that it will be useful, but
+/* WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/* GNU Library General Public License for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; see the file COPYING.LIB.  If not, write to
+/* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+/* Boston, MA  02111-1307 USA
+/**************************************************************************/
+
+getopt.ambigious={0}: option ''{1}'' is ambiguous
+getopt.arguments1={0}: option ''--{1}'' doesn't allow an argument
+getopt.arguments2={0}: option ''{1}{2}'' doesn't allow an argument
+getopt.requires={0}: option ''{1}'' requires an argument
+getopt.unrecognized={0}: unrecognized option ''--{1}''
+getopt.unrecognized2={0}: unrecognized option ''{1}{2}''
+getopt.illegal={0}: illegal option -- {1}
+getopt.invalid={0}: invalid option -- {1}
+getopt.requires2={0}: option requires an argument -- {1}
+getopt.invalidValue=Invalid value {0} for parameter 'has_arg' 
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_cs.properties
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_cs.properties	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_cs.properties	(revision 21017)
@@ -0,0 +1,33 @@
+/**************************************************************************
+/* MessagesBundle_cs.properties -- Czech language error messages
+/*
+/* Czech Messages Copyright (c) 1998 by Roman Szturc (Roman.Szturc@vsb.cz)
+/* These messages are encoded in ISO-8859-2
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by  the Free Software Foundation; either version 2 of the License or
+/* (at your option) any later version.
+/*
+/* This program is distributed in the hope that it will be useful, but
+/* WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/* GNU Library General Public License for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; see the file COPYING.LIB.  If not, write to
+/* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+/* Boston, MA  02111-1307 USA
+/**************************************************************************/
+
+getopt.ambigious={0}: volba ''{1}'' je nejednoznaèná
+getopt.arguments1={0}: volba ''--{1}'' nepøipou¹tí argument
+getopt.arguments2={0}: volba ''{1}{2}'' nepøipou¹tí argument
+getopt.requires={0}: volba ''{1}'' vyŸaduje argument
+getopt.unrecognized={0}: nepøípustná volba ''--{1}''
+getopt.unrecognized2={0}: nepøípustná volba ''{1}{2}''
+getopt.illegal={0}: nepøípustná volba -- {1}
+getopt.invalid={0}: neplatná volba -- {1}
+getopt.requires2={0}: volba vyŸaduje argument -- {1}
+getopt.invalidValue=Neplatná hodnota {0} parameteru 'has_arg' 
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_de.properties
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_de.properties	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_de.properties	(revision 21017)
@@ -0,0 +1,33 @@
+/**************************************************************************
+/* MessagesBundle.properties -- German language error messages
+/*
+/* German Messages Copyright (c) 1999 by Bernhard Bablok (bablokb@gmx.net)
+/* These messages are encoded in ISO-8859-1
+//*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by  the Free Software Foundation; either version 2 of the License or
+/* (at your option) any later version.
+/*
+/* This program is distributed in the hope that it will be useful, but
+/* WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/* GNU Library General Public License for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; see the file COPYING.LIB.  If not, write to
+/* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+/* Boston, MA  02111-1307 USA
+/**************************************************************************/
+
+getopt.ambigious={0}: Option ''{1}'' ist zweideutig
+getopt.arguments1={0}: Option ''--{1}'' erlaubt kein Argument
+getopt.arguments2={0}: Option ''{1}{2}'' erlaubt kein Argument
+getopt.requires={0}: Option ''{1}'' benötigt ein Argument
+getopt.unrecognized={0}: Unbekannte Option ''--{1}''
+getopt.unrecognized2={0}: Unbekannte Option ''{1}{2}''
+getopt.illegal={0}: Verbotene Option -- {1}
+getopt.invalid={0}: Ungültige Option -- {1}
+getopt.requires2={0}: Option benötigt ein Argument -- {1}
+getopt.invalidValue=Ungültiger Wert {0} für Parameter 'has_arg' 
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_fr.properties
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_fr.properties	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_fr.properties	(revision 21017)
@@ -0,0 +1,35 @@
+/**************************************************************************
+/* MessagesBundle_fr.properties -- French language error messages
+/*
+/* Copyright (c) 1999 Free Software Foundation, Inc.
+/*    Michel Robitaille <robitail@IRO.UMontreal.CA>, 1996,
+/*    Edouard G. Parmelan <edouard.parmelan@quadratec.fr>, 1999.
+/* These messages are encoded in ISO-8859-1
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by  the Free Software Foundation; either version 2 of the License or
+/* (at your option) any later version.
+/*
+/* This program is distributed in the hope that it will be useful, but
+/* WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/* GNU Library General Public License for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; see the file COPYING.LIB.  If not, write to
+/* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+/* Boston, MA  02111-1307 USA
+/**************************************************************************/
+
+getopt.ambigious={0}: l'option ''{1}'' est ambiguë
+getopt.arguments1={0}: l'option ''--{1}'' ne permet pas de paramètre
+getopt.arguments2={0}: l'option ''{1}{2}'' ne permet pas de paramètre
+getopt.requires={0}: l'option ''{1}'' requiert un paramètre
+getopt.unrecognized={0}: option non reconnue ''--{1}''
+getopt.unrecognized2={0}: option non reconnue ''{1}{2}''
+getopt.illegal={0}: option illégale -- {1}
+getopt.invalid={0}: option invalide -- {1}
+getopt.requires2={0}: cette option requiert un paramètre -- {1}
+getopt.invalidValue=Valeur invalide {0} pour le paramètre 'has_arg'
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_no.properties
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_no.properties	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/MessagesBundle_no.properties	(revision 21017)
@@ -0,0 +1,32 @@
+/**************************************************************************
+/* MessagesBundle.properties -- Norwegian language error messages
+/*
+/* Copyright (c) 1999 by Bjørn-Ove Heimsund (s811@ii.uib.no)
+/*
+/* This program is free software; you can redistribute it and/or modify
+/* it under the terms of the GNU Library General Public License as published
+/* by  the Free Software Foundation; either version 2 of the License or
+/* (at your option) any later version.
+/*
+/* This program is distributed in the hope that it will be useful, but
+/* WITHOUT ANY WARRANTY; without even the implied warranty of
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/* GNU Library General Public License for more details.
+/*
+/* You should have received a copy of the GNU Library General Public License
+/* along with this program; see the file COPYING.LIB.  If not, write to
+/* the Free Software Foundation Inc., 59 Temple Place - Suite 330,
+/* Boston, MA  02111-1307 USA
+/**************************************************************************/
+
+getopt.ambigious={0}: flagget ''{1}'' er flertydig
+getopt.arguments1={0}: flagget ''--{1}'' tillater ikke et argument
+getopt.arguments2={0}: flagget ''{1}{2}'' tillater ikke et argument
+getopt.requires={0}: flagget ''{1}'' krever et argument
+getopt.unrecognized={0}: ukjent flagg ''--{1}''
+getopt.unrecognized2={0}: ukjent flagg ''{1}{2}''
+getopt.illegal={0}: ugyldig flagg -- {1}
+getopt.invalid={0}: ugyldig flagg -- {1}
+getopt.requires2={0}: flagget krever et argument -- {1}
+getopt.invalidValue=Ugyldig verdi {0} for parameter 'has_arg' 
+
Index: other-projects/gs2-java-client/trunk/gnu/getopt/README
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/README	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/README	(revision 21017)
@@ -0,0 +1,43 @@
+This is a Java port of the GNU getopt functions based on the versions 
+contained in glibc 2.0.6.  I have attempted to keep the functionality 
+and programmer's interface as faithful to the original as possible.
+However, due to differences between Java and C, some minor changes
+has to me made.  (Given the obtuse interface in the clib version, 
+perhaps some major changes should have been made).  This should not 
+affect the way options appear to be parsed to the end user of program 
+that uses this Java getopt.  The use of these classes are completely 
+documented in the javadoc comments, so I will not repeat that info here. 
+
+Note that since these objects are part of a package called "gnu.getopt", 
+they need to be in a subdirectory called gnu/getopt somewhere in your 
+CLASSPATH.  This includes the "MessagesBundle" files.
+
+I am not aware of any bugs.  If you find one though, please send email 
+to me at arenn@urbanophile.com.  The more detailed a bug report the better. 
+Bug fixes are also welcome at the same address.  Please reference
+release number "1.0.7".  If you use this code, it would be helpful
+if you let me know so that I can let you know if anything changes or
+if any major bugs have been found/fixed.
+
+I have included a Makefile for compiling the code. If you do not have
+access to make, then you can simply do a "javac *.java" at the OS 
+command line (or follow your vendor's instructions for compiling a
+Java class).  To build the documentation, do a "make docs" 
+or "javadoc -public *.java".  Note that the images needed by the html
+generated by javadoc are not included.  You will need to get those
+from some other Java documentation package.
+
+Note that the Makefile is not compliant with the GNU makefile
+standards as I anticipate that at some point a master makefile will
+be created for various GNU Java packages.  And it is serious overkill
+to create a megabloat makefile (kinda like this megabloat README) for 
+such a simple package.
+
+There is sample code showing how to use getopt available in the
+GetoptDemo.java file.
+
+Happy hacking,
+
+Aaron.
+arenn@urbanophile.com
+http://www.urbanophile.com/arenn/
Index: other-projects/gs2-java-client/trunk/gnu/getopt/package.html
===================================================================
--- other-projects/gs2-java-client/trunk/gnu/getopt/package.html	(revision 21017)
+++ other-projects/gs2-java-client/trunk/gnu/getopt/package.html	(revision 21017)
@@ -0,0 +1,11 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.16-22 i686) [Netscape]">
+   <title>Utils Package</title>
+</head>
+<body bgcolor="#FFFFFF">
+A package for parsing line arguments to programs.
+</body>
+</html>
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/Makefile
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/Makefile	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/Makefile	(revision 21017)
@@ -0,0 +1,35 @@
+
+CLASSES = SimpleClient.class Proxy.class SearchAllCollections.class
+
+all : subdirs $(CLASSES)
+	echo try a command like "java org.nzdl.gsdl.SimpleClient -v 2 -Q"
+
+subdirs :
+	(cd service && $(MAKE) all)
+	(cd util && $(MAKE) all)
+	(cd hli && $(MAKE) all)
+	(cd SimpleGraphicalClient && $(MAKE) all)
+
+clean:
+	(cd SimpleGraphicalClient && $(MAKE) clean)
+	(cd util && $(MAKE) clean)
+	(cd service && $(MAKE) clean)
+	(cd hli && $(MAKE) clean)
+	rm -f *.class
+
+distclean : clean
+
+
+# Instructions for compiling the java files
+JAVAC=javac
+
+#JAVACOPTIONS= -g:lines
+#JAVACOPTIONS= -g:none -O
+
+%.class : %.java
+	$(JAVAC) $(JAVACOPTIONS)  $<
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/Proxy.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/Proxy.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/Proxy.java	(revision 21017)
@@ -0,0 +1,131 @@
+/*
+ *    Proxy.java
+ *    Copyright (C) 2000 Stuart Yeates 
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl;
+
+// java standard library classes used
+import java.io.*;
+//import java.util.*;
+
+import org.omg.CosNaming.*;
+import org.omg.CORBA.ORB;
+
+// local libraries
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.service.NzdlCollectionInfo; 
+import org.nzdl.gsdl.service.NzdlQuery;
+import org.nzdl.gsdl.service.NzdlRequest;
+import org.nzdl.gsdl.service.NzdlResponse;
+import org.nzdl.gsdl.service.NzdlResultSet;
+import org.nzdl.gsdl.service.NzdlService;
+import org.nzdl.gsdl.service.NzdlServiceServer;
+import org.nzdl.gsdl.service.NzdlServiceClient;
+import org.nzdl.gsdl.service.NzdlCrossCollectionWrapper;
+import org.nzdl.gsdl.util.NzdlCorbaFactory;
+import org.nzdl.gsdl.util.NzdlServiceFactory;
+import org.nzdl.gsdl.util.NzdlPreferences;
+
+
+/**
+ * SimpleServer A very basic Greenstone server (not yet complete).
+ *
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.SimpleClient
+ * @see org.nzdl.gsdl.service.NzdlServiceServer
+ * @see org.omg.CORBA.ORB
+ * @see <a href="http://www.nzdl.org/">The New Zealand Digital Library Project</a>
+ * @see <a href="http://www.nzdl.org/fast-cgi-bin/library?&a=p&p=gsdl">Greenstone Digital Library Software</a>
+ */
+
+
+public class Proxy implements Serializable, Cloneable
+{
+  static String IORFileName = "/tmp/localcorba.proxy.objid";
+
+
+  /**
+   * Starts up a trivial server.
+   *
+   * @param args the arguments passed through to the orb initialisation code...
+   */
+  public static void main(String args[])
+  {
+    corbaComErrorHolder error = NzdlCorbaFactory.createComErrorHolder();
+    try{
+      NzdlPreferences.saving = false;
+      NzdlPreferences.setBoolean("Connect to multiple servers", false);
+      NzdlPreferences.setBoolean("Cache corba requests", true);
+      NzdlPreferences.setBoolean("Save documents", true);
+      NzdlPreferences.setBoolean("Log at the NzdlService level", false);
+
+      NzdlService client = NzdlServiceFactory.createNzdlService(args,
+								null,
+								null,
+								null,
+								null);
+      //client = new NzdlCrossCollectionWrapper(client,"");
+      
+      ORB orb = ORB.init(args, null);
+      
+      // Create the servant and register it with the ORB
+      NzdlServiceServer simpleRef = new NzdlServiceServer(client);
+
+      simpleRef.initialise(error);
+      if (error.value.value() != corbaComError._corbaNoError) {
+	System.err.println("CORBA error after initialisation:" + error.value.value());
+      }
+      
+      orb.connect(simpleRef);
+      System.err.println(orb.object_to_string(simpleRef));     
+     
+      NzdlServiceFactory.registerIOR(orb.object_to_string(simpleRef));
+
+      try  {
+	BufferedWriter output
+	  = new BufferedWriter(new FileWriter(IORFileName));
+	output.write(orb.object_to_string(simpleRef));
+	output.flush();
+      } catch (java.io.IOException e) {
+	System.err.println("Error reading IOR file:\n" + e);
+      }
+      
+
+
+      // Wait for invocations from clients
+      java.lang.Object sync = new java.lang.Object();
+      synchronized(sync){
+        sync.wait();
+      }
+      
+    } catch(Exception e) {
+      System.err.println("CORBA error:" + error.value.value());     
+      System.err.println("ERROR: " + e);
+      e.printStackTrace(System.out);
+    } 
+    
+  }
+}
+
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SearchAllCollections.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SearchAllCollections.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SearchAllCollections.java	(revision 21017)
@@ -0,0 +1,313 @@
+/*
+ *    SearchAllCollections.java
+ *
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl;
+
+// long live GNU ...
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+// java libraries we're using
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+// local libraries
+import org.nzdl.gsdl.service.NzdlCollectionInfo; 
+import org.nzdl.gsdl.service.NzdlQuery;
+import org.nzdl.gsdl.service.NzdlRequest;
+import org.nzdl.gsdl.service.NzdlResponse;
+import org.nzdl.gsdl.service.NzdlResultSet;
+import org.nzdl.gsdl.service.NzdlService;
+import org.nzdl.gsdl.service.NzdlServiceClient;
+import org.nzdl.gsdl.util.NzdlServiceFactory;
+
+/**
+ * Class SearchAllCollections
+ *
+ * Send a query to each collection and report the number of results.
+ *
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Stuart Yeates (say1@cs.waikato.ac.nz)
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.service.NzdlCollectionInfo
+ * @see org.nzdl.gsdl.service.NzdlQuery
+ * @see org.nzdl.gsdl.service.NzdlRequest
+ * @see org.nzdl.gsdl.service.NzdlResponse
+ * @see org.nzdl.gsdl.service.NzdlResultSet
+ * @see org.nzdl.gsdl.service.NzdlService
+ * @see org.nzdl.gsdl.service.NzdlServiceClient
+ * @see org.nzdl.gsdl.util.NzdlServiceFactory
+ * @see gnu.getopt.Getopt
+ * @see gnu.getopt.LongOpt
+ */
+
+public class SearchAllCollections implements Cloneable, Serializable {
+
+  /** The underlying CORBA inferface */
+  NzdlService nzdl = null;
+
+  /** Look for an IOR in the file first */
+  boolean useFileFirst = false;
+  /** The IOR that was specified on the commandline */
+  String IORFromCommandLine = null;
+  /** The URL that was specified on the commandline */
+  String URLFromCommandLine = null;
+  /** The name of the file we look for IOR's in */
+  static String IORFileName = "/tmp/localcorba.objid";
+
+  /** The query to use */
+  String queryText = "the";
+
+  /** How verbose do we want to be ? */
+  int verbosity = 0;
+
+    SearchAllCollections() {
+	nzdl = NzdlServiceFactory.createNzdlService(null, 
+						    System.getProperties(), 
+						    URLFromCommandLine,
+						    IORFileName, 
+						    IORFromCommandLine);
+	if (nzdl == null)
+	    throw new Error("URK! unable to find an IOR...");
+    }
+    
+
+    /** 
+     * Normal constructor. the args are passed into the orb 
+     * initialisation code so they can extract obscure args ...
+     */ 
+    SearchAllCollections(String [] args) {
+	// parseArgs(args);
+	nzdl = NzdlServiceFactory.createNzdlService(args, 
+						    System.getProperties(), 
+						    URLFromCommandLine, 
+						    IORFileName, 
+						    IORFromCommandLine);
+	if (nzdl == null)
+	    throw new Error("Unable to find an IOR.");
+    }
+
+    public void finalize(){
+
+    }
+
+    /** 
+     * Pre:  Accept SourceOfID as either: URL or IOR string or Filename
+     * Post: extract localcorba.objid from source of ID
+     */
+    private String getIorKey(String sourceOfID) {
+	String ior = null;
+	try  {
+	    sourceOfID = sourceOfID.trim();
+	    System.err.println("Reading IOR from: " + sourceOfID);
+	    
+	    String firstChars = sourceOfID.substring(0, Math.min(4,sourceOfID.length())).toUpperCase();
+	    // if sourceOfID is a URL ---------------------------------------
+	    if (sourceOfID.length() > 4 && firstChars.equalsIgnoreCase("HTTP"))	{
+		URL myUrl = new URL(sourceOfID);
+		BufferedReader input =new
+		    BufferedReader(new InputStreamReader(myUrl.openStream()));
+		ior = input.readLine();
+	    }
+	    
+	    // if sourceOfID is an IOR --------------------------------------
+	    else if (sourceOfID.length() > 4 && firstChars.equalsIgnoreCase("IOR:"))	{
+		ior = sourceOfID;      		  	
+	    }
+	    
+	    // else assume sourceOfID is a file name ------------------------
+	    else {
+		BufferedReader input
+		    = new BufferedReader(new FileReader(sourceOfID));
+		ior = input.readLine();      		  	
+	    }
+	}  //end of try
+	catch (java.io.IOException e) {
+	    System.err.println("Error reading IOR key:\n" + e);
+	    System.err.println("Aborting service...");
+	    System.exit(1);
+	}
+	return ior;
+    }   // end of getIorKey
+    
+
+    static String getHelpText() {
+	String s = "";
+	s += "SearchAllCollections - a Java client to the Greenstone Digital Library";
+	s += "\n";
+	s += "Arguments -\n";
+	s += "Short form Long form                Explaination\n";
+	s += "-h         --help                   Print this help text\n";
+	s += "-I <IOR>   --IOR <IOR>              Use <IOR> to connect\n";
+	s += "-f <file>  --file <IOR>             Look for an IOR if <file>\n";
+	s += "-q <query> --query <query>          Use <query>\n";
+	s += "-v <n>     --verbose <n>            Use verbosity level of <v>\n";
+	s += "               0 = silent except fro error reporting\n";
+	s += "               1 = reporting of operations\n";
+	s += "               2 = verbose reporting of operations \n";
+	s += "               3 = reporting of results of operations\n";
+	s += "               4 = showing all the documents retrieved\n";
+	s += "\n";
+	return s;
+    }
+    
+    private boolean parseArgs(String [] args) {
+	
+	LongOpt[] longopts = new LongOpt[9];
+	int i = 0;
+	StringBuffer sb = new StringBuffer();
+	
+	longopts[i++]  = new LongOpt("help",    LongOpt.NO_ARGUMENT,       null, 'h');
+	longopts[i++]  = new LongOpt("IOR",     LongOpt.REQUIRED_ARGUMENT, null, 'I');
+	longopts[i++]  = new LongOpt("file",    LongOpt.REQUIRED_ARGUMENT, null, 'f');
+	longopts[i++]  = new LongOpt("query",   LongOpt.REQUIRED_ARGUMENT, null, 'q');
+	longopts[i++]  = new LongOpt("verbose", LongOpt.REQUIRED_ARGUMENT, null, 'v');
+	Getopt g = new Getopt("org.nzdl.gsdl.SearchAllCollections",
+			      args, "hI:f:c:q:v:", longopts);
+	int c;
+	String arg;
+	try {
+	    while ((c = g.getopt()) != -1) {
+		switch(c) {
+		case 'h':
+		    System.out.println(getHelpText());
+		    return false;
+		case 'I':
+		    IORFromCommandLine = g.getOptarg();
+		    break;
+		case 'f':
+		    IORFileName = g.getOptarg();
+		    useFileFirst = true;
+		    break;
+		case 'q':
+		    queryText = g.getOptarg();
+		    break;
+		case 'v':
+		    arg = g.getOptarg();
+		    verbosity = Integer.parseInt(arg);
+		    break;
+		default:
+		    System.err.print(getHelpText());
+		    System.exit(1);
+	  
+		}
+	    }
+	} catch (Throwable t) {
+	    System.out.println("Exception thrown while processing arguments \n");
+	    t.printStackTrace(System.out);
+	    return false;
+	}
+	return true;
+    }
+  
+
+    void queryAllCollections() {
+	
+	
+	// set of collection titles
+	Set collectionSet = nzdl.getCollectionSet();
+	System.out.println("Searching for \"" + queryText 
+			   + "\" in up to " + collectionSet.size() + " collections.");
+	
+	Iterator collectionSetIterator = collectionSet.iterator();
+	while (collectionSetIterator.hasNext() ) {
+
+	    String collectionName = (String) collectionSetIterator.next(); 
+	    if (nzdl.hasCollection(collectionName) ) {
+		// if (nzdl.pingCollection(collectionName) ) {
+
+		// ping is broken, so use builddate to decide whether this 
+                // collection is valid
+		    NzdlCollectionInfo info = nzdl.getCollectionInfo(collectionName);
+		    if (info != null && info.getBuildDate() != 0) {
+			queryCollection(collectionName, queryText);
+		    }
+		// }
+	    } 
+	}
+    }
+
+    void queryCollection(String collectionName, String queryText)
+    {
+	NzdlQuery query = new NzdlQuery(queryText);
+	query.setMaxDocs( 10 );
+
+	NzdlRequest request = new NzdlRequest( query );
+	NzdlResponse response = new NzdlResponse( );
+	
+	nzdl.service( collectionName, request, response );
+	
+	long frequency = response.getResultSet().getNumOfDocs();
+	if (frequency > 0) {
+	    System.out.println("\n------------------------------");
+	    System.out.println(frequency + "\t" + collectionName);
+	    describeCollection(collectionName);
+	}
+    }
+    
+    void describeCollection(String collectionName) {
+
+      // collection name
+      Set n = nzdl.getMetaData(collectionName, "collection", "collectionname");
+      if (n.size() == 1) {
+	System.out.println("\nName: " + n.toArray()[0]);
+      }
+
+      // collection description
+      Set d = nzdl.getMetaData(collectionName, "collection", "collectionextra");
+      if (d.size() == 1) {
+	String value = (String) d.toArray()[0];
+	if (value.length() > 0) {
+	  System.out.println("Description: " + value);
+	} 
+      }
+
+      // basic collection information
+      NzdlCollectionInfo info = nzdl.getCollectionInfo(collectionName);
+      System.out.println("Info: " + info);
+    }
+    
+    
+    public static final void main( String [] args ) {
+	
+	SearchAllCollections client = new SearchAllCollections(args);
+	client.queryAllCollections();
+ 
+    } //main
+    
+} // class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleClient.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleClient.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleClient.java	(revision 21017)
@@ -0,0 +1,416 @@
+/*
+ *    SimpleClient.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl;
+
+// long live GNU ...
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
+// java libraries we're using
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+
+// local libraries
+import org.nzdl.gsdl.service.NzdlCollectionInfo; 
+import org.nzdl.gsdl.service.NzdlQuery;
+import org.nzdl.gsdl.service.NzdlRequest;
+import org.nzdl.gsdl.service.NzdlResponse;
+import org.nzdl.gsdl.service.NzdlResultSet;
+import org.nzdl.gsdl.service.NzdlService;
+import org.nzdl.gsdl.service.NzdlServiceClient;
+import org.nzdl.gsdl.util.NzdlServiceFactory;
+import org.nzdl.gsdl.service.NzdlFilterOption;
+import org.nzdl.gsdl.service.NzdlFilterOptions;
+/**
+ * Class SimpleClient
+ *
+ * A class to test the workings of Corba interface from the client side.
+ *
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz)
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.SimpleServer
+ * @see org.nzdl.gsdl.service.NzdlCollectionInfo
+ * @see org.nzdl.gsdl.service.NzdlQuery
+ * @see org.nzdl.gsdl.service.NzdlRequest
+ * @see org.nzdl.gsdl.service.NzdlResponse
+ * @see org.nzdl.gsdl.service.NzdlResultSet
+ * @see org.nzdl.gsdl.service.NzdlService
+ * @see org.nzdl.gsdl.service.NzdlServiceClient
+ * @see gnu.getopt.Getopt
+ * @see gnu.getopt.LongOpt
+ * @see <a href="http://www.nzdl.org/">The New Zealand Digital Library Project</a>
+ * @see <a href="http://www.nzdl.org/fast-cgi-bin/library?&a=p&p=gsdl">Greenstone Digital Library Software</a>
+ */
+
+public class SimpleClient implements Cloneable, Serializable {
+
+  /** The underlying CORBA inferface */
+  NzdlService nzdl = null;
+  /** Look for an IOR in the file first */
+  boolean useFileFirst = false;
+  /** The IOR that was specified on the commandline */
+  String IORFromCommandLine = null;
+  /** The URL that was specified on the commandline */
+  String URLFromCommandLine = null;
+  /** The name of the file we look for IOR's in */
+  static String IORFileName = "/tmp/localcorba.objid";
+  /** The collection to query */
+  String collectionNameToQuery = "";
+  /** The query to use */
+  String queryToQuery = "the";
+    /** The index to use */
+    String indexToQuery = "";
+  /** Poll all collections */
+  boolean examineAllCollections = false;
+  /** Should we load the docs as well ?*/
+  boolean loadDocs = false;
+  /** should we query all the collections with the query or just one ? */
+  boolean queryAllCollections = false;
+  /** How verbose do we want to be ? */
+  int verbosity = 2;
+
+  /** 
+   * Basic no-args constructor. Not recommended for normal use, 
+   * but necessary if we want to create beans ... 
+   */ 
+  protected SimpleClient() {
+    nzdl = NzdlServiceFactory.createNzdlService(null, 
+				      System.getProperties(), 
+				      URLFromCommandLine,
+				      IORFileName, 
+				      IORFromCommandLine);
+    if (nzdl == null)
+      throw new Error("URK! unable to find an IOR...");
+  }
+  
+  /** 
+   * Normal constructor. the args are passed into the orb 
+   * initialisation code so they can extract obscure args ...
+   */ 
+  SimpleClient(String [] args) {
+    parseArgs(args);
+    nzdl = NzdlServiceFactory.createNzdlService(args, 
+				      System.getProperties(), 
+				      URLFromCommandLine, 
+				      IORFileName, 
+				      IORFromCommandLine);
+    if (nzdl == null)
+      throw new Error("URK! unable to find an IOR...");
+  }
+
+
+  void pollCollections() {
+
+    // extract some highlevel information on the collections on the server
+    // independent of the command line arguments passed in
+    
+    Set collectionSet = nzdl.getCollectionSet(); // set of strings of collection titles
+    System.out.println("Number of collections on the server: " + collectionSet.size());
+		
+    Iterator collectionSetIterator = collectionSet.iterator();
+    while (collectionSetIterator.hasNext() ) {
+      String collectionName = (String)collectionSetIterator.next(); // object -> String
+      NzdlCollectionInfo collectionInfo = nzdl.getCollectionInfo( collectionName );
+      // this next line should work but doesn't
+      System.out.println("Collection: " + collectionInfo.getName());
+      // so we revert to using the original string from the collectionSet
+      System.out.println("Collection: " + collectionName);  
+      if (nzdl.hasCollection(collectionName) ) {
+	System.out.println("\t" + "hasCollection(" + collectionName + ")" + " is true");
+	if (nzdl.pingCollection(collectionName) ) {
+	  System.out.println("\t" + "pingCollection(" + collectionName + ")" + " is true");		
+	  // these next statements make use of the NzdlCollection API  		 
+	  System.out.println("\t" + "Public: " + collectionInfo.isPublic());
+	  System.out.println("\t" + "Beta: " + collectionInfo.isBeta());
+	  long buildDate = collectionInfo.getBuildDate();
+	  //process buildDate into something sensible
+	  System.out.println("\t" + "Build Date: " + buildDate);
+	  System.out.println("\t" + "No. of Documents: " + collectionInfo.getNumOfDocs());
+	  System.out.println("\t" + "No. of Words: " + collectionInfo.getNumOfWords());
+	  System.out.println("\t" + "No. of Bytes: " + collectionInfo.getNumOfBytes()); 
+	}
+	else {
+	  System.out.println("\t" + "pingCollection(" + collectionName + ")" + " is false");
+	}
+      }
+      else
+	{ 
+	  System.out.println("\t" + "hasCollection(" + collectionName + ")" + " is false"); 
+	}
+    } 
+		
+		
+  }
+
+  void runQuery()
+  {
+    String queryTerm = queryToQuery;
+    Vector  collections = new Vector();
+
+    Set collectionSet = nzdl.getCollectionSet(); 
+    
+    if (collectionSet.size() < 1)
+      throw new Error("unable to open query collection, no collections avaliable");
+
+
+    if (queryAllCollections == false) {
+      // if we're only doing one, we taken either the first or 
+      // the one we've been asked to query...
+      if (collectionNameToQuery.equals("")) {
+	Iterator collectionSetIterator = collectionSet.iterator();
+	collections.addElement(collectionSetIterator.next());
+      }  else {
+	collections.addElement(collectionNameToQuery);
+      }
+    } else {
+      Iterator collectionSetIterator = collectionSet.iterator();
+      while (collectionSetIterator.hasNext() ) {
+	String collectionName = (String)collectionSetIterator.next(); 
+	collections.addElement(collectionName);
+      }
+    }
+    
+    
+    Enumeration e = collections.elements();
+    while (e.hasMoreElements()) {
+      String collName  = (String) e.nextElement();
+
+
+      // get some basic col info - num docs in collection
+      NzdlCollectionInfo collInfo = nzdl.getCollectionInfo( collName );      
+      if (verbosity > 0)
+	System.out.println("Searching collection: " + collName);
+      
+      long numResults = collInfo.getNumOfDocs(); // number of docs in collection
+      if (verbosity > 2)
+	System.out.println("Collection " + collName + " has " + numResults + " documents" );
+
+      // get some filter options for query filter - list the indexes available
+      NzdlFilterOptions filterops = nzdl.getFilterOptionSet(collName, "QueryFilter");
+      
+      NzdlFilterOption filt;
+      if (verbosity > 1) {
+	  if (filterops.hasOption("Index")) {
+	      filt = (NzdlFilterOption)filterops.getFilterOption("Index");
+	      System.out.println(collName+"  has indexes "+ filt.validValues);
+	      System.out.println("The default index is "+filt.defaultValue);
+	  }
+      }
+
+      if (verbosity > 1)
+	System.out.print("Searching for query term: " + queryTerm+ ", in index: ");
+      if (indexToQuery=="") {
+	  System.out.println("[default]");
+      }
+      else {
+	  System.out.println(indexToQuery);
+      } 
+      String metaTag = "Title";
+      
+      // if (verbosity > 2)
+      //System.out.println("Searching in '" + metaTag + "' metadata");
+      
+      NzdlQuery query = new NzdlQuery( queryTerm );
+      // return the first numResults that match
+      query.setEndResults( 200 );
+      // "-1" means consider all the documents that match
+      query.setMaxDocs( 200);
+      query.setIndex(indexToQuery); // for mgpp colls, this must be a valid index, or "". otherwise it will cause an error.
+      
+      NzdlRequest request = new NzdlRequest( query );
+      NzdlResponse response = new NzdlResponse( );
+      if (verbosity > 2)
+	System.out.println("getting document IDs ... ");
+      nzdl.service( collName, request, response );
+      
+      NzdlResultSet results = response.getResultSet();
+      List docIDs = results.getDocumentIDs();
+
+      if (verbosity > 1)
+	System.out.println("Number of documents returned: " + docIDs.size());
+      if (verbosity > 2)
+	System.out.println("getting '" + metaTag + "' meta data of documents ... ");
+
+      Map metaData = nzdl.getMetaData( collName, docIDs, metaTag );
+      
+      for (ListIterator i = docIDs.listIterator(); i.hasNext(); ) {
+	String id = (String) i.next();
+	Set meta = (Set) metaData.get( id );
+	if (loadDocs) { 
+	  if (verbosity > 3) {
+	    System.out.println(meta.toString()); 
+	    System.out.println("getting document contents ... ");
+	  }
+	  String documentContents = nzdl.getDocument(collName, id);
+	  if (verbosity > 3) {
+	    System.out.println("got document contents. ");
+	    System.out.println(" *************** START DOC " + id + " ***************"); 
+	    System.out.println(documentContents);
+	    System.out.println(" *************** END DOC " + id + " ***************"); 
+	  }
+	} else {
+	  if (verbosity > 3) 
+	    System.out.println(meta.toString()); 
+	}
+      }
+    }
+  }
+	   
+    
+  static String getHelpText() {
+    String s = "";
+    s += "SimpleClient - a Java client to the Greenstone Digital Library";
+    s += "\n";
+    s += "Arguments -\n";
+    s += "Short form Long form                Explanation\n";
+    s += "-h         --help                   Print this help text\n";
+    s += "-u <url>   --URL <url>              Use <url> to connect\n";
+    s += "-I <IOR>   --IOR <IOR>              Use <IOR> to connect\n";
+    s += "-f <file>  --file <IOR>             Look for an IOR if <file>\n";
+    s += "-c <coll>  --collection <coll>      Examine collection <coll>\n";
+    s += "-a         --all                    Examine all collections\n";
+    s += "-q <query> --query <query>          Use <query>\n";
+    s += "-i <index> --index <index>          Query the <index> index\n";
+    s += "-d         --docs                   Load the documents as well\n";
+    s += "-Q         --queryAllCollections    Apply the <query> to all collections\n";
+    s += "-v <n>     --verbose <n>            Use verbosity level of <v>\n";
+    s += "               0 = silent except fro error reporting\n";
+    s += "               1 = reporting of operations\n";
+    s += "               2 = verbose reporting of operations \n";
+    s += "               3 = reporting of results of operations\n";
+    s += "               4 = showing all the documents retrieved\n";
+    s += "\n";
+    return s;
+  }
+  
+  private boolean parseArgs(String [] args) {
+    System.err.println("in parseArgs");
+   
+    LongOpt[] longopts = new LongOpt[11];
+    int i = 0;
+    StringBuffer sb = new StringBuffer();
+    
+    longopts[i++]  = new LongOpt("help",                  LongOpt.NO_ARGUMENT,       null, 'h');
+    longopts[i++]  = new LongOpt("IOR",                   LongOpt.REQUIRED_ARGUMENT, null, 'I');
+    longopts[i++]  = new LongOpt("URL",                   LongOpt.REQUIRED_ARGUMENT, null, 'u');
+    longopts[i++]  = new LongOpt("file",                  LongOpt.REQUIRED_ARGUMENT, null, 'f');
+    longopts[i++]  = new LongOpt("collection",            LongOpt.REQUIRED_ARGUMENT, null, 'c');
+    longopts[i++]  = new LongOpt("all",                   LongOpt.NO_ARGUMENT,       null, 'a');
+    longopts[i++]  = new LongOpt("query",                 LongOpt.REQUIRED_ARGUMENT, null, 'q');
+    longopts[i++]  = new LongOpt("index",                 LongOpt.REQUIRED_ARGUMENT, null, 'i');
+    longopts[i++]  = new LongOpt("docs",                  LongOpt.NO_ARGUMENT,       null, 'd');
+    longopts[i++]  = new LongOpt("verbose",               LongOpt.REQUIRED_ARGUMENT, null, 'v');
+    longopts[i++]  = new LongOpt("queryAllCollections",   LongOpt.NO_ARGUMENT,       null, 'Q');
+    Getopt g = new Getopt("org.nzdl.gsdl.SimpleClient",
+                          args,
+                          "hI:f:c:aq:i:dv:Qu:",
+                          longopts);
+    int c;
+    String arg;
+    try {
+      while ((c = g.getopt()) != -1) {
+        switch(c) {
+        case 'h':
+          System.out.println(getHelpText());
+	  System.exit(1);
+          return false;
+        case 'I':
+	  IORFromCommandLine = g.getOptarg();
+          break;
+        case 'u':
+	  URLFromCommandLine = g.getOptarg();
+          break;
+        case 'f':
+	  IORFileName = g.getOptarg();
+	  useFileFirst = true;
+          break;
+	case 'c':
+	  collectionNameToQuery = g.getOptarg();
+          break;
+	case 'q':
+	  queryToQuery = g.getOptarg();
+          break;
+	case 'i':
+	    indexToQuery = g.getOptarg();
+	    break;
+	case 'a':
+	  examineAllCollections = true;
+	  break;
+	case 'd':
+	  loadDocs = true;
+	  break;
+	case 'Q':
+	  queryAllCollections = true;
+	  break;
+	case 'v':
+          arg = g.getOptarg();
+          verbosity = Integer.parseInt(arg);
+          break;
+	default:
+	  System.err.print("getopt() returned " + c + " sb = \"" + sb +
+			   "\" longopts[g.getLongind()].getName() = \"" +
+			   longopts[g.getLongind()].getName() + "\"\n");
+	  System.err.print(getHelpText());
+	  System.exit(1);
+	  
+	}
+      }
+    } catch (Throwable t) {
+      System.out.println("Exception thrown while processing arguments \n");
+      t.printStackTrace(System.out);
+      return false;
+    }
+    return true;
+  }
+  
+  public static final void main( String [] args ) {
+    
+    SimpleClient client = new SimpleClient(args);
+    
+    if (client.examineAllCollections) 
+      client.pollCollections();
+    
+        client.runQuery();
+    
+  } //main
+
+} // class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Berry.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Berry.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Berry.java	(revision 21017)
@@ -0,0 +1,54 @@
+/*
+ *    Berry.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+
+import java.util.*;
+
+public class Berry extends Object {
+
+    private String berryTitle;
+    // private Person person;
+    private QueryHistoryItem queryHistoryItem;
+    private Date dateAdded;
+    private String collectionName; //unique collection ID across world?!?
+    private String documentID;
+      
+		 
+    public Berry(QueryHistoryItem newQueryHistoryItem, String newDocumentID, String newCollectionName, String newBerryTitle) {	
+	// need to add Person to argument list
+	queryHistoryItem = newQueryHistoryItem;
+	documentID = newDocumentID;
+	collectionName = newCollectionName;
+	berryTitle = newBerryTitle; // for the moment!
+	dateAdded = new Date();
+    }
+
+
+    public Date getDateAdded() {
+	return dateAdded;
+    }
+
+
+    public String toString () {
+	return( berryTitle);
+    }
+
+
+} // Berry class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/BerryBasketModel.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/BerryBasketModel.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/BerryBasketModel.java	(revision 21017)
@@ -0,0 +1,83 @@
+/*
+ *    BerryBasketModel.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+
+import java.util.*;
+import javax.swing.event.*;
+import javax.swing.*;
+import javax.swing.table.*; 
+import java.awt.*;
+
+
+class BerryBasketModel extends AbstractTableModel {
+
+    private ArrayList columnTitles;
+    private ArrayList berryBasket;
+
+    private String DOCUMENT = "Document";
+    private String DATE = "Date";
+ 
+ 
+    public BerryBasketModel()
+    {
+	super();
+	berryBasket = new ArrayList();
+	columnTitles = new ArrayList();
+	columnTitles.add(DOCUMENT);
+	//columnTitles.add("User");
+	columnTitles.add(DATE);
+    }
+
+    public void add(Berry berry) {
+	System.out.println("adding to BerryBasketModel: "  + berry.toString());
+	berryBasket.add(0, berry);
+	fireTableRowsInserted(0,0);
+    }
+	
+    public int getColumnCount() { 
+	return columnTitles.size();
+    }
+
+    public String getColumnName(int column) {
+	return (String) columnTitles.get(column);
+    }
+
+    public int getRowCount() {
+	return berryBasket.size();
+    }
+	
+    public Object getValueAt(int row, int column) { 
+	// get Berry object
+	// extract document title (say), person, date info from Berry object
+	// depending on column number
+	// column reordering shouldn't matter, all
+	// gets dealt with automatically
+
+	Berry berry = (Berry) berryBasket.get(row);
+
+	if (column == columnTitles.indexOf(DOCUMENT)) return berry.toString();
+
+	if (column == columnTitles.indexOf(DATE)) return berry.getDateAdded();
+
+	// shouldn't get here but display something anyway
+	return "row" + row + "col" + column;
+    }
+	
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/BerryBasketPanel.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/BerryBasketPanel.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/BerryBasketPanel.java	(revision 21017)
@@ -0,0 +1,71 @@
+
+/*
+ *    BerryBasketPanel.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+
+import javax.swing.*;
+import javax.swing.table.*;
+import javax.swing.border.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+
+public class BerryBasketPanel extends JPanel implements Constants {
+
+    BerryBasketModel berryModel;
+    JTable berryTable;
+    JList berryList;
+    JScrollPane scrollBerryPane;
+
+    public BerryBasketPanel(CSModel csModel)  {
+	super();
+	setLayout( new BorderLayout() );
+	setBorder(BorderFactory.createTitledBorder("BerryBasket"));
+	berryModel = csModel.getBerryBasketModel();
+	berryTable = new JTable(berryModel);
+ 
+	berryTable.setFont(berryFont);
+	berryTable.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
+	
+	//berryTable.setDefaultRenderer(Color.class, new BerryCellRenderer());
+	scrollBerryPane = new JScrollPane(berryTable);
+	berryTable.setPreferredScrollableViewportSize(new Dimension(100, 70));
+
+	add(scrollBerryPane, BorderLayout.CENTER);
+    } //end constructor
+
+
+    class BerryCellRenderer extends JLabel implements TableCellRenderer {
+  
+	public Component getTableCellRendererComponent(JTable table,
+						       Object value,
+						       boolean isSelected,
+						       boolean hasFocus,
+						       int row,
+						       int column) {
+	    this.setText(value.toString());
+	    return this;
+	} // end getTableCellRendererComponent
+  
+  
+    } //  end BerryCellRenderer
+
+} // end BerryBasketPanel
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/CSFrame.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/CSFrame.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/CSFrame.java	(revision 21017)
@@ -0,0 +1,284 @@
+
+/*
+ *    CSFrame.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+
+import javax.swing.JMenuItem;
+import javax.swing.JMenuBar;
+import javax.swing.JPanel;
+import javax.swing.JFrame;
+import javax.swing.JList;
+import javax.swing.JPopupMenu;
+import javax.swing.BoxLayout;
+import javax.swing.JMenu;
+import javax.swing.AbstractAction;
+import javax.swing.SwingUtilities;
+import javax.swing.KeyStroke;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.Observer;
+import java.util.Observable;
+/**
+ * Class 
+ *
+ * A class to 
+ * 
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.service.SimpleGraphicalClient.SimpleGraphicalClient
+ */
+
+public class CSFrame extends JFrame implements Observer, Constants
+
+{
+
+CSModel csModel;
+SearchPanel searchPanel;
+JPanel otherPanel;
+
+
+  // Constructor
+  public CSFrame(String title, CSModel newCSModel)
+  {
+    setTitle(title);                              // Set the window title
+	
+	csModel = newCSModel;
+	Container content = getContentPane();
+
+    setJMenuBar(menuBar);                         // Add the menu bar to the window
+
+    JMenu fileMenu = new JMenu("File");           // Create File menu
+    JMenu editMenu = new JMenu("Edit");    	   // Create Edit menu
+
+    // File Menu
+
+    //fileMenu.addSeparator();
+    fileMenu.add( quitAction = new FileAction("Poll Server", POLL_ID, this)).setAccelerator(KeyStroke.getKeyStroke('P', Event.CTRL_MASK));
+    fileMenu.add( quitAction = new FileAction("Collect Garbage", GARBAGE_ID, this)).setAccelerator(KeyStroke.getKeyStroke('G', Event.CTRL_MASK));
+    fileMenu.add( quitAction = new FileAction("Quit", QUIT_ID, this)).setAccelerator(KeyStroke.getKeyStroke('Q', Event.CTRL_MASK));
+
+    // Edit Menu
+
+    editMenu.add( prefAction = new EditAction("Preferences", PREF_ID, this));
+    editMenu.add( prefAction = new EditAction("View Change Log", LOG_ID, this));
+    editMenu.add( prefAction = new EditAction("View Licence", LICENCE_ID, this));
+    editMenu.add( prefAction = new EditAction("View CORBA interface", INTERFACE_ID, this));
+
+	
+    menuBar.add(fileMenu);                        // Add the file menu
+    menuBar.add(editMenu);                        // Add the edit menu
+	
+	
+	searchPanel = new SearchPanel(csModel, this);
+		
+	JPanel centerPanel = new JPanel();
+	QueryHistoryPanel queryHistoryPanel = new QueryHistoryPanel(csModel);
+	BerryBasketPanel berryBasketPanel = new BerryBasketPanel(csModel);
+
+
+	centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
+	centerPanel.add(berryBasketPanel);
+	centerPanel.add(queryHistoryPanel);
+
+
+	content.setLayout(new BoxLayout(content, BoxLayout.X_AXIS));	
+	content.add(searchPanel);
+	content.add(centerPanel);
+	
+	addWindowListener(new WindowHandler());
+		
+	pack();
+	searchPanel.searchTextField.requestFocus();
+  } //end constructor
+
+
+public void update(Observable observedThing, Object o )
+	{
+	System.out.println("Updating...");
+	//jlist.setListData( ((CSModel)observedThing).getModel() );
+	}
+
+
+
+  // action objects
+
+  abstract class CSAction extends AbstractAction {
+      int menuItemID;
+      CSFrame frame;
+  
+  		  CSAction( String name, int newMenuItemID, CSFrame f)
+  		  {
+  		   	super(name);
+			menuItemID = newMenuItemID;
+			frame = f;
+  		   }
+		   
+		   public abstract void actionPerformed(ActionEvent e);
+		   
+  } //end CSAction
+  
+  class FileAction extends CSAction
+  {
+        FileAction(String name, int newMenuItemID, CSFrame frame)
+        {
+             super(name,newMenuItemID, frame );
+         }
+
+         public void actionPerformed(ActionEvent e)
+         {
+		 switch (menuItemID) {
+		 		 case GARBAGE_ID:
+		   System.err.println("forcing gc...");
+		   System.gc() ;
+		   System.runFinalization();
+		   System.err.println("forcing gc...");
+		   System.gc() ;
+		   System.runFinalization();
+		   System.err.println("forced gc");
+		   break; 
+				case POLL_ID:
+					 System.out.println("poll chosen from menu");
+					 break; 
+				case QUIT_ID:
+					 System.out.println("quit chosen from menu");
+					 //save preferences not in dialog
+					 searchPanel.savePrefs();
+					 dispose();       // free resources
+					 System.exit(0);  // exit program
+					 break; 
+				default:
+					 System.out.println("unimplemented option chosen from FileAction");
+					 break; 
+		  } // end switch
+         }//end actionPerformed
+  } // end FileAction
+
+  class EditAction extends CSAction 
+  {
+        EditAction(String name, int newMenuItemID, CSFrame frame)
+        {
+             super(name,newMenuItemID, frame );
+         }
+
+         public void actionPerformed(ActionEvent e)
+         {
+		 switch (menuItemID) {
+		 		case PREF_ID:
+					 PreferencesDialog prefDialog = new PreferencesDialog(frame, "Preferences", false); 
+					 break;
+		 		case LOG_ID:
+					 FileDialog changeDialog = new FileDialog(frame, "ChangeLog", false,"ChangeLog"); 
+					 break;
+		 		case LICENCE_ID:
+					 FileDialog gplDialog = new FileDialog(frame, "GNU Public Licence", false,"GPL"); 
+					 break;
+		 		case INTERFACE_ID:
+					 FileDialog ifaceDialog = new FileDialog(frame, "Greenstone CORBA interface", false,"corbaiface.idl"); 
+					 break;
+		 		default:
+					 System.out.println("unimplemented option chosen from EditAction");
+					 break; 
+		 } // end switch
+         } //end actionPerformed
+  } // end EditAction
+  
+  
+class WindowHandler extends WindowAdapter
+{
+
+   public void windowOpened(WindowEvent e) {
+
+    SwingUtilities.invokeLater(new Runnable() {
+       public void run() {
+           searchPanel.searchTextField.requestFocus();
+		   searchPanel.searchTextField.setCaretPosition(
+		      searchPanel.searchTextField.getText().length() );
+		   searchPanel.searchTextField.selectAll();
+       }
+    });
+	} //end windowOpened
+
+
+
+	public void windowClosing(WindowEvent e)
+	{
+		dispose();       // free resources
+		System.exit(0);  // exit program
+	}
+}// end WindowHandler
+
+
+class MouseHandler extends MouseAdapter
+{
+private Frame frame;
+
+ 		public MouseHandler( CSFrame f )
+ 		{
+		   this.frame = f; 
+		}
+
+     public void mouseClicked(MouseEvent e) {
+	 		//System.out.println("mouse event" );
+         if (e.getClickCount() == 2) {
+		 	 System.out.println("double click - mouse event" );
+             int index = jlist.locationToIndex(e.getPoint());
+			 System.out.println("index is " + index );
+			 //psObject = (PeopleSpaceObject) jlist.getModel().getElementAt(index);
+			 } //end if
+     } //end mouseClicked
+		  
+		  public void mousePressed(MouseEvent e) {
+          		 maybeShowPopup(e);
+          }
+
+    	  public void mouseReleased(MouseEvent e) {
+          		 maybeShowPopup(e);
+    	  }
+
+    	  private void maybeShowPopup(MouseEvent e) {
+          		  if (e.isPopupTrigger()) {
+            	  	   contextPopup.show(e.getComponent(),
+                       e.getX(), e.getY());
+          		  } //end if	  
+  		  } //end maybeShowPopup
+  
+ } //end class MouseHandler
+
+  // private declarations
+  private JMenuBar menuBar = new JMenuBar();      // Window menu bar
+  private JMenuItem  quitItem;
+  
+ private JList jlist, peopleList;
+ private JPopupMenu contextPopup;
+
+  // FileActions
+  private FileAction newSpaceAction, newGroupAction, newPersonAction, quitAction;
+  
+  // EditActions
+  
+  private EditAction prefAction;
+
+  //Dialog
+
+  private PreferencesDialog newPreferencesDialog;
+  
+} //end CSFrame
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/CSModel.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/CSModel.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/CSModel.java	(revision 21017)
@@ -0,0 +1,190 @@
+/*
+ *    SimpleGraphicalClient.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import java.util.*;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.Iterator;
+import java.util.Vector;
+
+// local libraries
+
+import org.nzdl.gsdl.service.NzdlService;
+import org.nzdl.gsdl.service.NzdlCollectionInfo;
+
+/**
+ * Class 
+ *
+ * A class to 
+ * 
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.service.SimpleGraphicalClient.SimpleGraphicalClient
+ */
+
+class CSModel extends Object {
+
+    Vector collectionList;
+    TreeMap collectionInfoMap;
+    HashMap collectionNameMap;
+    String currentCollection;
+    ResultModel results;
+    NzdlService nzdl;
+    QueryHistoryModel queryHistoryModel;
+    BerryBasketModel berryBasketModel;
+    
+
+    public CSModel(NzdlService newNzdl)
+    {
+	nzdl = newNzdl;
+	results = new ResultModel();
+	collectionList = new Vector();
+	collectionInfoMap = new TreeMap();
+	collectionNameMap = new HashMap();
+	queryHistoryModel = new QueryHistoryModel();
+	berryBasketModel = new BerryBasketModel();
+	currentCollection = "";
+	initialiseCollection();
+    }
+  
+  
+    public NzdlService getNzdlService()
+    {
+	return nzdl;
+    }
+
+    public QueryHistoryModel getQueryHistoryModel() {
+	return queryHistoryModel;
+    }
+
+    public BerryBasketModel getBerryBasketModel() {
+	return berryBasketModel;
+    }
+	
+    /* Result methods */
+
+    public ResultModel getResultsModel()
+    {
+	return results;
+    }
+	
+    public void addResult(Result result)
+    {
+	results.add(result);
+    }
+	
+    public void clearResults()
+    {
+	//System.out.println("Clearing resultModel");
+	results.clear();
+    }
+
+    /* collectionList methods */
+
+    public Vector getCollectionList() {
+	return new Vector(collectionInfoMap.keySet());
+    }
+
+    public Collection getCollectionAsCollection() {
+	return (Collection)collectionInfoMap;
+    }
+
+    public int getCollectionListSize() {
+	return collectionInfoMap.size();
+    }
+
+    public NzdlCollectionInfo getCollectionInfo(String collectionName) {
+	return (NzdlCollectionInfo) collectionInfoMap.get(collectionName);
+    }
+
+
+    public String getLongCollectionName(String collectionName) {
+	return (String) collectionNameMap.get(collectionName);
+    }
+
+
+    public String getCollectionDescription(String collectionName) {
+	Set descSet = nzdl.getMetaData(collectionName, "collection", "collectionextra");
+	if (descSet.size() == 1) 
+	    return (String) descSet.toArray()[0];
+	else
+	    return "collectionName has more than 1 collectionextra entry";
+    }
+
+
+    public void setCurrentCollection(String collection )
+    {
+	currentCollection = collection;
+    }
+
+    public String getCurrentCollection()
+    {
+	return currentCollection;
+    }
+
+    public String getFirstCollection()
+    {
+	if (getCollectionListSize() > 0)
+	    return (String)collectionInfoMap.firstKey();
+	else
+	    return "no collections";
+    }
+    /**
+     *
+     */
+    public void initialiseCollection() 
+    {
+	Set collectionSet = nzdl.getCollectionSet(); // set of strings of collection titles
+	TreeSet orderedCollectionSet = new TreeSet(collectionSet);
+	// TreeSet automatically puts strings in alphabetical order
+	System.out.println("Number of collections on the server: " + 
+			   orderedCollectionSet.size());
+	Iterator collectionSetIterator = orderedCollectionSet.iterator();
+	while (collectionSetIterator.hasNext() ) {
+	    // object -> String
+	    String collectionName = (String)collectionSetIterator.next(); 
+	    NzdlCollectionInfo info = nzdl.getCollectionInfo(collectionName);
+
+	    if (info != null && 
+		info.getBuildDate() != 0 &&
+		nzdl.pingCollection(collectionName)) {
+		collectionInfoMap.put(collectionName, info);
+		String longCollectionName = "";
+		Set n = nzdl.getMetaData(collectionName, "collection", "collectionname");
+		if (n != null) {
+		    if (n.size() == 1) 
+			longCollectionName = (String) n.toArray()[0];
+		    else 
+			longCollectionName = collectionName + " has more than 1 collectionname";
+		    collectionNameMap.put(collectionName,longCollectionName );
+		    System.err.println("Adding " + collectionName + " to collection list...");
+		}
+	    } // end if
+	    else {
+		System.err.println("Collection " + collectionName + " getBuildDate() returned 0");
+	    } // end else
+	} // end while	
+	setCurrentCollection(getFirstCollection()); //assume at least one collection
+    
+    }
+	
+	
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/CollectionInfoDialog.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/CollectionInfoDialog.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/CollectionInfoDialog.java	(revision 21017)
@@ -0,0 +1,207 @@
+/*
+
+ *    CollectionInfoDialog.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+
+ *
+
+ *    This program is free software; you can redistribute it and/or modify
+
+ *    it under the terms of the GNU General Public License as published by
+
+ *    the Free Software Foundation; either version 2 of the License, or
+
+ *    (at your option) any later version.
+
+ *
+
+ *    This program is distributed in the hope that it will be useful,
+
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+ *    GNU General Public License for more details.
+
+ *
+
+ *    You should have received a copy of the GNU General Public License
+
+ *    along with this program; if not, write to the Free Software
+
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.text.html.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.text.*;
+import java.io.*;
+
+import org.nzdl.gsdl.service.*;
+
+public class CollectionInfoDialog extends JDialog implements ActionListener, Constants {
+
+private JButton okButton;
+private JPanel  buttonPanel, holderPanel, contentPanel, collectionNamePanel;
+private String publicString, betaString;
+private String fullCollectionName = "";
+private String descString = "";
+private String numOfWordsString, numOfDocsString;
+private NumberFormat numFormat = NumberFormat.getInstance();
+
+    CollectionInfoDialog(Frame f, String collectionName, CSModel csModel) {
+	super(f, "Collection Information" );
+
+	contentPanel = new JPanel(new GridLayout(0,2, 5, 4));;
+	buttonPanel = new JPanel();
+
+	NzdlCollectionInfo collectionInfo =  csModel.getCollectionInfo(collectionName);
+	
+	collectionNamePanel = new JPanel();
+	// collectionNamePanel.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
+	//collectionNamePanel.add(new JLabel(csModel.getLongCollectionName(collectionName)));
+	collectionNamePanel.add(new JLabel(collectionInfo.getLongCollectionName()));
+
+	contentPanel.add(new JLabel("Short collection name:"));
+	JLabel collectionLabel = new JLabel(collectionName);
+	contentPanel.add(collectionLabel);
+	contentPanel.add(new JLabel("Number of Documents:"));
+
+	long numOfDocs =  collectionInfo.getNumOfDocs();
+	if (numOfDocs == 0) 
+	    numOfDocsString = "unknown";
+	else 
+	    numOfDocsString = numFormat.format(numOfDocs);
+	contentPanel.add(new JLabel(numOfDocsString));
+	contentPanel.add(new JLabel("Number of Words:"));
+
+	long numOfWords = collectionInfo.getNumOfWords();
+	if (numOfWords == 0) 
+	    numOfWordsString = "unknown";
+	else
+	    numOfWordsString = numFormat.format(numOfWords);
+	contentPanel.add(new JLabel(numOfWordsString));
+	contentPanel.add(new JLabel("Size:"));
+	long numOfBytes = collectionInfo.getNumOfBytes();
+	contentPanel.add(new JLabel(formatByteSize(numOfBytes)));
+	contentPanel.add(new JLabel("Last built on:"));
+	// waiting for API to return a correct Date object ...
+	Date buildDate = new Date( collectionInfo.getBuildDate()*1000);
+	contentPanel.add(new JLabel(DateFormat.getDateTimeInstance().format(buildDate)));
+	contentPanel.add(new JLabel("Is it Public?"));
+
+	if (collectionInfo.isPublic())
+	    publicString = "yes";
+	else
+	    publicString = "no";
+	contentPanel.add(new JLabel(publicString));
+	contentPanel.add(new JLabel("Is it beta?"));
+	if (collectionInfo.isBeta())
+	    betaString = "yes";
+	else
+	    betaString = "no";
+	contentPanel.add(new JLabel(betaString));
+
+	JPanel descPanel = new JPanel();
+
+	descString = csModel.getCollectionDescription(collectionName);
+	//System.err.println(descString);
+	if (collectionInfo.isCollectionDescription()) {
+	    // insert this when it stops leaving extra \n in the text
+	    //descString = collectionInfo.getCollectionDescription();
+	    descPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10,2,5,2), BorderFactory.createTitledBorder("Description")));
+	    JTextPane descPane = new JTextPane();
+	    HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
+	    HTMLDocument htmlDoc = new HTMLDocument();
+	    descPane.setEditorKit(htmlEditorKit);
+	    try {
+		htmlEditorKit.read(new StringReader(descString), htmlDoc, 0); 
+	    }
+	    catch (Exception e) {
+		System.err.println(e);
+	    }
+	    descPane.setEditable(false);
+	    descPane.setFont(docFont);
+	    descPane.setDocument(htmlDoc);
+	    descPane.setCaretPosition(1); // we know descString.length() > 0
+	    JScrollPane scrollPane = new JScrollPane(descPane);
+	    scrollPane.setPreferredSize(new Dimension(420, 130));
+	    descPanel.add(scrollPane);
+	} // if
+
+	okButton = new JButton("Ok");
+	okButton.setPreferredSize(new Dimension(80,20));
+	okButton.addActionListener(this);
+	buttonPanel.add( okButton );
+	getRootPane().setDefaultButton(okButton);
+    
+	holderPanel = new JPanel();
+	holderPanel.setBorder(BorderFactory.createEmptyBorder(10,10,2,10));
+	holderPanel.setLayout( new BoxLayout(holderPanel, BoxLayout.Y_AXIS));
+	holderPanel.add(collectionNamePanel);
+	holderPanel.add(contentPanel);
+	if (descString.length() > 0) {
+	    holderPanel.add(Box.createVerticalStrut(10));
+	    holderPanel.add(descPanel); // only if we have a description to show
+	}
+	holderPanel.add(Box.createVerticalStrut(5));
+	holderPanel.add(buttonPanel);
+	getContentPane().add(holderPanel);
+	pack();
+	setVisible(true);
+    } //end CollectionInfoDialog constructor
+
+
+
+public void actionPerformed(ActionEvent e) {
+    Object source = e.getSource();
+    if (source == okButton)
+	{
+	    //System.err.println("ok button pressed!");
+
+	    dispose(); //close window
+	}
+    else
+	{
+		System.err.println("event not processed in CollectionInfoDialog");
+	}
+} //end actionPerformed
+
+
+    /* generate a string with correct sizing information */
+    /* bytes, K or G */
+    public String formatByteSize (long numberOfBytes) {
+	int minfd = numFormat.getMinimumFractionDigits();
+	int maxfd = numFormat.getMaximumFractionDigits();
+	String resultString;
+	numFormat.setMinimumFractionDigits(1);
+	numFormat.setMaximumFractionDigits(1);
+	if (numberOfBytes > 1073741824)
+	     resultString =  numFormat.format((numberOfBytes / (float)1073741824)) + " G";
+	else 
+	    if (numberOfBytes > 1048576)
+		resultString = numFormat.format((numberOfBytes / (float)1048576)) + " M";
+	    else {
+		numFormat.setMinimumFractionDigits(0);
+		numFormat.setMaximumFractionDigits(0);
+		if (numberOfBytes > 1024)
+		    resultString = numFormat.format((numberOfBytes / (float)1024)) + " K";
+	        else
+		    resultString =  numFormat.format(numberOfBytes) + " bytes";
+	    }
+	numFormat.setMinimumFractionDigits(minfd);
+	numFormat.setMaximumFractionDigits(maxfd);
+        return resultString;
+} // end formatByteSize
+
+
+
+} // end CollectionInfoDialog class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Constants.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Constants.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Constants.java	(revision 21017)
@@ -0,0 +1,91 @@
+/*
+ *    SimpleGraphicalClient.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import java.awt.*;
+
+/**
+ * Class 
+ *
+ * A class to 
+ * 
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.service.SimpleGraphicalClient.SimpleGraphicalClient
+ */
+
+
+public interface Constants
+
+{
+
+/* Menu Item IDs */
+
+/* File Menu */
+
+  final static int  QUIT_ID				= 104;
+  final static int  POLL_ID				= 105;
+  final static int  GARBAGE_ID				= 106;
+
+/* Edit Menu */
+
+  final static int PREF_ID	   			= 201;
+  final static int LOG_ID	   			= 202;
+  final static int LICENCE_ID	   			= 203;
+  final static int INTERFACE_ID	   			= 204;
+
+
+
+    /* Cursors */
+
+    Cursor NORMAL_CURSOR = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
+    Cursor WAIT_CURSOR = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
+
+    /* Query History Table Column Titles */
+    
+
+
+
+/*Fonts */
+
+/* font for display of document contents */
+Font docFont = new Font("SansSerif", Font.PLAIN , 10);
+
+/* font for display of results */
+
+Font resultsFont = new Font("SansSerif", Font.PLAIN , 10);
+
+/* font for display of berrybasket contents */
+
+Font berryFont = new Font("SansSerif", Font.PLAIN , 10);
+
+/* font for display of queryHistory */
+
+Font queryHistoryFont = new Font("SansSerif", Font.PLAIN , 10);
+
+/* font for query input TextField */
+
+Font searchTextFieldFont = new Font("SansSerif", Font.BOLD , 11);
+
+    /* fotn for search Term frequencies */
+
+    Font searchTermFreqFont = new Font("SansSerif", Font.PLAIN , 11);
+
+} 
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/DocumentInfoDialog.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/DocumentInfoDialog.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/DocumentInfoDialog.java	(revision 21017)
@@ -0,0 +1,100 @@
+/*
+ *    DocumentInfoDialog.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import javax.swing.*;
+import javax.swing.text.*;
+import javax.swing.text.html.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.text.*;
+import java.io.*;
+
+import org.nzdl.gsdl.service.*;
+
+public class DocumentInfoDialog 
+  extends JDialog 
+  implements ActionListener, Constants {
+  
+  private JButton okButton;
+  private JPanel  buttonPanel, holderPanel, contentPanel;
+
+  DocumentInfoDialog(Frame f, 
+		     String collectionName, 
+		     String docID, 
+		     CSModel csModel) {
+    super(f, "Document Information" );
+ 
+    contentPanel = new JPanel(new GridLayout(0,2, 5, 4));
+    buttonPanel = new JPanel();
+
+    NzdlDocumentInfo documentInfo =  
+      new NzdlDocumentInfo(csModel.nzdl, collectionName, docID);
+	
+    // collectionNamePanel.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
+    //collectionNamePanel.add(new JLabel(csModel.getLongDocumentName(collectionName)));
+    Enumeration keys = documentInfo.getKeys();
+    Enumeration values = documentInfo.getValues();
+
+    while (keys.hasMoreElements()) {
+      String key = (String) keys.nextElement();
+      String value = (String) values.nextElement();
+      contentPanel.add(new JLabel(key));
+      contentPanel.add(new JLabel(value));  
+    }
+
+    okButton = new JButton("Ok");
+    okButton.setPreferredSize(new Dimension(80,20));
+    okButton.addActionListener(this);
+    buttonPanel.add( okButton );
+    getRootPane().setDefaultButton(okButton);
+
+    holderPanel = new JPanel();
+    holderPanel.setBorder(BorderFactory.createEmptyBorder(10,10,2,10));
+    holderPanel.setLayout( new BoxLayout(holderPanel, BoxLayout.Y_AXIS));
+    holderPanel.add(contentPanel);
+    holderPanel.add(Box.createVerticalStrut(5));
+    holderPanel.add(buttonPanel);
+    getContentPane().add(holderPanel);
+
+    pack();
+    setVisible(true);
+  } //end DocumentInfoDialog constructor
+
+ 
+  public void actionPerformed(ActionEvent e) {
+    Object source = e.getSource();
+    if (source == okButton)
+      {
+	//System.err.println("ok button pressed!");
+	dispose(); //close window
+      }
+    else
+      {
+	System.err.println("event not processed in DocumentInfoDialog");
+      }
+  } //end actionPerformed
+
+} // end DocumentInfoDialog class
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/FileDialog.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/FileDialog.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/FileDialog.java	(revision 21017)
@@ -0,0 +1,120 @@
+/*
+ *    FileDialog.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.io.*;
+
+
+
+public class FileDialog extends JDialog implements ActionListener {
+
+  //private CSFrame parentFrame;
+  //private JButton okButton;
+  //private JTextArea text;
+  private String filename = "GPL";
+
+
+  FileDialog(CSFrame f, String title, boolean modal, String filename) {
+    super(f, title, modal );
+ 
+    this.filename = filename;
+
+    String log = null;
+    
+    try {
+      File file = new File(filename);
+      Reader rdr = null;
+      if (file.exists()) {
+	rdr = new FileReader(file);
+      } else {
+	file =  new File("../" + filename);
+	if (file.exists()){
+	  rdr = new FileReader(file);
+	} else {
+	  file =  new File("../../" + filename);
+	  if (file.exists()){
+	    rdr = new FileReader(file);
+	  } else {
+	    file =  new File("../../../" + filename);
+	    if (file.exists()){
+	      rdr = new FileReader(file);
+	    } else {
+	      file =  new File("../../../../" + filename);
+	      if (file.exists()){
+		rdr = new FileReader(file);
+	      }
+	    }
+	  }
+	}
+      }
+      if (rdr != null) {
+	int c = -1;
+	StringBuffer buf = new StringBuffer();
+	while((c = rdr.read()) != -1) {
+	buf.append((char) c);
+	}
+	log = buf.toString();
+      } else {
+	log = "Couldn't find the log file.\n Are we running from the java-client directory or a sub directory of it?";
+      }
+    } catch (Exception e) {
+      log = "Exception while reading log file: " + e;
+    }
+    
+    JTextArea text = new JTextArea(log);
+
+    text.setCaretPosition(1);
+    text.setEditable(false);
+
+    JScrollPane scrollPane = 
+	new JScrollPane(text);
+    // JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+    //  JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+    
+    JPanel panel = new JPanel();
+    panel.setLayout(new BorderLayout());
+    scrollPane.setPreferredSize(new Dimension(700, 500));
+    panel.add(scrollPane, BorderLayout.NORTH);
+    
+    JButton okButton = new JButton("Ok");
+    okButton.setPreferredSize(new Dimension(80,20));
+    okButton.addActionListener(this);
+    JPanel buttonPanel = new JPanel();
+    buttonPanel.add(okButton);
+
+    panel.add( buttonPanel, BorderLayout.SOUTH);
+    
+    getContentPane().add(panel);
+    getRootPane().setDefaultButton(okButton);
+
+    pack();
+    setVisible(true);
+  } 
+
+  public void actionPerformed(ActionEvent e) {
+  
+    dispose(); //close window
+  } 
+
+} // end PreferencesDialog class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/GMLDocument.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/GMLDocument.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/GMLDocument.java	(revision 21017)
@@ -0,0 +1,112 @@
+/*
+ *    GMLDocument.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import java.util.*;
+import javax.swing.text.*;
+import javax.swing.text.html.*;
+
+
+import org.nzdl.gsdl.service.*;
+
+/**
+ * Class GMLDocument
+ *
+ * A class to represent GML Documents
+ * 
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @see org.nzdl.gsdl.service.SimpleGraphicalClient.SimpleGraphicalClient
+ */
+
+public class GMLDocument extends HTMLDocument
+{
+
+    GMLDocument(){
+	super();
+    }
+
+
+
+    public void getImageData(NzdlService nzdl, String collectionName) {
+	// display image data
+	System.err.println("about to get iterator ...");
+	/* 
+	   HTML.Tag tag = HTML.Tag.IMG;
+	
+	   HTMLDocument.Iterator it = getIterator(tag); */
+	//System.err.println("collectionName = " + collectionName);
+	//System.err.println("HTTPPrefix = " + nzdl.getCollectionInfo(collectionName).getHTTPPrefix());
+	//System.err.println("HTTPDomain = " + nzdl.getCollectionInfo(collectionName).getHTTPDomain());
+
+	ElementIterator iterator = new ElementIterator(this);
+
+	Element element;
+
+	while ((element = iterator.next()) != null) {
+	    // System.err.println("Got an element, getName() = " + element.getName() );
+	    AttributeSet attributes = element.getAttributes();
+	    
+	    Object name = attributes.getAttribute(StyleConstants.NameAttribute);
+	    System.err.println(" " + name);
+	    if ( attributes.getAttribute(StyleConstants.NameAttribute) == HTML.Tag.IMG) {
+		System.err.println("Got an image!");
+		System.err.println("Num of attributes = " + attributes.getAttributeCount());
+		//Enumeration attributeNames = attributes.getAttributeNames();
+		for (Enumeration attributeNames = attributes.getAttributeNames()                      ; attributeNames.hasMoreElements() ;) {
+		    Object attributeName = attributeNames.nextElement();
+		    Object attributeValue = attributes.getAttribute(attributeName);
+		    System.err.println("\t" + attributeName + " = " + attributeValue);
+		} // end for
+	    } // end if
+        
+	 } // end while
+
+	/*
+	if (it.getTag() == null) System.err.println("iterator is null");
+	System.err.println("got iterator for tag type:" + it.getTag());
+	System.err.println("about to loop over " + it.getTag() + " tags...");
+	while (it.isValid()) {
+	    System.err.println("Found tag: " + it.getTag());
+	    System.err.println("Start offset = " + it.getStartOffset() + "  End Offset = " + it.getEndOffset());
+	    int length = it.getEndOffset() - it.getStartOffset();
+	    AttributeSet attributeSet = it.getAttributes();
+
+	    for (Enumeration i = attributeSet.getAttributeNames(); i.hasMoreElements();) { 
+		System.err.println(i.nextElement());
+	    }
+
+	    System.err.println("extracted Document contents = ...");
+	    try {
+		System.err.println(getText(it.getStartOffset(), length));
+	    }
+	    catch (BadLocationException e) {
+		System.err.println(e);
+	    }
+
+	    System.err.println("attr count =" + attributeSet.getAttributeCount());
+	    it.next();
+	}
+	System.err.println("no more " + it.getTag() + " tags");
+	System.err.println("tag " + tag + " has block status " + tag.isBlock());
+	*/
+	} //end getImageData
+
+
+
+} //end GMLDocument class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Makefile
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Makefile	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Makefile	(revision 21017)
@@ -0,0 +1,29 @@
+CLASSES = FileDialog.class\
+  PreferencesDialog.class\
+  CSFrame.class \
+  CSModel.class\
+  Constants.class\
+  Result.class\
+  ResultModel.class\
+  SearchPanel.class\
+  SimpleGraphicalClient.class\
+  CollectionInfoDialog.class\
+  DocumentInfoDialog.class
+
+all : $(CLASSES)
+	echo try a command like "java org.nzdl.gsdl.SimpleGraphicalClient.SimpleGraphicalClient"
+
+clean:
+	rm -f *.class
+
+distclean : clean
+
+
+# Instructions for compiling the java files
+JAVAC=javac
+
+#JAVACOPTIONS= -g:lines
+#JAVACOPTIONS= -g:none -O
+
+%.class : %.java
+	$(JAVAC) $(JAVACOPTIONS)  $<
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/PreferencesDialog.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/PreferencesDialog.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/PreferencesDialog.java	(revision 21017)
@@ -0,0 +1,181 @@
+/*
+
+ *    PreferencesDialogt.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+
+ *
+
+ *    This program is free software; you can redistribute it and/or modify
+
+ *    it under the terms of the GNU General Public License as published by
+
+ *    the Free Software Foundation; either version 2 of the License, or
+
+ *    (at your option) any later version.
+
+ *
+
+ *    This program is distributed in the hope that it will be useful,
+
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+
+ *    GNU General Public License for more details.
+
+ *
+
+ *    You should have received a copy of the GNU General Public License
+
+ *    along with this program; if not, write to the Free Software
+
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import org.nzdl.gsdl.util.NzdlConstants;
+import org.nzdl.gsdl.util.NzdlPreferences;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+
+
+
+public class PreferencesDialog extends JDialog implements ActionListener {
+
+    private CSFrame parentFrame;
+private JButton okButton, cancelButton;
+private JPanel  buttonPanel, holderPanel;
+private Box contentBox;
+    private JCheckBox showFirstDocCheckBox, showAsTextCheckBox, connectToMultipleCheckBox, logNetworkLevelCheckBox, useCacheCheckBox,  saveDocsCheckBox;
+
+
+
+PreferencesDialog(CSFrame f, String title, boolean modal) {
+    super(f, title, modal );
+    parentFrame = f;
+
+    contentBox = Box.createVerticalBox();
+    //  contentPanel = new JPanel();
+    //  GridLayout grid = new GridLayout(0,2,5,5);
+	  		
+    buttonPanel = new JPanel();
+
+    //editPanel.setLayout(new GridLayout(0,1,5,5));
+			
+
+    JLabel prefTitle = new JLabel("Preferences", SwingConstants.CENTER);
+    prefTitle.setAlignmentX(JLabel.CENTER_ALIGNMENT);
+    JPanel prefTitlePanel = new JPanel();
+    prefTitlePanel.add(prefTitle);
+
+    //contentBox.add();
+    // the preferences themselves ...
+
+    showFirstDocCheckBox = 
+      new JCheckBox( NzdlConstants.DISPLAY_FIRST_DOC, NzdlPreferences.getBoolean( NzdlConstants.DISPLAY_FIRST_DOC));
+    showFirstDocCheckBox.setHorizontalAlignment(SwingConstants.LEFT);
+
+    showAsTextCheckBox = 
+      new JCheckBox( NzdlConstants.RAW_TEXT, NzdlPreferences.getBoolean(NzdlConstants.RAW_TEXT));
+    showAsTextCheckBox.setHorizontalAlignment(SwingConstants.LEFT);
+
+    connectToMultipleCheckBox = 
+      new JCheckBox(NzdlConstants.MULTIPLE_SERVERS, NzdlPreferences.getBoolean(NzdlConstants.MULTIPLE_SERVERS));
+    connectToMultipleCheckBox.setHorizontalAlignment(SwingConstants.LEFT);
+
+    logNetworkLevelCheckBox = 
+      new JCheckBox(NzdlConstants.LOG_SERVICE, NzdlPreferences.getBoolean(NzdlConstants.LOG_SERVICE));
+    logNetworkLevelCheckBox.setHorizontalAlignment(SwingConstants.LEFT);
+
+    useCacheCheckBox = 
+      new JCheckBox(NzdlConstants.CACHE_CORBA, NzdlPreferences.getBoolean(NzdlConstants.CACHE_CORBA));
+    useCacheCheckBox.setHorizontalAlignment(SwingConstants.LEFT);
+
+    saveDocsCheckBox = 
+      new JCheckBox(NzdlConstants.SAVE_DOCS, NzdlPreferences.getBoolean(NzdlConstants.SAVE_DOCS));
+    saveDocsCheckBox.setHorizontalAlignment(SwingConstants.LEFT);
+
+    // add the preferences ...
+
+    contentBox.add(prefTitlePanel);
+    contentBox.add(showFirstDocCheckBox);
+    contentBox.add(showAsTextCheckBox);
+    contentBox.add(connectToMultipleCheckBox);
+    contentBox.add(logNetworkLevelCheckBox);
+    contentBox.add(useCacheCheckBox);
+    contentBox.add(saveDocsCheckBox);
+
+    okButton = new JButton("Ok");
+    cancelButton = new JButton("Cancel");
+    okButton.setPreferredSize(new Dimension(80,20));
+    cancelButton.setPreferredSize(new Dimension(80,20));
+    okButton.addActionListener(this);
+    cancelButton.addActionListener(this);
+    buttonPanel.add( okButton );
+    buttonPanel.add( cancelButton );
+    getRootPane().setDefaultButton(okButton);
+
+    holderPanel = new JPanel();
+    holderPanel.setBorder(BorderFactory.createEmptyBorder(10,10,2,10));
+    holderPanel.setLayout( new BorderLayout());
+    holderPanel.add( contentBox, BorderLayout.NORTH);
+    holderPanel.add( buttonPanel, BorderLayout.SOUTH);
+    getContentPane().add(holderPanel);
+    //setSize(new Dimension(300,300));
+
+    pack();
+    setVisible(true);
+} //end PreferencesDialog constructor
+
+
+
+public void actionPerformed(ActionEvent e) {
+    Object source = e.getSource();
+    if (source == okButton)
+	{
+	    //System.err.println("ok button pressed!");
+
+	    boolean oldRawText =  NzdlPreferences.getBoolean(NzdlConstants.RAW_TEXT);
+
+	    NzdlPreferences.setBoolean(NzdlConstants.DISPLAY_FIRST_DOC,showFirstDocCheckBox.isSelected());
+	    NzdlPreferences.setBoolean(NzdlConstants.RAW_TEXT, showAsTextCheckBox.isSelected());
+	    NzdlPreferences.setBoolean(NzdlConstants.MULTIPLE_SERVERS, connectToMultipleCheckBox.isSelected());
+	    NzdlPreferences.setBoolean(NzdlConstants.LOG_SERVICE,logNetworkLevelCheckBox.isSelected());
+	    NzdlPreferences.setBoolean(NzdlConstants.CACHE_CORBA, useCacheCheckBox.isSelected());
+	    NzdlPreferences.setBoolean(NzdlConstants.SAVE_DOCS, saveDocsCheckBox.isSelected());
+	  NzdlPreferences.getInstance().save();
+
+	  // update the current display if raw text option has changed ?
+
+	  boolean newRawText = NzdlPreferences.getBoolean(NzdlConstants.RAW_TEXT);
+	  
+	  if (oldRawText != newRawText) {
+	      //System.err.println("raw text option changed");
+	      if (newRawText) {
+		  // kludgy direct access to instance and method 
+		  parentFrame.searchPanel.switchToRawText();
+	      }
+	      else
+		  // kludgy direct access to instance and method
+	          parentFrame.searchPanel.switchToHTML();
+	  } // end if oldRawText != newRawTex
+
+	  dispose(); //close window
+	} // end if source == okButton
+    else
+	{
+	    if (source == cancelButton)
+		{
+		    dispose();
+		}					
+	    else
+		System.err.println("event not processed in PreferencesDialog");
+	}
+} //end actionPerformed
+
+} // end PreferencesDialog class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Query.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Query.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Query.java	(revision 21017)
@@ -0,0 +1,46 @@
+
+/*
+ *    Query.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+
+import java.io.*;
+
+public class Query extends Object
+{
+
+    /* should be able to return
+       query terms
+    */
+
+
+    private String queryText;
+
+    public Query(String queryString) {	 
+	queryText = queryString;
+    }
+
+    public String toString () {
+	return( queryText);
+    }
+    
+
+} //end Query class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/QueryHistoryItem.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/QueryHistoryItem.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/QueryHistoryItem.java	(revision 21017)
@@ -0,0 +1,95 @@
+
+/*
+ *    QueryHistoryItem.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import java.io.*;
+import java.util.*;
+
+public class QueryHistoryItem extends Object
+{
+
+    private Date date;
+    private String user; // should be a Person object
+    private Query query;
+    private String collectionName;
+    private long numOfHits;
+    private String queryType; // boolean or ranked
+    private boolean stemmed;
+    private boolean caseMatched;
+
+	   // time
+	   // person
+	   // etc
+	   
+    public QueryHistoryItem(Query newQuery, Date newDate, String newCollectionName, String newUser, long newNumOfHits, String newQueryType, boolean newStemmed, boolean newCaseMatched) {
+	query = newQuery;
+	date = newDate;
+	user = newUser;
+	collectionName = newCollectionName;
+	numOfHits = newNumOfHits;
+	queryType = newQueryType;
+	stemmed = newStemmed;
+	caseMatched = newCaseMatched;
+    }
+
+ public QueryHistoryItem() {
+     this(new Query(""), new Date(), "", "", 0, "", false, false);
+    }
+
+    public String getCollectionName() {
+	return collectionName;
+    }
+
+    public String getUser() {
+	return user;
+    }
+
+    public Query getQuery() {
+	return query;
+    }
+
+    public Date getDate() {
+	return date;
+    }
+
+    public long getNumOfHits() {
+	return numOfHits;
+    }
+
+    public String getQueryType() {
+	return queryType;
+    }
+
+    public boolean getStemmed() {
+	return stemmed;
+    }
+
+    public boolean getCaseMatched() {
+	return caseMatched;
+    }
+
+    public String toString () {
+	return( user + " " + date + " "  + collectionName +" terms");
+    }
+    
+
+} //end QueryHistoryItem class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/QueryHistoryModel.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/QueryHistoryModel.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/QueryHistoryModel.java	(revision 21017)
@@ -0,0 +1,109 @@
+/*
+ *    QueryHistoryModel.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import java.util.*;
+import javax.swing.event.*;
+import javax.swing.*;
+import javax.swing.table.*;
+
+class QueryHistoryModel extends AbstractTableModel implements Constants {
+
+    private ArrayList historyItems; 
+    private ArrayList columnTitles;
+
+    private String COLLECTION = "Collection";
+    private String DATE_TIME = "Time";
+    private String TERMS = "Terms";
+    private String HITS  = "Hits";
+    private String QUERYTYPE = "Type";
+    private String STEMMED = "Stem?";
+    private String CASEMATCHED = "Case?";
+
+
+    public QueryHistoryModel() {
+	super();
+	historyItems = new ArrayList();
+	columnTitles = new ArrayList();
+	columnTitles.add( DATE_TIME);
+	columnTitles.add( COLLECTION);
+	columnTitles.add( TERMS);
+	columnTitles.add(QUERYTYPE);
+	columnTitles.add(STEMMED);
+	columnTitles.add(CASEMATCHED);
+	columnTitles.add( HITS);
+    }
+
+	
+    public void add(QueryHistoryItem queryHistoryItem) {
+	historyItems.add(0,queryHistoryItem); //add at the top!
+	//fireTableDataChanged(); //too general
+	fireTableRowsInserted(0,0);
+    }
+	
+    public int getColumnCount() {
+	return columnTitles.size();
+    }
+
+    public Class getColumnClass(int c) {
+	return getValueAt(0, c).getClass();
+    }
+
+    public int getRowCount() {
+	return historyItems.size();
+    }
+
+    public String getColumnName(int column) {
+	return (String) columnTitles.get(column);
+    }
+
+    public Object getValueAt( int row, int column ) {
+	QueryHistoryItem historyItem = (QueryHistoryItem)historyItems.get(row);
+	if (column == columnTitles.indexOf(DATE_TIME)) return historyItem.getDate();
+	if (column == columnTitles.indexOf(COLLECTION)) return new CollectionName(historyItem.getCollectionName());
+	if (column == columnTitles.indexOf(TERMS)) return new Query(historyItem.getQuery().toString());
+	if (column == columnTitles.indexOf(HITS)) return new Long(historyItem.getNumOfHits());
+	if (column == columnTitles.indexOf(QUERYTYPE)) return new String(historyItem.getQueryType());
+	if (column == columnTitles.indexOf(STEMMED)) return new Boolean(historyItem.getStemmed());
+	if (column == columnTitles.indexOf(CASEMATCHED)) return new Boolean( historyItem.getCaseMatched());
+
+	// something has gone wrong if we get here!
+	// but display something anyway...
+	return "row" + row + "col" + column;
+    }
+   
+
+
+    public class CollectionName extends Object {
+	String string;
+
+	CollectionName(String newString) {
+	    string = newString;
+	}
+
+	public String toString() {
+	    return string;
+	}
+
+    } // CollectionName
+
+
+} //QueryHistoryModel
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/QueryHistoryPanel.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/QueryHistoryPanel.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/QueryHistoryPanel.java	(revision 21017)
@@ -0,0 +1,119 @@
+/*
+ *    QueryHistoryPanel.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.*;
+import javax.swing.*;
+import javax.swing.border.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.text.*;
+
+
+public class QueryHistoryPanel extends JPanel implements Constants
+{
+
+    QueryHistoryModel personalQueryHistoryModel;
+    CSModel csModel;
+
+    JTable personalQueryHistoryTable;
+    JTabbedPane tabbedPane;
+    JScrollPane personalScrollQueryPane;
+    TableSorter tableSorter;
+
+    public QueryHistoryPanel(CSModel newCSModel) {
+	super();
+	csModel = newCSModel;
+	setLayout( new BorderLayout() );
+	setBorder(BorderFactory.createTitledBorder("Query History"));
+	
+	personalQueryHistoryModel = csModel.getQueryHistoryModel();
+	tableSorter = new TableSorter(personalQueryHistoryModel);
+	personalQueryHistoryTable = new JTable(tableSorter);
+	tableSorter.addMouseListenerToHeaderInTable(personalQueryHistoryTable);
+
+
+	personalQueryHistoryTable.setDefaultRenderer(QueryHistoryModel.CollectionName.class, new CollectionNameRenderer());
+	personalQueryHistoryTable.setDefaultRenderer(Date.class, new DateRenderer());
+
+	personalQueryHistoryTable.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
+	personalScrollQueryPane = new JScrollPane(personalQueryHistoryTable);
+	
+	//this needs to be not hard-coded
+	personalQueryHistoryTable.getColumnModel().getColumn(0).setMaxWidth(110);
+	personalQueryHistoryTable.getColumnModel().getColumn(0).setMinWidth(110);
+	personalQueryHistoryTable.getColumnModel().getColumn(1).setMaxWidth(100);
+	personalQueryHistoryTable.getColumnModel().getColumn(3).setMaxWidth(50);
+
+	tabbedPane= new JTabbedPane();
+	tabbedPane.addTab("Personal", personalScrollQueryPane);
+	add(tabbedPane, BorderLayout.CENTER);
+    } // end constructor
+
+
+
+class CollectionNameRenderer extends JLabel implements TableCellRenderer {
+  
+  public Component getTableCellRendererComponent(JTable table,
+                                               Object value,
+                                               boolean isSelected,
+                                               boolean hasFocus,
+                                               int row,
+						 int column) {
+      this.setText(value.toString());
+      this.setFont(queryHistoryFont);
+      this.setToolTipText(csModel.getLongCollectionName(value.toString()));
+      this.setBorder(BorderFactory.createEmptyBorder(0,5,0,2));
+      return this;
+  } // end getTableCellRendererComponent
+  
+    
+
+  
+  } //  end CollectionNameRenderer
+
+class DateRenderer extends JLabel implements TableCellRenderer {
+  
+  public Component getTableCellRendererComponent(JTable table,
+                                               Object value,
+                                               boolean isSelected,
+                                               boolean hasFocus,
+                                               int row,
+					       int column) {
+      Date date = (Date) value;
+      this.setText(DateFormat.getInstance().format(date));
+      this.setFont(queryHistoryFont);
+      this.setToolTipText(DateFormat.getDateTimeInstance().format(date));
+
+      this.setBorder(BorderFactory.createEmptyBorder(0,5,0,2));
+      return this;
+  } // end getTableCellRendererComponent
+  
+    
+
+  
+  } //  end DateRenderer
+
+
+
+} // QueryHistoryPanel
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Result.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Result.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/Result.java	(revision 21017)
@@ -0,0 +1,72 @@
+/*
+ *    SimpleGraphicalClient.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+/**
+ * Class 
+ *
+ * A class to 
+ * 
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.service.SimpleGraphicalClient.SimpleGraphicalClient
+ */
+
+public class Result extends Object
+{
+       private String resultTitle;
+       private String docID;
+       private String collectionName;
+       private QueryHistoryItem queryHistoryItem;
+
+
+    public final static Result FAKE_RESULT = new Result("No results returned", "", "", new QueryHistoryItem() );
+    public final static Result INITIAL_FAKE_RESULT = new Result("Search results will appear here", "", "",  new QueryHistoryItem());
+       // related query
+	   // time, person, collection etc
+
+    public Result( String newResultTitle) {	 
+	resultTitle = newResultTitle;
+    }
+		 
+   public Result( String newResultTitle, String newResultDocID,  String newResultCollectionName, QueryHistoryItem newQueryHistoryItem)
+         {	 
+         resultTitle = newResultTitle;
+	 docID = newResultDocID;
+	 collectionName = newResultCollectionName;
+	 queryHistoryItem = newQueryHistoryItem;
+         }
+
+    public String toString () {
+	return resultTitle;
+    }
+    public String getDocID() {
+	return docID;
+    }
+    public String getCollectionName() {
+	return collectionName;
+    }
+    public QueryHistoryItem getQueryHistoryItem() {
+	return queryHistoryItem;
+    }
+
+
+
+} //end Result class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/ResultModel.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/ResultModel.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/ResultModel.java	(revision 21017)
@@ -0,0 +1,51 @@
+/*
+ *    ResultModel.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import javax.swing.event.*;
+import javax.swing.DefaultListModel;
+
+/**
+ * Class ResultModel
+ *
+ * A class to 
+ * 
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.service.SimpleGraphicalClient.SimpleGraphicalClient
+ */
+
+class ResultModel extends DefaultListModel 
+{
+	public ResultModel()
+	{
+		super();
+		
+	}
+
+	public void add(Result result)
+	{
+		//System.err.println("adding to ResultModel: "  + result.toString()+ " previous size = " + size());	
+		addElement(result);
+	}
+	
+	
+
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/SearchPanel.java	(revision 21017)
@@ -0,0 +1,519 @@
+/*
+ *    SimpleGraphicalClient.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.io.*;
+import java.io.IOException;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.text.html.*; 
+
+
+// local libraries
+import org.nzdl.gsdl.service.NzdlCollectionInfo; 
+import org.nzdl.gsdl.service.NzdlQuery;
+import org.nzdl.gsdl.service.NzdlRequest;
+import org.nzdl.gsdl.service.NzdlResponse;
+import org.nzdl.gsdl.service.NzdlResultSet;
+import org.nzdl.gsdl.service.NzdlService;
+import org.nzdl.gsdl.service.NzdlServiceClient;
+import org.nzdl.gsdl.util.*;
+
+
+/**
+ * A Class representing the Panel in which the Querying action happens. 
+ *
+ * Does most of the actual `work' in the package.
+ * 
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.service.SimpleGraphicalClient.SimpleGraphicalClient
+ * @see org.nzdl.gsdl.service.SimpleGraphicalClient.CSModel
+ * @see javax.swing.JPanel
+ */
+
+public class SearchPanel extends JPanel implements ActionListener, Constants
+{
+
+  CSModel csModel;
+  NzdlService nzdl;
+
+  JLabel searchTerms;
+  JLabel collectionLabel;
+  JButton collectionInfoButton;  
+  JTextField searchTextField;
+  JButton searchButton;
+  JComboBox collectionList;  
+  JPanel queryFormulationPanel, resultsPanel, dataPanel, optionsPanel; 
+    JPanel queryTypePanel, searchControlPanel,  searchTermsPanel;
+  JPanel collectionListPanel, searchTextFieldPanel, searchButtonPanel;
+    JPopupMenu resultPopup;
+    Result selectedResult;
+    ResultModel resultListModel;
+  JList   resultsList;   
+    JCheckBox stemCheckBox, caseFoldCheckBox;
+    JRadioButton rankedRadioButton, booleanRadioButton;
+    ButtonGroup buttonGroup;
+  JScrollPane scrollResultsPane;
+  JScrollPane scrollDataPane;
+  JFrame windowParent;
+    //JEditorPane documentPane;
+    JTextPane documentPane; // make this a JTextComponent ??
+    JTextArea documentArea;
+    JTextComponent documentComponent;
+    HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
+    StyledEditorKit styledEditorKit = new StyledEditorKit();
+    GMLDocument htmlDoc = new GMLDocument();
+    DefaultStyledDocument defaultStyledDoc = new DefaultStyledDocument();
+    final static GMLDocument blankDoc = new GMLDocument();
+  
+    /**
+   * Construct and initialise a new SearchPanel
+   */
+
+  public SearchPanel( CSModel newCsModel, JFrame parent) 
+  {
+    super();
+    windowParent = parent;
+    csModel = newCsModel;
+    nzdl = csModel.getNzdlService();
+    setLayout( new BoxLayout(this, BoxLayout.Y_AXIS));
+    setBorder(BorderFactory.createTitledBorder("Search"));
+	
+	
+    searchTextField = new JTextField("Enter search terms here", 35) { 
+	public boolean isRequestFocusEnabled(){ 
+	  return true; 
+	}
+      };
+    searchTextField.setText("Enter search terms here");
+    searchTextField.setFont(searchTextFieldFont);
+    searchTextField.setColumns(35);
+    searchTextField.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+    searchButton = new JButton("Search");
+	
+    searchButton.addActionListener(this);
+    //searchButton.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
+    searchButton.setPreferredSize(new Dimension(80, 20));
+	
+    collectionListPanel = new JPanel();
+    collectionListPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+    collectionListPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+    collectionLabel = new JLabel("Collection: ");
+
+    collectionList = new JComboBox(csModel.getCollectionList()){
+	       public boolean isFocusTraversable() {
+		return false;
+		}
+    };
+    collectionList.setEditable(false);
+     
+    collectionInfoButton = new JButton("Info...") {
+	    public String getToolTipText(MouseEvent e) {
+		return "Collection information for '" + csModel.getLongCollectionName((String)collectionList.getSelectedItem()) +"'";
+	    }
+    };
+    ToolTipManager.sharedInstance().registerComponent(collectionInfoButton);
+    collectionInfoButton.addActionListener(this);
+
+    collectionListPanel.add(collectionLabel);
+    collectionListPanel.add(collectionList);
+    collectionListPanel.add(collectionInfoButton);
+
+    searchTextFieldPanel = new JPanel();
+    searchTextFieldPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+    searchTextFieldPanel.add(searchTextField);
+
+    //NzdlPreferences prefs = NzdlPreferences.getInstance();
+    String queryType = NzdlConstants.DEFAULT_QUERY_TYPE;
+    if (NzdlPreferences.getInstance().isString(NzdlConstants.QUERYTYPE)) {
+	queryType = NzdlPreferences.getInstance().getString(NzdlConstants.QUERYTYPE);
+    }
+    // check integrity of queryType
+    if (!((queryType.equals(NzdlConstants.RANKED_STRING)) | (queryType.equals(NzdlConstants.BOOLEAN_STRING)))) {
+	// preferences may have been corrupted!
+	queryType = NzdlConstants.DEFAULT_QUERY_TYPE;
+    }
+    boolean stemming = NzdlConstants.DEFAULT_STEMMING;
+    if (NzdlPreferences.getInstance().isBoolean(NzdlConstants.STEMMING))
+	stemming = NzdlPreferences.getInstance().getBoolean(NzdlConstants.STEMMING);
+    boolean caseFolding = NzdlConstants.DEFAULT_CASE_FOLDING;
+    if (NzdlPreferences.getInstance().isBoolean(NzdlConstants.CASE_FOLDING))
+	caseFolding = NzdlPreferences.getInstance().getBoolean(NzdlConstants.CASE_FOLDING);
+	
+    optionsPanel = new JPanel();
+
+    queryTypePanel = new JPanel();
+    queryTypePanel.setLayout(new GridLayout(2,1));
+    rankedRadioButton = new JRadioButton(NzdlConstants.RANKED_STRING);
+    rankedRadioButton.setActionCommand(NzdlConstants.RANKED_STRING);
+    rankedRadioButton.setSelected(queryType.equals(rankedRadioButton.getText()));
+    rankedRadioButton.setToolTipText("Display results in a ranked list");
+    
+    booleanRadioButton = new JRadioButton(NzdlConstants.BOOLEAN_STRING);
+    booleanRadioButton.setActionCommand(NzdlConstants.BOOLEAN_STRING);
+    booleanRadioButton.setSelected(queryType.equals(booleanRadioButton.getText()));
+    booleanRadioButton.setToolTipText("Allows the use of Boolean operators: AND(&) OR(|) and NOT(!)");
+    buttonGroup = new ButtonGroup();
+    buttonGroup.add(rankedRadioButton);
+    buttonGroup.add(booleanRadioButton);
+    queryTypePanel.add(rankedRadioButton);
+    queryTypePanel.add(booleanRadioButton);
+
+    stemCheckBox = new JCheckBox("Stemming", stemming);
+    stemCheckBox.setToolTipText("Strip endings such as '...ing', '...ed'");
+    caseFoldCheckBox = new JCheckBox("Match case", caseFolding);
+    caseFoldCheckBox.setToolTipText("Only match when the case is the same");
+
+    optionsPanel.add(queryTypePanel);
+    optionsPanel.add(stemCheckBox);
+    optionsPanel.add(caseFoldCheckBox);
+
+    searchButtonPanel = new JPanel();
+    searchButtonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+    searchButtonPanel.add(searchButton);
+
+
+
+    searchControlPanel = new JPanel();
+    searchControlPanel.setLayout(new BorderLayout());
+    searchControlPanel.add(optionsPanel, BorderLayout.WEST);
+    searchControlPanel.add(searchButtonPanel, BorderLayout.EAST);
+
+    searchTermsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+    searchTerms = new JLabel("");
+    searchTerms.setFont(searchTermFreqFont);
+    searchTermsPanel.add(searchTerms);
+
+    queryFormulationPanel = new JPanel();
+    queryFormulationPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+    queryFormulationPanel.setLayout(new BoxLayout(queryFormulationPanel, BoxLayout.Y_AXIS));
+    queryFormulationPanel.add(Box.createHorizontalStrut(100));
+    queryFormulationPanel.add(collectionListPanel);
+    queryFormulationPanel.add(searchTextFieldPanel);
+    queryFormulationPanel.add(searchControlPanel);
+    queryFormulationPanel.add(searchTermsPanel);
+    
+
+    resultsPanel = new JPanel();
+    resultsPanel.setLayout(new BorderLayout());
+    resultsPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+    resultListModel = csModel.getResultsModel();
+    resultsList = new JList(resultListModel); 
+    resultsList.setFont(resultsFont);
+    resultsList.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+    resultsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+    scrollResultsPane = new JScrollPane(resultsList);
+    resultsPanel.add(scrollResultsPane, BorderLayout.CENTER);
+    csModel.addResult(Result.INITIAL_FAKE_RESULT);
+
+    resultPopup = new JPopupMenu();
+    JMenuItem copyResultItem = new JMenuItem("Copy result");
+    JMenuItem addBerryItem = new JMenuItem("Add to BerryBasket");
+
+    copyResultItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		System.err.println("copy result to clipboard");
+	    }
+    });
+
+
+
+
+    addBerryItem.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		csModel.getBerryBasketModel().add( new Berry(selectedResult.getQueryHistoryItem(),selectedResult.getDocID(),selectedResult.getCollectionName(), selectedResult.toString()));
+	    } // actionPerformed
+    });
+    resultPopup.add(copyResultItem);
+    resultPopup.addSeparator();
+    resultPopup.add(addBerryItem);
+    MouseListener popupListener = new PopupListener();
+    resultsList.addMouseListener(popupListener);
+
+
+
+
+    dataPanel = new JPanel();
+    dataPanel.setLayout(new BorderLayout());
+    dataPanel.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
+    documentPane = new JTextPane() { // to control scrolling for raw text docs
+                           public boolean getScrollableTracksViewportWidth() { 
+                           if (getSize().width < getParent().getSize().width)
+			        return true; 
+                           else return false; 
+                           } 
+                           public void setSize(Dimension d) { 
+                           if (d.width < getParent().getSize().width) 
+			        d.width = getParent().getSize().width; 
+                                super.setSize(d); 
+                           } 
+	}; // end custom JTextPane
+
+    documentPane.setEditable(false);
+    documentPane.setFont(docFont);
+    documentPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
+    //documentPane.setPreferredSize(new Dimension(100, 100));
+
+    scrollDataPane = new JScrollPane(documentPane);
+    scrollDataPane.setPreferredSize(new Dimension(300, 300));
+    dataPanel.add(scrollDataPane, BorderLayout.CENTER);
+
+    parent.getRootPane().setDefaultButton(searchButton);
+
+    resultsList.addListSelectionListener(new ResultListSelectionHandler() );
+
+    add(Box.createHorizontalStrut(400));
+    add(queryFormulationPanel);
+    add(resultsPanel);
+    add(dataPanel);
+    searchTextField.requestFocus();
+
+  }
+
+  /** respond to the user pressing the Search button */
+
+  public void actionPerformed(ActionEvent e) {
+      String collectionName = collectionList.getSelectedItem().toString();
+    if (e.getSource() == searchButton ) {
+      // cursor not set when RETURN pressed, only when button clicked ?
+      windowParent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+      String queryString = searchTextField.getText();
+      System.err.println("Search started (" + collectionName + "): \"" + queryString + "\" ..." );
+      //send query to collection
+      NzdlQuery nzdlQuery = new NzdlQuery(queryString);
+      nzdlQuery.setQueryType(buttonGroup.getSelection().getActionCommand());
+      //nzdlQuery.setQueryType("boolean");
+      nzdlQuery.setStemming(stemCheckBox.isSelected());
+      // interface reverses underlying logic so negate UI element state
+      nzdlQuery.setCaseFolding(! caseFoldCheckBox.isSelected());
+
+      // return the first numResults that match
+      nzdlQuery.setEndResults( -1 );
+      // "-1" means consider all the documents that match
+      nzdlQuery.setMaxDocs( -1 );
+
+      NzdlRequest request = new NzdlRequest( nzdlQuery );
+      NzdlResponse response = new NzdlResponse();
+      
+      nzdl.service( collectionName, request, response );
+      NzdlResultSet results = response.getResultSet();
+      ArrayList docIDs = new ArrayList(results.getDocumentIDs());
+      searchTerms.setText(results.getTermFrequencyString());
+
+      // paired collection of docIDs and Titles - but as Sets!
+      Map titleMetaData = nzdl.getMetaData( collectionName, docIDs, "Title" );
+      // created a paired collection of docIDs and Titles - as simple Strings!
+      HashMap titleMap = new HashMap();
+      for (ListIterator i = docIDs.listIterator(); i.hasNext(); ) {
+	String docID = (String) i.next();
+	//Set titleSet = (Set) titleMetaData.get( docID );
+	ArrayList titleList = new ArrayList((Set)titleMetaData.get(docID));
+	// use the first title as *the* title
+	titleMap.put(docID, titleList.get(0)); 
+      } // end for
+      // update the results list
+      csModel.clearResults();
+
+      QueryHistoryItem queryHistoryItem =  new QueryHistoryItem(new Query(queryString), new Date(), collectionName, "user",docIDs.size(),buttonGroup.getSelection().getActionCommand(),stemCheckBox.isSelected(), caseFoldCheckBox.isSelected());
+    csModel.getQueryHistoryModel().add(queryHistoryItem);
+
+      if (docIDs.size() == 0 ) { // give some feedback for 0 results
+	csModel.addResult(Result.FAKE_RESULT);
+	documentPane.setStyledDocument(blankDoc);
+      }
+      else { // there are some results
+	Iterator docIDsIterator = docIDs.iterator();
+	while (docIDsIterator.hasNext()) {
+	  String resultDocID =  (String) docIDsIterator.next();
+	  csModel.addResult(new Result((String)titleMap.get(resultDocID), resultDocID, collectionName, queryHistoryItem ));
+	} //end while
+	if (NzdlPreferences.getInstance().getBoolean(NzdlConstants.DISPLAY_FIRST_DOC))
+	resultsList.setSelectedIndex(0); 
+      } // end else
+
+      /*
+      csModel.getQueryHistoryModel().add( new QueryHistoryItem(new Query(queryString), new Date(), collectionName, "user",docIDs.size(),buttonGroup.getSelection().getActionCommand(),stemCheckBox.isSelected(), caseFoldCheckBox.isSelected() ));
+      */
+      titleMap.clear();
+      titleMetaData.clear();
+      docIDs.clear();
+      windowParent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+    } // end if
+    else {
+	if (e.getSource() == collectionInfoButton) {
+	    CollectionInfoDialog cid = new CollectionInfoDialog(windowParent, collectionName, csModel);
+	}
+	else {
+	    System.err.println("unknown Action event in SearchPanel");
+	}
+    }
+  } //end actionPerformed
+
+  /** handles selection events in the results list so that when the 
+      user selects a new title (say) the document contents is 
+      automatically displayed in the main panel */
+
+  class ResultListSelectionHandler implements ListSelectionListener {
+
+    public void valueChanged(ListSelectionEvent e) {
+      // get the result object from the SelectedIndex
+      // assume we only get here with events from resultsList
+	int docLength = 0;
+      if (e.getValueIsAdjusting()) { return; }
+      Result result =  (Result) resultsList.getSelectedValue();
+      
+      if ((result == Result.FAKE_RESULT) || (result == Result.INITIAL_FAKE_RESULT)) {
+	  documentPane.setStyledDocument( blankDoc );
+	  System.err.println("clicked on fake result");
+      }
+      else { // a real result representing a real document to deal with
+
+	  windowParent.setCursor(WAIT_CURSOR);
+
+	  deleteDocContents(); // for memory/garbage collection
+
+	  StringReader sr = new StringReader(nzdl.getDocument(result.getCollectionName(),  result.getDocID()));
+
+	  {
+	    // TODO find a more graceful place to display this info
+	    DocumentInfoDialog did = new DocumentInfoDialog(windowParent, result.getCollectionName(), result.getDocID(), csModel);
+	  }
+
+	  if (NzdlPreferences.getInstance().getBoolean(NzdlConstants.RAW_TEXT)) 
+	      // display the document as raw text
+	      displayAsRawText(sr);
+	  else {
+	      // treat as HTML
+	      displayAsHTML(sr);
+	      //htmlDoc.getImageData(nzdl, result.getCollectionName());
+	  }
+
+	  windowParent.setCursor(NORMAL_CURSOR);
+      }
+    } //end valueChanged
+  }//end ResultListSelectionHandler
+
+
+
+    private void deleteDocContents() {
+	//trash the old htmlDoc for memory/garbage collection
+	try {
+	    if (htmlDoc != null)
+		htmlDoc.remove(0, htmlDoc.getLength());
+	    if (defaultStyledDoc != null)
+		defaultStyledDoc.remove(0, defaultStyledDoc.getLength());
+	}
+	catch (Exception exception) {
+	    throw new Error (exception.toString());
+	}
+    } // end deleteDocContents
+
+
+    public void switchToRawText() {
+	windowParent.setCursor(WAIT_CURSOR);
+	System.err.println("switching to raw text");
+	displayAsRawText(new StringReader(documentPane.getText()));
+	windowParent.setCursor(NORMAL_CURSOR);
+    }
+
+    public void displayAsRawText(StringReader sr) {
+	    defaultStyledDoc = new DefaultStyledDocument();
+	    documentPane.setEditorKit(styledEditorKit);
+	    try {
+		styledEditorKit.read( sr, defaultStyledDoc, 0);
+	    }
+	    catch (Exception e) {
+		System.err.println(e);
+	    }
+	    documentPane.setDocument(defaultStyledDoc);
+	    setCaretToStart(defaultStyledDoc.getLength());
+     } // end displayAsRawText
+
+
+    public void switchToHTML() {
+	     windowParent.setCursor(WAIT_CURSOR);
+	     System.err.println("switching to HTML");
+	     displayAsHTML(new StringReader(documentPane.getText()));
+	     windowParent.setCursor(NORMAL_CURSOR);
+    }
+
+     public void displayAsHTML(StringReader sr) {
+	     htmlDoc = new GMLDocument();
+	     documentPane.setEditorKit(htmlEditorKit);
+	     try {
+		 htmlEditorKit.read( sr, htmlDoc, 0);
+	     }
+	     catch (Exception e) {
+		 System.err.println(e);
+	     }
+	     documentPane.setStyledDocument( htmlDoc );
+	     setCaretToStart(htmlDoc.getLength());
+      } // end displayAsHTML
+
+
+    private void setCaretToStart(int docLength) {
+		 // it seems as if they haven't considered 
+		 // documents with > MAX_INT num of chars ...
+	if (docLength > 0)
+		documentPane.setCaretPosition(1);
+    }
+
+    /*
+     * save prefs not in preferencesDialog 
+     */
+    public void savePrefs() {
+	NzdlPreferences.getInstance().setBoolean(NzdlConstants.STEMMING,stemCheckBox.isSelected());
+	NzdlPreferences.getInstance().setBoolean(NzdlConstants.CASE_FOLDING,caseFoldCheckBox.isSelected());
+	NzdlPreferences.getInstance().setString(NzdlConstants.QUERYTYPE,buttonGroup.getSelection().getActionCommand());
+    } //savePrefs
+
+
+    class PopupListener extends MouseAdapter {
+	public void mousePressed(MouseEvent e) {
+	    maybeShowPopup(e);
+	}
+
+	public void mouseReleased(MouseEvent e) {
+	    maybeShowPopup(e);
+	}
+
+	private void maybeShowPopup(MouseEvent e) {
+	    if (e.isPopupTrigger()) {
+		int index = resultsList.locationToIndex(new Point(e.getX(), e.getY()));
+		if ((index > -1) & (index < resultListModel.getSize())) {
+		    Result result = (Result) resultListModel.getElementAt(index);
+		    if ((result != Result.INITIAL_FAKE_RESULT) & (result != Result.FAKE_RESULT)) {
+			selectedResult = result;
+			resultPopup.show(e.getComponent(),
+					 e.getX(), e.getY());
+		    }
+		}
+			    }
+	}
+    } // PopupListener
+
+
+
+} //end SearchPanel
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/SimpleGraphicalClient.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/SimpleGraphicalClient.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/SimpleGraphicalClient.java	(revision 21017)
@@ -0,0 +1,143 @@
+
+
+/*
+ *    SimpleGraphicalClient.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import java.awt.Dimension;
+import java.awt.Toolkit;
+
+// local libraries
+import org.nzdl.gsdl.service.NzdlCollectionInfo; 
+import org.nzdl.gsdl.service.NzdlQuery;
+import org.nzdl.gsdl.service.NzdlRequest;
+import org.nzdl.gsdl.service.NzdlResponse;
+import org.nzdl.gsdl.service.NzdlResultSet;
+import org.nzdl.gsdl.service.NzdlService;
+import org.nzdl.gsdl.service.NzdlServiceClient;
+import org.nzdl.gsdl.util.NzdlPreferences;
+import org.nzdl.gsdl.util.NzdlServiceFactory;
+
+/**
+ * Class SimpleGraphicalClient
+ *
+ * A class to test the workings of Corba interface from the client side.
+ * 
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.service.NzdlCollectionInfo
+ * @see org.nzdl.gsdl.service.NzdlQuery
+ * @see org.nzdl.gsdl.service.NzdlRequest
+ * @see org.nzdl.gsdl.service.NzdlResponse
+ * @see org.nzdl.gsdl.service.NzdlResultSet
+ * @see org.nzdl.gsdl.service.NzdlService
+ * @see org.nzdl.gsdl.service.NzdlServiceClient
+ * @see org.nzdl.gsdl.util.NzdlServiceFactory;
+ */
+
+
+public class SimpleGraphicalClient implements Cloneable {
+
+  CSModel csModel;
+  CSFrame window;
+  
+  
+  /** The underlying CORBA inferface */
+  NzdlService nzdl = null;
+ 
+  /** The name of the file we look for IOR's in */
+  String IORFileName = "/tmp/localcorba.objid"; 
+  /** The IOR that was specified on the commandline */
+  String IORFromCommandLine = null;
+ 
+  /** How verbose do we want to be ? */
+  int verbosity = 2;
+	
+  /** 
+   * Basic constructor
+   */
+  SimpleGraphicalClient() {
+    System.err.println("in constructor");
+    init(null);
+  }
+
+  /** 
+   * Normal constructor
+   * @param args the command line arguments
+   */
+  public SimpleGraphicalClient(String [] args) {
+   
+    init(args);
+  }
+
+  /** 
+   * Do initialisation, including finding a server to connect to and
+   * setting up all the GUI stuff
+   * @param args the command line arguments
+   */
+    void init(String [] args)  {
+	nzdl = NzdlServiceFactory.createNzdlService(args, 
+					  System.getProperties(), 
+					  null,
+					  IORFileName, 
+					  IORFromCommandLine);
+	if (nzdl == null)
+	    throw new Error("URK! unable to find an IOR...");
+		
+	csModel = new CSModel(nzdl);
+   
+	window = new CSFrame("Search via Corba", csModel);   
+	Toolkit theKit = window.getToolkit();        // Get the window toolkit
+	Dimension screenSize = theKit.getScreenSize();  // Get screen size
+
+	// Set the position to screen center & size to half screen size
+	/* window.setBounds(screenSize.width/4, screenSize.height/4,        // Position
+	   screenSize.width/2, screenSize.height/2);      // Size
+  
+	*/
+	window.setVisible(true);	
+    } // init
+
+
+  /**
+   * Start the SimpleGraphicalClient 
+   * @param commandline arguments (only used in ORB initialisation).
+   */
+	
+  public static void main(String args[])
+  {
+		
+	  System.err.println("starting...");
+	  SimpleGraphicalClient sgc = new SimpleGraphicalClient();	
+
+	  
+  } //main
+	
+	
+} // class GraphicalClient
+
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/TableMap.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/TableMap.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/TableMap.java	(revision 21017)
@@ -0,0 +1,69 @@
+/** 
+ * In a chain of data manipulators some behaviour is common. TableMap
+ * provides most of this behavour and can be subclassed by filters
+ * that only need to override a handful of specific methods. TableMap 
+ * implements TableModel by routing all requests to its model, and
+ * TableModelListener by routing all events to its listeners. Inserting 
+ * a TableMap which has not been subclassed into a chain of table filters 
+ * should have no effect.
+ *
+ * @version 1.4 12/17/97
+ * @author Philip Milne */
+
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+import javax.swing.table.*; 
+import javax.swing.event.TableModelListener; 
+import javax.swing.event.TableModelEvent; 
+
+public class TableMap extends AbstractTableModel 
+                      implements TableModelListener {
+    protected TableModel model; 
+
+    public TableModel getModel() {
+        return model;
+    }
+
+    public void setModel(TableModel model) {
+        this.model = model; 
+        model.addTableModelListener(this); 
+    }
+
+    // By default, implement TableModel by forwarding all messages 
+    // to the model. 
+
+    public Object getValueAt(int aRow, int aColumn) {
+        return model.getValueAt(aRow, aColumn); 
+    }
+        
+    public void setValueAt(Object aValue, int aRow, int aColumn) {
+        model.setValueAt(aValue, aRow, aColumn); 
+    }
+
+    public int getRowCount() {
+        return (model == null) ? 0 : model.getRowCount(); 
+    }
+
+    public int getColumnCount() {
+        return (model == null) ? 0 : model.getColumnCount(); 
+    }
+        
+    public String getColumnName(int aColumn) {
+        return model.getColumnName(aColumn); 
+    }
+
+    public Class getColumnClass(int aColumn) {
+        return model.getColumnClass(aColumn); 
+    }
+        
+    public boolean isCellEditable(int row, int column) { 
+         return model.isCellEditable(row, column); 
+    }
+//
+// Implementation of the TableModelListener interface, 
+//
+    // By default forward all events to all the listeners. 
+    public void tableChanged(TableModelEvent e) {
+        fireTableChanged(e);
+    }
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/TableSorter.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/TableSorter.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/TableSorter.java	(revision 21017)
@@ -0,0 +1,313 @@
+/**
+ * A sorter for TableModels. The sorter has a model (conforming to TableModel) 
+ * and itself implements TableModel. TableSorter does not store or copy 
+ * the data in the TableModel, instead it maintains an array of 
+ * integers which it keeps the same size as the number of rows in its 
+ * model. When the model changes it notifies the sorter that something 
+ * has changed eg. "rowsAdded" so that its internal array of integers 
+ * can be reallocated. As requests are made of the sorter (like 
+ * getValueAt(row, col) it redirects them to its model via the mapping 
+ * array. That way the TableSorter appears to hold another copy of the table 
+ * with the rows in a different order. The sorting algorthm used is stable 
+ * which means that it does not move around rows when its comparison 
+ * function returns 0 to denote that they are equivalent. 
+ *
+ * @version 1.5 12/17/97
+ * @author Philip Milne
+ */
+package org.nzdl.gsdl.SimpleGraphicalClient;
+
+
+import java.util.*;
+
+import javax.swing.table.TableModel;
+import javax.swing.event.TableModelEvent;
+
+// Imports for picking up mouse events from the JTable. 
+
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.InputEvent;
+import javax.swing.JTable;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableColumnModel;
+
+public class TableSorter extends TableMap {
+    int             indexes[];
+    Vector          sortingColumns = new Vector();
+    boolean         ascending = true;
+    int compares;
+
+    public TableSorter() {
+        indexes = new int[0]; // for consistency
+    }
+
+    public TableSorter(TableModel model) {
+        setModel(model);
+    }
+
+    public void setModel(TableModel model) {
+        super.setModel(model); 
+        reallocateIndexes(); 
+    }
+
+    public int compareRowsByColumn(int row1, int row2, int column) {
+        Class type = model.getColumnClass(column);
+        TableModel data = model;
+
+        // Check for nulls.
+
+        Object o1 = data.getValueAt(row1, column);
+        Object o2 = data.getValueAt(row2, column); 
+
+        // If both values are null, return 0.
+        if (o1 == null && o2 == null) {
+            return 0; 
+        } else if (o1 == null) { // Define null less than everything. 
+            return -1; 
+        } else if (o2 == null) { 
+            return 1; 
+        }
+
+        /*
+         * We copy all returned values from the getValue call in case
+         * an optimised model is reusing one object to return many
+         * values.  The Number subclasses in the JDK are immutable and
+         * so will not be used in this way but other subclasses of
+         * Number might want to do this to save space and avoid
+         * unnecessary heap allocation.
+         */
+
+        if (type.getSuperclass() == java.lang.Number.class) {
+            Number n1 = (Number)data.getValueAt(row1, column);
+            double d1 = n1.doubleValue();
+            Number n2 = (Number)data.getValueAt(row2, column);
+            double d2 = n2.doubleValue();
+
+            if (d1 < d2) {
+                return -1;
+            } else if (d1 > d2) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else if (type == java.util.Date.class) {
+            Date d1 = (Date)data.getValueAt(row1, column);
+            long n1 = d1.getTime();
+            Date d2 = (Date)data.getValueAt(row2, column);
+            long n2 = d2.getTime();
+
+            if (n1 < n2) {
+                return -1;
+            } else if (n1 > n2) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else if (type == String.class) {
+            String s1 = (String)data.getValueAt(row1, column);
+            String s2    = (String)data.getValueAt(row2, column);
+            int result = s1.compareTo(s2);
+
+            if (result < 0) {
+                return -1;
+            } else if (result > 0) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else if (type == Boolean.class) {
+            Boolean bool1 = (Boolean)data.getValueAt(row1, column);
+            boolean b1 = bool1.booleanValue();
+            Boolean bool2 = (Boolean)data.getValueAt(row2, column);
+            boolean b2 = bool2.booleanValue();
+
+            if (b1 == b2) {
+                return 0;
+            } else if (b1) { // Define false < true
+                return 1;
+            } else {
+                return -1;
+            }
+        } else {
+            Object v1 = data.getValueAt(row1, column);
+            String s1 = v1.toString();
+            Object v2 = data.getValueAt(row2, column);
+            String s2 = v2.toString();
+            int result = s1.compareTo(s2);
+
+            if (result < 0) {
+                return -1;
+            } else if (result > 0) {
+                return 1;
+            } else {
+        	return 0;
+            }
+        }
+    }
+
+    public int compare(int row1, int row2) {
+        compares++;
+        for (int level = 0; level < sortingColumns.size(); level++) {
+            Integer column = (Integer)sortingColumns.elementAt(level);
+            int result = compareRowsByColumn(row1, row2, column.intValue());
+            if (result != 0) {
+                return ascending ? result : -result;
+            }
+        }
+        return 0;
+    }
+
+    public void reallocateIndexes() {
+        int rowCount = model.getRowCount();
+
+        // Set up a new array of indexes with the right number of elements
+        // for the new data model.
+        indexes = new int[rowCount];
+
+        // Initialise with the identity mapping.
+        for (int row = 0; row < rowCount; row++) {
+            indexes[row] = row;
+        }
+    }
+
+    public void tableChanged(TableModelEvent e) {
+        //System.out.println("Sorter: tableChanged"); 
+        reallocateIndexes();
+
+        super.tableChanged(e);
+    }
+
+    public void checkModel() {
+        if (indexes.length != model.getRowCount()) {
+            System.err.println("Sorter not informed of a change in model.");
+        }
+    }
+
+    public void sort(Object sender) {
+        checkModel();
+
+        compares = 0;
+        // n2sort();
+        // qsort(0, indexes.length-1);
+        shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length);
+        //System.out.println("Compares: "+compares);
+    }
+
+    public void n2sort() {
+        for (int i = 0; i < getRowCount(); i++) {
+            for (int j = i+1; j < getRowCount(); j++) {
+                if (compare(indexes[i], indexes[j]) == -1) {
+                    swap(i, j);
+                }
+            }
+        }
+    }
+
+    // This is a home-grown implementation which we have not had time
+    // to research - it may perform poorly in some circumstances. It
+    // requires twice the space of an in-place algorithm and makes
+    // NlogN assigments shuttling the values between the two
+    // arrays. The number of compares appears to vary between N-1 and
+    // NlogN depending on the initial order but the main reason for
+    // using it here is that, unlike qsort, it is stable.
+    public void shuttlesort(int from[], int to[], int low, int high) {
+        if (high - low < 2) {
+            return;
+        }
+        int middle = (low + high)/2;
+        shuttlesort(to, from, low, middle);
+        shuttlesort(to, from, middle, high);
+
+        int p = low;
+        int q = middle;
+
+        /* This is an optional short-cut; at each recursive call,
+        check to see if the elements in this subset are already
+        ordered.  If so, no further comparisons are needed; the
+        sub-array can just be copied.  The array must be copied rather
+        than assigned otherwise sister calls in the recursion might
+        get out of sinc.  When the number of elements is three they
+        are partitioned so that the first set, [low, mid), has one
+        element and and the second, [mid, high), has two. We skip the
+        optimisation when the number of elements is three or less as
+        the first compare in the normal merge will produce the same
+        sequence of steps. This optimisation seems to be worthwhile
+        for partially ordered lists but some analysis is needed to
+        find out how the performance drops to Nlog(N) as the initial
+        order diminishes - it may drop very quickly.  */
+
+        if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) {
+            for (int i = low; i < high; i++) {
+                to[i] = from[i];
+            }
+            return;
+        }
+
+        // A normal merge. 
+
+        for (int i = low; i < high; i++) {
+            if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {
+                to[i] = from[p++];
+            }
+            else {
+                to[i] = from[q++];
+            }
+        }
+    }
+
+    public void swap(int i, int j) {
+        int tmp = indexes[i];
+        indexes[i] = indexes[j];
+        indexes[j] = tmp;
+    }
+
+    // The mapping only affects the contents of the data rows.
+    // Pass all requests to these rows through the mapping array: "indexes".
+
+    public Object getValueAt(int aRow, int aColumn) {
+        checkModel();
+        return model.getValueAt(indexes[aRow], aColumn);
+    }
+
+    public void setValueAt(Object aValue, int aRow, int aColumn) {
+        checkModel();
+        model.setValueAt(aValue, indexes[aRow], aColumn);
+    }
+
+    public void sortByColumn(int column) {
+        sortByColumn(column, true);
+    }
+
+    public void sortByColumn(int column, boolean ascending) {
+        this.ascending = ascending;
+        sortingColumns.removeAllElements();
+        sortingColumns.addElement(new Integer(column));
+        sort(this);
+        super.tableChanged(new TableModelEvent(this)); 
+    }
+
+    // There is no-where else to put this. 
+    // Add a mouse listener to the Table to trigger a table sort 
+    // when a column heading is clicked in the JTable. 
+    public void addMouseListenerToHeaderInTable(JTable table) { 
+        final TableSorter sorter = this; 
+        final JTable tableView = table; 
+        tableView.setColumnSelectionAllowed(false); 
+        MouseAdapter listMouseListener = new MouseAdapter() {
+            public void mouseClicked(MouseEvent e) {
+                TableColumnModel columnModel = tableView.getColumnModel();
+                int viewColumn = columnModel.getColumnIndexAtX(e.getX()); 
+                int column = tableView.convertColumnIndexToModel(viewColumn); 
+                if (e.getClickCount() == 1 && column != -1) {
+                    //System.out.println("Sorting ..."); 
+                    int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK; 
+                    boolean ascending = (shiftPressed == 0); 
+                    sorter.sortByColumn(column, ascending); 
+                }
+            }
+        };
+        JTableHeader th = tableView.getTableHeader(); 
+        th.addMouseListener(listMouseListener); 
+    }
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/package.html
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/package.html	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/SimpleGraphicalClient/package.html	(revision 21017)
@@ -0,0 +1,18 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.16-22 i686) [Netscape]">
+   <title>Utils Package</title>
+</head>
+<body bgcolor="#FFFFFF">
+Contains a nice GUI client that can search collections and display documents.
+This program does not currently display document images.<br>
+To run from the command prompt: <br>
+<tt>
+cd java-client
+java org.nzdl.gsdl.SimpleGraphicalClient.SimpleGraphicalClient
+</tt>
+
+</body>
+</html>
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Collection.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Collection.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Collection.java	(revision 21017)
@@ -0,0 +1,200 @@
+/*
+ *    Collection.java
+ *    Copyright (C) 2000 Stuart Yeates 
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl.hli;
+
+import org.nzdl.gsdl.service.*;
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+
+// java standard library classes used
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.Cloneable;
+import java.util.Vector;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.Enumeration;
+import java.util.Date;
+
+/**
+ * Class ...
+ *
+ * Based on algorithms in ...
+ *
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see
+ * @see
+ * @see
+ * 
+ */
+
+public class Collection implements Cloneable, Serializable
+{
+  Server server = null;
+
+  /** Collection name */
+  String name = "empty collection name";
+  /** Collection name */
+  public String getName() { return name; };
+  /** Collection name */
+  public void setName(String str) { name = str; };
+
+  /** Collection display name */
+  String displayName = "empty collection display name";
+  /** Collection display name */
+  public String getDisplayName() { return displayName; };
+  /** Collection display name */
+  public void setDisplayName(String str) { displayName = str; };
+
+  /** Collection about text */
+  String aboutText = "empty about text";
+  /** Collection about text */
+  public String getAboutText() { return aboutText; };
+  /** Collection about text */
+  public void setAboutText(String str) { aboutText = str; };
+
+  /** Beta status */
+  boolean beta  = true;
+  /** Beta status */
+  public boolean get() { return beta; };
+  /** Beta status */
+  public void set(boolean str) { beta = str; };
+
+  /** The date the collection was built */
+  Date buildDate = new Date();
+  /** The date the collection was built */
+  public Date getBuildDate() { return buildDate; };
+  /** The date the collection was built */
+  public void setBuildDate(Date str) {buildDate  = str; };
+
+  /** Docs in Collection */
+  long docsInCollection = 0;
+  /** Docs in Collection */
+  public long getDocsInCollection() { return docsInCollection; };
+  /** Docs in Collection */
+  public void setDocsInCollection(long str) {docsInCollection  = str; };
+
+  /** Words in Collection */
+  long wordsInCollection  = 0;
+  /** Words in Collection */
+  public long getWordsInCollection() { return wordsInCollection; };
+  /** Words in Collection */
+  public void setWordsInCollection(long str) { wordsInCollection = str; };
+
+  /** Bytes in Collection */
+  long bytesInCollection  = 0;
+  /** Bytes in Collection */
+  public long getBytesInCollection() { return bytesInCollection; };
+  /** Bytes in Collection */
+  public void setBytesInCollection(long str) { bytesInCollection = str; };
+
+  /** Collection Level MetaData */
+  Vector collectionLevelMetadata = null;
+  /** Collection Level MetaData */
+  public Vector getCollectionLevelMetadata() { return collectionLevelMetadata; };
+  /** Collection Level MetaData */
+  public void setCollectionLevelMetadata(Vector str) { collectionLevelMetadata = str; };
+
+  /** Building (unclear what this is ...) */
+  Vector building = null;
+  /** Building (unclear what this is ...) */
+  public Vector getBuilding() { return building; };
+  /** Building (unclear what this is ...) */
+  public void setBuilding(Vector str) { building = str; };
+
+  /** Format (unclear what this is ...) */
+  Vector format = null;
+  /** Format (unclear what this is ...) */
+  public Vector getFormat() { return format; };
+  /** Format (unclear what this is ...) */
+  public void setFormat(Vector str) { format = str; };
+
+  class NamedValue {
+    String name;
+    String value;
+    NamedValue(String name, String value) {this.name=name;this.value=value;};
+  }
+
+  Collection(Server sever, String name, NzdlCollectionInfo info) {
+    this.server = server;
+    this.name = name;
+    
+    this.beta = info.isBeta();
+    this.buildDate = new Date(info.getBuildDate()*1000);
+    this.docsInCollection = info.getNumOfDocs();
+    this.wordsInCollection = info.getNumOfWords();
+    this.bytesInCollection = info.getNumOfBytes();
+
+    this.collectionLevelMetadata = new Vector();
+    {
+      corbatext_t[] names = info.getInfo().collectionMeta.names;
+      corbatext_t[] values = info.getInfo().collectionMeta.values;
+      for (int i = 0; i < names.length;i++) {
+	String thisname = NzdlCorbaFactory.toString(names[i]);
+	String thisvalue = NzdlCorbaFactory.toString(values[i]);
+	if (thisname == "collectionname")
+	  displayName = thisvalue;
+	if (thisname == "collectionextra")
+	  aboutText = thisvalue;
+	this.collectionLevelMetadata.add(new NamedValue(thisname,thisvalue));
+	System.err.println("Metadata: \"" + thisname + "\" = \"" + thisvalue + "\"");
+      }
+    }
+    this.building  = new Vector();
+    {
+      corbatext_t[] names = info.getInfo().building.names;
+      corbatext_t[] values = info.getInfo().building.values;
+      for (int i = 0; i < names.length;i++) {
+	String thisname = NzdlCorbaFactory.toString(names[i]);
+	String thisvalue = NzdlCorbaFactory.toString(values[i]);
+	this.building.add(new NamedValue(thisname,thisvalue));
+	System.err.println("Building: \"" + thisname + "\" = \"" + thisvalue + "\"");
+      }
+    }
+    this.format = new Vector();
+    {
+      corbatext_t[] names = info.getInfo().format.names;
+      corbatext_t[] values = info.getInfo().format.values;
+      for (int i = 0; i < names.length;i++) {
+	String thisname = NzdlCorbaFactory.toString(names[i]);
+	String thisvalue = NzdlCorbaFactory.toString(values[i]);
+	this.format.add(new NamedValue(thisname,thisvalue));
+	System.err.println("Format: \"" + thisname + "\" = \"" + thisvalue + "\"");
+      }
+    }
+  }
+
+
+
+  /**
+   * Tests...
+   *
+   * 
+   * @exception java.io.IOException when ...
+   * @param args the arguments ...
+   */
+
+  public static void main(String args[]) throws IOException
+  {
+  }
+}
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Document.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Document.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Document.java	(revision 21017)
@@ -0,0 +1,75 @@
+/*
+ *    TODO.java
+ *    Copyright (C) 2000 Stuart Yeates 
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl.hli;
+
+import org.nzdl.gsdl.service.*;
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+
+
+// java standard library classes used
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.Cloneable;
+
+/**
+ * Class ...
+ *
+ * Based on algorithms in ...
+ *
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see
+ * @see
+ * @see
+ * 
+ */
+
+public class Document implements Cloneable, Serializable
+{
+  /**
+   *
+   * 
+   * @exception java.io.IOException when ...
+   * @param arg2 ... 
+   * @param arg1 ...
+   * @return ...
+   * @see
+   * @see
+   */
+
+
+
+
+  /**
+   * Tests...
+   *
+   * 
+   * @exception java.io.IOException when ...
+   * @param args the arguments ...
+   */
+
+  public static void main(String args[]) throws IOException
+  {
+
+  }
+}
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Makefile
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Makefile	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Makefile	(revision 21017)
@@ -0,0 +1,31 @@
+#name/location of java compiler
+JAVAC=javac
+
+#javac options
+#JAVACOPTIONS= -g:none -O
+JAVACOPTIONS= -deprecation -g:lines
+
+#complete compilation
+JAVACOMPILE=$(JAVAC) $(JAVACOPTIONS)
+
+#make a .class file from a .java file
+%.class: %.java
+	$(JAVAC) $(JAVACOPTIONS)  $<
+
+CLASSFILES= Server.class\
+  Collection.class\
+  Document.class\
+  Query.class
+
+all: $(CLASSFILES)
+
+clean:
+	rm -f *.class
+
+
+
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Query.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Query.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Query.java	(revision 21017)
@@ -0,0 +1,131 @@
+/*
+ *    Query.java
+ *    Copyright (C) 2000 Stuart Yeates 
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl.hli;
+
+import org.nzdl.gsdl.service.*;
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+
+// java standard library classes used
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.Cloneable;
+import java.util.Vector;
+
+/**
+ * A high-level view of a Query
+ *
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see
+ * @see
+ * @see
+ * 
+ */
+
+public class Query implements Cloneable, Serializable
+{
+  /** */
+  Collection collection = null;
+
+  /** */
+  String queryString = "";
+  
+  /** */
+  Vector docIDs = new Vector();
+
+  /** */
+  Vector documents = new Vector();
+
+  /** */
+  long numberOfHits = 0;
+
+  /** */
+  String[] queryTerms = null;
+
+  /** */
+  long[] termTermFequencies = null;
+    
+  Query(Collection collection, String queryString) {
+    this.collection = collection;
+    this.queryString = queryString;
+  }
+
+  void runQuery() {
+    if (collection == null)
+      throw new Error ("null collection in runQuery");
+    if (queryString == null)
+      throw new Error ("null queryString in runQuery");
+    
+//      // create the argument objects 
+//      corbaFilterResponseHolder reposnse = 
+//        NzdlCorbaFactory.createFilterResponseHolder();
+//      corbaFilterRequest request = 
+//        NzdlCorbaFactory.createQueryFilterRequest( queryString );
+//      corbatext_t c_name = 
+//        NzdlCorbaFactory.toCorbaText( collection.getName() );
+//      corbaComErrorHolder c_err = 
+//        NzdlCorbaFactory.createComErrorHolder();
+    
+//      // run the actual query
+//      m_nzdlServer.filter( c_name, request, response, c_err );
+//      if (c_err.value.value() != 0)
+//        System.err.println("service() error " + c_err.value.value());  
+
+//      // parse the results
+//      numberOfHits = response.numDocs;
+    
+    
+  }
+  
+
+  
+
+
+
+  /**
+   *
+   * 
+   * @exception java.io.IOException when ...
+   * @param arg2 ... 
+   * @param arg1 ...
+   * @return ...
+   * @see
+   * @see
+   */
+
+
+
+
+  /**
+   * Tests...
+   *
+   * 
+   * @exception java.io.IOException when ...
+   * @param args the arguments ...
+   */
+
+  public static void main(String args[]) throws IOException
+  {
+
+  }
+}
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Server.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Server.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/hli/Server.java	(revision 21017)
@@ -0,0 +1,141 @@
+/*
+ *    Server.java
+ *    Copyright (C) 2000 Stuart Yeates 
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl.hli;
+
+import org.nzdl.gsdl.service.*;
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+
+
+// java standard library classes used
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.Cloneable;
+import java.util.Vector;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.Enumeration;
+
+/**
+ * A high level view of a digital library server.
+ *
+ *
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see Collection
+ * @see Document
+ * @see
+ */
+
+public class Server implements Cloneable, Serializable
+{
+  /** The host running the server. Currently broken. */
+  String host = "";
+  /** The host running the server. Currently broken. */
+  public String getHost() { return host; };
+  /** The host running the server. Currently broken. */
+  public void setHost(String str) { host = str; };
+
+  /** The Independant Object Reference for this Server */
+  String IOR = "";
+  /** The Independant Object Reference for this Server */
+  public String getIOR() { return IOR; };
+  /** The Independant Object Reference for this Server */
+  public void setIOR(String str) { IOR = str; };
+
+  /** The collections offered by this server */
+  Vector collections = null;
+  /** The collections offered by this server */
+  public Vector getCollections() {
+    return new Vector(collections);
+  }
+  /** The underlying interface */
+  NzdlService nzdl = null;
+
+  /** Initialise (or re-initialise) the Server */
+  public void update() {
+    //construct a new interface
+    if (IOR != null && IOR != "") 
+      nzdl = NzdlServiceFactory.createNzdlService(IOR);
+    if (nzdl == null)
+      throw new Error("Null NzdlService");
+
+    // clear the collection set
+    if (collections != null)
+      collections.clear();
+    collections = new Vector();
+
+    // restock the collection set
+    Set set = nzdl.getCollectionSet();
+    if (set == null)
+      throw new Error("getCollectionSet() returned null");
+    Iterator iter = set.iterator() ;
+    if (iter == null)
+      throw new Error("iterator() returned null");
+    while(iter.hasNext()) {
+      String name = (String) iter.next();
+      NzdlCollectionInfo info = nzdl.getCollectionInfo(name);
+      Collection collection = new Collection(this,name,info); 
+      collections.add(collection);
+    }
+  }
+
+  /** Find a collection based on it's name */
+  public Collection collectionForName(String name) {
+    Enumeration e =  collections.elements();
+    while(e.hasMoreElements()) {
+      Collection collection = (Collection) e.nextElement(); 
+      if (collection!= null && collection.getName().equals(name)) {
+	return collection;
+      }
+    }
+    return null;
+  }
+  /** Build a new Server */
+  public Server(NzdlService nzdl) {
+    this.nzdl = nzdl;
+    update();
+  }
+
+  /** Build a new Server */
+  public Server(String IOR) {
+    this.IOR = IOR;
+    update();
+  }
+
+  public static void main(String args[]) throws IOException
+  {
+    NzdlService nzdl= NzdlServiceFactory.findIOR(args,null,null,null,null);
+    Server server = new Server(nzdl); 
+  }
+
+}
+
+
+
+
+
+
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/package.html
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/package.html	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/package.html	(revision 21017)
@@ -0,0 +1,15 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.16-22 i686) [Netscape]">
+   <title>Utils Package</title>
+</head>
+<body bgcolor="#FFFFFF">
+Contains following classes: SearchAllCollections, SimpleClient
+(can be used to test the workings of the client-side interface) and SimpleServer
+(a basic Greenstone Server).
+<p>To run from the command prompt, type something like:
+<p><tt>cd java-client java org.nzdl.gsdl.SimpleClient -v 2 -Q</tt>
+</body>
+</html>
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/Makefile
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/Makefile	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/Makefile	(revision 21017)
@@ -0,0 +1,46 @@
+#name/location of java compiler
+JAVAC=javac
+
+#javac options
+#JAVACOPTIONS= -g:none -O
+#JAVACOPTIONS= -deprecation -g:lines
+
+#complete compilation
+JAVACOMPILE=$(JAVAC) $(JAVACOPTIONS)
+
+#make a .class file from a .java file
+%.class: %.java
+	$(JAVAC) $(JAVACOPTIONS)  $<
+
+CLASSFILES=NzdlCollectionInfo.class \
+	  NzdlDocumentInfo.class \
+          NzdlQuery.class \
+          NzdlQueryHit.class \
+          NzdlRequest.class \
+          NzdlResponse.class \
+          NzdlResultSet.class \
+          NzdlService.class \
+          NzdlServiceClient.class \
+          NzdlServiceServer.class \
+          NzdlWrapper.class \
+          NzdlLogWrapper.class \
+          NzdlDocSaveWrapper.class \
+          NzdlMultiWayWrapper.class \
+          NzdlCacheWrapper.class\
+          NzdlCrossCollectionWrapper.class \
+          NzdlBrowse.class \
+	  NzdlFilterOptions.class\
+	  NzdlFilterOption.class
+
+all: $(CLASSFILES)
+
+clean:
+	rm -f *.class
+
+
+
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlBrowse.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlBrowse.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlBrowse.java	(revision 21017)
@@ -0,0 +1,20 @@
+package org.nzdl.gsdl.service;
+
+public class NzdlBrowse 
+{ 
+	String OID, metadata;
+
+	public NzdlBrowse (String OID, String metadata)
+	{
+		this.OID = OID;
+		this.metadata = metadata;
+	}
+
+	public String getBrowseNode()
+	{	return this.OID;
+	}
+
+	public String getMetadata()
+	{	return this.metadata;
+	}
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlCacheWrapper.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlCacheWrapper.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlCacheWrapper.java	(revision 21017)
@@ -0,0 +1,167 @@
+/*
+ *    NzdlCacheWrapper.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.Hashtable;
+
+/* gsdl corba stuff */
+import org.nzdl.gsdl.corba.gsdlInterface.corbaFilterRequest;
+import org.nzdl.gsdl.util.NzdlCorbaFactory;
+
+/**
+ *  A Wrapper around an NzdlService object that adds functionality. 
+ *
+ * Typically one or more of the methods will be overridden to 
+ * add that functionality
+ *
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class NzdlCacheWrapper
+  extends NzdlWrapper implements java.io.Serializable{
+
+  private Hashtable _docs;
+  private Hashtable _collectionInfo;
+  private Hashtable _services;
+
+  /**
+   * The bean constructor ...
+   */  
+  public NzdlCacheWrapper() {
+    _docs = new Hashtable();
+    _collectionInfo = new Hashtable();
+    _services = new Hashtable();
+  }
+
+  /**
+   * The normal constructor ...
+   */  
+  public NzdlCacheWrapper(NzdlService service) {
+    super(service);
+    _docs = new Hashtable();
+    _collectionInfo = new Hashtable();
+    _services = new Hashtable();
+  }
+  
+  /**
+   * Wraps a getCollectionInfo with a cache check 
+   * to see if we've made the same call before ...
+   * @see NzdlService#getCollectionInfo
+   */
+  public NzdlCollectionInfo getCollectionInfo( String _name ) {
+    //System.err.println("in NzdlServiceCachingClient::getCollectionInfo()");
+    NzdlCollectionInfo info = null;
+    info = (NzdlCollectionInfo)_collectionInfo.get(_name);
+    if (info != null)
+      return info;
+    info = super.getCollectionInfo(_name);
+    _collectionInfo.put(_name,info);
+
+    //System.err.println("Cache miss (getCollectionInfo)");
+    return info;
+  }
+
+  /**
+   * Wraps a getDocument with a cache check 
+   * to see if we've made the same call before ...
+   * @see NzdlService#getDocument
+   */
+  public String getDocument( String _name, String _docID ) {
+    String doc = null;
+    String key = "" + _name + _docID;
+    doc = (String)_docs.get(key);
+    if (doc != null)
+      return doc;
+    doc = super.getDocument(_name,_docID);
+    _docs.put(key, doc);
+    
+    //System.err.println("Cache miss (getDocument) " + _name 
+    //	        + " " +_docID);
+    
+    return doc;
+  }
+
+  /**
+   * Wraps a service with a cache check 
+   * to see if we've made the same call before ...
+   * @see NzdlService#service
+   */
+  public void service( String _name, NzdlRequest _request, NzdlResponse _response ) {    
+    
+    String key = _name + corbaFilterRequestToString(_request);
+
+    if (_services.get(key) != null) {
+      _response.copyData((NzdlResponse) _services.get(key));
+      return;
+    }
+
+    super.service(_name, _request,_response);
+
+    _services.put(key, _response);
+    
+    //System.err.println("Cache miss (service)" + key);
+    return;
+  }
+  
+  /**
+   * Stringifies a NzdlRequest object so we can use it as a hash value
+   * @see NzdlRequest
+   */
+  protected String corbaFilterRequestToString(NzdlRequest nzdlrequest)
+  {
+    corbaFilterRequest request = nzdlrequest.getFilter();
+    StringBuffer buf = new StringBuffer(1000);
+    
+    String tmp = NzdlCorbaFactory.toString(request.filter);
+    buf.append(tmp).append('\uFFFF');
+    
+    for (int i = 0; i <request.filterOptions.length;i++){
+      tmp = NzdlCorbaFactory.toString(request.filterOptions[i].name);
+      buf.append(tmp).append('\uFFFF');
+      tmp = NzdlCorbaFactory.toString(request.filterOptions[i].value);
+      buf.append(tmp).append('\uFFFF');
+    }
+    
+    for (int i = 0; i <request.docSet.length;i++){
+      tmp = NzdlCorbaFactory.toString(request.docSet[i]);
+      buf.append(tmp).append('\uFFFF');
+    }
+    
+    buf.append(request.filterResultOptions).append('\uFFFF');
+
+    tmp = NzdlCorbaFactory.toString(request.requestParams);
+    buf.append(tmp).append('\uFFFF');
+    
+    tmp = NzdlCorbaFactory.toString(request.refParams);
+    buf.append(tmp).append('\uFFFF');
+    
+    for (int i = 0; i <request.fields.length;i++){
+      tmp = NzdlCorbaFactory.toString(request.fields[i]);
+      buf.append(tmp).append('\uFFFF');
+    }
+    
+    buf.append(request.getParents).append('\uFFFF');
+
+    return buf.toString();
+  }
+
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlCollectionInfo.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlCollectionInfo.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlCollectionInfo.java	(revision 21017)
@@ -0,0 +1,265 @@
+/*
+ *    NzdlCollectionInfo.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+/** gsdl corba stuff */
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+import java.util.*;
+
+/**
+ * An object that stores information on a collection. Information is obtained from
+ * {@link NzdlService NzdlService.getCollectionInfo(name)}
+ * Easily interrogated by a user.
+ *
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui    (amahoui@yahoo.com)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Dave Nichols   (daven@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @version $Revision$
+ */
+public class NzdlCollectionInfo extends Object {
+
+  private corbaColInfoResponse m_Info = null;
+    private HashMap metaMap;
+
+  /**
+   * Create an instance of NzdlCollectionInfo.
+   */
+    public NzdlCollectionInfo( corbaColInfoResponse _info ) {
+	m_Info = _info;
+	metaMap = new HashMap();
+
+	if (!getHTTPDomain().equals(""))
+	    System.out.println("getHTTPDomain working !");
+	if (!getName().equals(""))
+	    System.out.println("getName working !");
+	if (!getHostName().equals(""))
+	    System.out.println("getHostName working !");
+
+	for (int i=0;i< m_Info.collectionMeta.names.length; i++) {
+	    metaMap.put( NzdlCorbaFactory.toString(m_Info.collectionMeta.names[i]), NzdlCorbaFactory.toString(m_Info.collectionMeta.values[i]));
+	    //System.err.println(NzdlCorbaFactory.toString(m_Info.collectionMeta.values[i]));
+	}
+
+    }
+
+  /**
+   * Returns the corbaInfoResponse.
+   */
+  public corbaColInfoResponse getInfo(){
+    return m_Info;
+  }
+
+  /**
+   * Returns the name of a collection. <br>
+   * Pre: Created instance of NzdlCollectionInfo. Used
+   * {@link NzdlService NzdlService.getCollectionInfo(name)}
+   * to extract collection information.
+   * @return A string representing the name of the collection.
+   */
+  public String getName() {
+    return NzdlCorbaFactory.toString( m_Info.shoftInfo.name ) ;
+  }
+  /**
+   * Return the Hostname
+   */
+  public String getHostName() {
+    return NzdlCorbaFactory.toString( m_Info.shoftInfo.host ) ;
+  }
+  /**
+   * Returns HTTP Prefix
+   */
+  public String getHTTPPrefix() {
+    //return m_Info.httpprefix.text.toString();
+     return NzdlCorbaFactory.toString( m_Info.httpprefix ) ;
+  }
+
+  /**
+   * Returns HTTP Domain
+   */
+  public String getHTTPDomain() {
+    return NzdlCorbaFactory.toString( m_Info.httpdomain ) ;
+  }
+
+  /**
+   * Returns reseptionist
+   */
+  public String getReceptionist() {
+    return NzdlCorbaFactory.toString( m_Info.receptionist ) ;
+  }
+
+  /**
+   * Returns true if collection is public. <br>
+   * Pre: Created instance of NzdlCollectionInfo. Used
+   * {@link NzdlService NzdlService.getCollectionInfo(name)}
+   * to extract collection information.
+   * @return Boolean true if collection is public, otherwise returns false.
+   */
+  public boolean isPublic() {
+    return m_Info.isPublic;
+  }
+
+  /**
+   * Returns true if collection is a beta version. <br>
+   * Pre: Created instance of NzdlCollectionInfo. Used
+   * {@link NzdlService NzdlService.getCollectionInfo(name)}
+   * to extract collection information.
+   * @return Boolean true if collection is a beta version, otherwise returns false.
+   */
+  public boolean isBeta() {
+    return m_Info.isBeta;
+  }
+
+  /**
+   * Returns an integer representation of build date. <br>
+   * Pre: Created instance of NzdlCollectionInfo. Used
+   * {@link NzdlService NzdlService.getCollectionInfo(name)}
+   * to extract collection information.
+   * @return Integer representation of date.
+   */
+  public long getBuildDate() {
+    return m_Info.buildDate;
+  }
+
+  /**
+   * Returns the number of documents in a collection. <br>
+   * Pre: Created instance of NzdlCollectionInfo. Used
+   * {@link NzdlService NzdlService.getCollectionInfo(name)}
+   * to extract collection information.
+   * @return An integer representing the number of documents in the collection.
+   */
+  public long getNumOfDocs() {
+    return m_Info.numDocs;
+  }
+
+  /**
+   * Returns the number of words in a collection. <br>
+   * Pre: Created instance of NzdlCollectionInfo. Used
+   * {@link NzdlService NzdlService.getCollectionInfo(name)}
+   * to extract collection information.
+   * @return An integer representing the number of words in the collection.
+   */
+  public long getNumOfWords() {
+    return m_Info.numWords;
+  }
+
+  /**
+   * Returns the number of bytes in the collection. <br>
+   * Pre: Created instance of NzdlCollectionInfo. Used
+   * {@link NzdlService NzdlService.getCollectionInfo(name)}
+   * to extract collection information.
+   * @return An integer representing the number of bytes in the collection.
+   */
+  public long getNumOfBytes() {
+    return m_Info.numBytes;
+  }
+
+  /**
+   * Returns a string describing collection details. <br>
+   * Pre: Created instance of NzdlCollectionInfo. Used
+   * {@link NzdlService NzdlService.getCollectionInfo(name)}
+   * to extract collection information.
+   * @return A string describing collection details such as: collection name;
+   * isPublic; isBeta; buildDate; numOfDocs; numOfWords; numOfBytes
+   */
+  public String toString() {
+    StringBuffer buf = new  StringBuffer(1000);
+    buf.append("coll name=\"").append(getName());
+    buf.append("\" isPublic=").append(isPublic());
+    buf.append(" isBeta=").append(isBeta());
+    buf.append(" buildDate=").append(getBuildDate());
+    buf.append(" numOfDocs=").append(getNumOfDocs());
+    buf.append(" numOfWords=").append(getNumOfWords());
+    buf.append(" numOfBytes=").append(getNumOfBytes());
+    return buf.toString();
+  }
+
+  /**
+   * Not currently implemented
+   */
+  public void print() {
+	/* daven@cs.waikato.ac.nz */
+	//System.out.println("Collection Information--------------");
+	//System.out.println("Collection Name = " + this.getName());
+	//System.out.println("Collection Name = " + m_info.getName());
+	
+  }
+
+
+    
+
+    /* return the metadata Map */
+
+    public Map getCollectionMetaData() {
+	return metaMap;
+    }
+
+
+    public boolean isCollectionDescription() {
+	return metaMap.containsKey(NzdlConstants.COLLECTION_DESCRIPTION);
+    }
+
+    /* this is currently leaving \n in the text whereas the 
+       version using nzdlService.getMetaData doesn't,
+       try the tcc description text to see an example,
+       something to do with the use of CorbaFactory method 
+       in the constructor is not quite right - Stuart will 
+       know what is wrong   -  Dave */
+
+    public String getCollectionDescription() {
+	return (String) metaMap.get(NzdlConstants.COLLECTION_DESCRIPTION);
+    }
+
+    public boolean isCollectionIcon() {
+	return metaMap.containsKey(NzdlConstants.ICON);
+    }
+
+    public String getCollectionIcon() {
+	return (String) metaMap.get(NzdlConstants.ICON);
+    }
+
+    public boolean isCollectionSmallIcon() {
+	return metaMap.containsKey(NzdlConstants.SMALL_ICON);
+    }
+
+    public String getCollectionSmallIcon() {
+	return (String) metaMap.get(NzdlConstants.SMALL_ICON);
+    }
+
+    public boolean isLongCollectionName() {
+	return metaMap.containsKey(NzdlConstants.LONG_COLLECTION_NAME);
+    }
+
+    public String getLongCollectionName() {
+	return (String) metaMap.get(NzdlConstants.LONG_COLLECTION_NAME);
+    }
+
+}
+
+
+
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlCrossCollectionWrapper.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlCrossCollectionWrapper.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlCrossCollectionWrapper.java	(revision 21017)
@@ -0,0 +1,356 @@
+/*
+ *    NzdlMultiWayWrapper.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.io.Writer;
+import java.io.FileWriter;
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.NzdlServiceFactory;
+import org.nzdl.gsdl.util.NzdlPreferences;
+
+
+/**
+ * A NzdlCrossCollectionWrapper is a wrapper around one or 
+ * more Collections to make them appear as a single collection.
+ *
+ * NzdlCrossCollectionWrapper assumes that docIDs are unique. 
+ * If they aren't, some _very_ strange things are going to 
+ * happen...
+ *
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @see org.nzdl.gsdl.service.NzdlCollectionInfo
+ * @version $Revision$
+ */
+public class NzdlCrossCollectionWrapper
+  extends NzdlWrapper {
+
+  Set collectionSet;
+  String collectionName;
+  /** 
+   * The bean constructor ...
+   */
+  public NzdlCrossCollectionWrapper() {
+    super(null);
+  }
+  /** 
+   * The normal constructor
+   */
+  public NzdlCrossCollectionWrapper(NzdlService server, 
+				    Set collectionSet,
+				    String collectionName) {
+    super(server);
+    this.collectionSet = collectionSet;
+    this.collectionName = collectionName;
+  }
+  /** 
+   * The normal constructor
+   */
+  public NzdlCrossCollectionWrapper(NzdlService server, 
+				    String substring) {
+    super(server);
+    
+    Set collections = super.getCollectionSet();
+
+    if (collections.size() == 0) {
+      System.err.println("NzdlCrossCollectionWrapper found no collections.");
+      this.collectionSet = new HashSet();
+      this.collectionName = ":::NoCoLlEcTiOn:::";
+      return;
+    }
+    
+    if (substring == null || substring == "") {
+      this.collectionSet = collections;
+      this.collectionName = "Union Collection";
+      System.err.println("NzdlCrossCollectionWrapper init1 collcount: " 
+			 + collectionSet.size());
+    } else {
+      Set allCollections = collections;
+      Set ourCollections = new HashSet();
+      
+      Iterator iter = collectionSet.iterator();      
+      while(iter.hasNext()) {
+	String coll = (String) iter.next();
+	// handle the case that we've talking via a NzdlMultiWayWrapper
+	String collname = NzdlMultiWayWrapper.findCollection(coll);
+	if (collname.startsWith(substring))
+	  if (collname.indexOf("nuipepa") == -1)
+	    ourCollections.add(coll);
+      }
+      this.collectionSet = ourCollections;
+      this.collectionName = "\"" + substring + "\" Union Collection";
+      System.err.println("NzdlCrossCollectionWrapper init2 collcount: " 
+			 + collectionSet.size());
+    }
+  }
+ 
+  /**
+   * Allow the client to configure a CORBA server.
+   * @param key the parameter to be set.
+   * @param values what that parameter will be set to.
+   */
+  public void configure( String _key, Set _values ) {
+    super.configure(_key, _values);
+  }
+
+  /**
+   * Obtain the set of collection names for a Greenstone library.
+   * @return A set of collection names in string format.
+   */
+  public Set getCollectionSet( ) {
+    System.err.println("in getCollectionSet " + this.collectionName);
+    Set result = super.getCollectionSet();
+    result.add(this.collectionName);
+    System.err.println("getCollectionSet done " + this.collectionName);
+    return result;
+  }
+
+  /**
+   * Check if ORB knows of this collection.
+   * @param name the name of a collecion to be searched for.
+   * @return boolean <TT>true</TT> if collection is found, else <TT>false</TT>.
+   */
+  public boolean hasCollection( String _name ) {
+    if (_name.equalsIgnoreCase(collectionName))
+      return true;
+    else
+      return  super.hasCollection(_name);
+  }
+
+
+  /**
+   * Check if ORB can communicate with of this collection.
+   * @param name the name of a collecion to be pinged.
+   * @return boolean <TT>true</TT> if collection returned ping, else
+   * <TT>false</TT>.
+   */
+  public boolean pingCollection( String _name ) {
+    if (_name.equalsIgnoreCase(collectionName))
+      return true;
+    else 
+      return super.pingCollection(_name);
+  }
+
+  /**
+   * Extract information on this collection into a
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} object
+   * @param name the collection to be retrieved.
+   * @return an instance of
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} containing data on a
+   * collection
+   */
+  public NzdlCollectionInfo getCollectionInfo( String _name ) {
+    if (_name.equalsIgnoreCase(collectionName)) {
+      corbaColInfoResponse fake = new corbaColInfoResponse();
+      
+      Iterator iter = collectionSet.iterator();      
+      while(iter.hasNext()) {
+	String collectionName = (String) iter.next();
+	NzdlCollectionInfo info = super.getCollectionInfo(collectionName);
+	corbaColInfoResponse real = info.getInfo();
+	fake.numDocs += real.numDocs;
+	fake.numWords += real.numWords;
+	fake.numBytes += real.numBytes;
+	fake.isPublic = real.isPublic;
+	fake.isBeta = real.isBeta;
+	fake.ccsCols = real.ccsCols;
+	fake.languages = real.languages;
+	fake.collectionMeta = real.collectionMeta;
+	fake.format = real.format;
+	fake.building = real.building;
+	fake.httpdomain = real.httpdomain;
+	fake.httpprefix = real.httpprefix;
+      }
+      
+      fake.buildDate = 1;
+      
+      return new NzdlCollectionInfo(fake);
+    } else {
+      return super.getCollectionInfo(_name);
+    }
+  }
+  
+  /**
+   * Returns the set of filters for the service object.
+   * @param name the collection name
+   * @return a set of strings that name the filters, for example
+   * BrowseFilter, QueryFilter and NullFilter.
+   */
+  public Set getFilterSet( String _name ) {
+    if (_name.equalsIgnoreCase(collectionName)) {
+      Set results = new HashSet();
+      Iterator iter = collectionSet.iterator();      
+      while(iter.hasNext()) {
+	String collectionName = (String) iter.next();
+	results.addAll(super.getFilterSet(collectionName));
+      }
+      return results;
+    } else {
+      return super.getFilterSet(_name);
+    }
+  }
+
+  /**
+   * @param name the collection name
+   * @return the Set of (name, value) value pairs for all metadata 
+   * associated with a collection  
+   */
+  public Set getMetaTagSet( String _name ) {
+    if (_name.equalsIgnoreCase(collectionName)) {
+      Set results = new HashSet();
+      Iterator iter = collectionSet.iterator();      
+      while(iter.hasNext()) {
+	String collectionName = (String) iter.next();
+	results.addAll(super.getMetaTagSet(collectionName));
+      }
+      return results;
+    } else {
+      return super.getMetaTagSet(_name);
+    }
+  }
+
+  /**
+   * Returns the Greenstone Markup Language (GML) text for a particular
+   * document from a collection.
+   * @param name the name of the collection.
+   * @param docID the document identity string
+   * @return the GML document in the form of a string.
+   */
+  public String getDocument( String _name, String _docID ) {
+    if (_name.equalsIgnoreCase(collectionName)) {
+      String results = new String();
+      Iterator iter = collectionSet.iterator();      
+      while(iter.hasNext()) {
+	String collectionName = (String) iter.next();
+	results = results + super.getDocument(collectionName, _docID);
+      }
+      return results;
+    } else {
+      return super.getDocument(_name,_docID);
+    }
+  }
+
+  /**
+   * Returns the set of value(s) for a metatag from a particular document.
+   * @param name collection name
+   * @param docID the document identifier.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The set of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Set getMetaData( String _name, String _docID, String _metaTag ) {
+    if (_name.equalsIgnoreCase(collectionName)) {
+      Set results = new HashSet();
+      Iterator iter = collectionSet.iterator();      
+      while(iter.hasNext()) {
+	String collectionName = (String) iter.next();
+	results.addAll(super.getMetaData(collectionName,_docID,_metaTag));
+      }
+      return results;
+    } else {
+      return super.getMetaData(_name,_docID,_metaTag);
+    }
+  }
+
+  /**
+   * Returns a map of value(s) for a metatag from a list of documents.
+   * @param name collection name
+   * @param docIDs a list of document identifier strings.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The map of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Map getMetaData( String _name, List _docIDs, String _metaTag ) {
+    if (_name.equalsIgnoreCase(collectionName)) {
+      Map results = new HashMap();
+      Iterator iter = collectionSet.iterator();      
+      while(iter.hasNext()) {
+	String collectionName = (String) iter.next();
+	results.putAll(super.getMetaData(collectionName,_docIDs,_metaTag));
+      }
+      return results;
+    } else {
+      return super.getMetaData(_name,_docIDs,_metaTag);
+    }
+  }
+
+
+  corbaTermInfo[] concat(corbaTermInfo[] first, corbaTermInfo[] second) {
+    corbaTermInfo[] result = 
+      new corbaTermInfo[first.length + second.length];
+    for (int i = 0;i<first.length;i++) 
+      result[i] = first[i];
+    for (int i = 0;i<second.length;i++) 
+      result[first.length+ i] = second[i];
+    return result;
+  }
+
+  corbaResultDocInfo[] concat(corbaResultDocInfo[] first, corbaResultDocInfo[] second) {
+    corbaResultDocInfo[] result = 
+      new corbaResultDocInfo[first.length + second.length];
+    for (int i = 0;i<first.length;i++) 
+      result[i] = first[i];
+    for (int i = 0;i<second.length;i++) 
+      result[first.length+ i] = second[i];
+    return result;
+  }
+
+  /**
+   * Services a {@link NzdlRequest NzdlRequest} to a collection and places
+   * the results into a {@link NzdlResponse NzdlResponse} object. <br>
+   * Pre:   Created instances of NzdlRequest and NzdlResponse. <br>
+   * Post: Placed the result data into NzdlResponse object.
+   * @param name the collection name.
+   * @param request an instance of NzdlRequest with query data to be serviced
+   * @param response an instance of NzdlResponse. where the results of
+   * sevciving the query will be placed
+   */
+  public void service( String _name, NzdlRequest _request, 
+		       NzdlResponse _response ) {    
+    if (_name.equalsIgnoreCase(collectionName)) {
+      corbaFilterResponse fake = new corbaFilterResponse();
+      Iterator iter = collectionSet.iterator();      
+      while(iter.hasNext()) {
+	String collectionName = (String) iter.next();
+	NzdlResponse response = new NzdlResponse();
+	super.service(collectionName,_request,response);
+	fake.numDocs = fake.numDocs + response.getResponse().numDocs;
+	fake.termInfo = concat(fake.termInfo,response.getResponse().termInfo);
+	fake.docInfo = concat(fake.docInfo,response.getResponse().docInfo);
+	_response.setResponse(fake);
+      }
+    } else {
+       super.service(_name,_request,_response);
+    }
+  }  
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlDocSaveWrapper.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlDocSaveWrapper.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlDocSaveWrapper.java	(revision 21017)
@@ -0,0 +1,93 @@
+/*
+ *    NzdlDocSaveWrapper.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.io.File;
+import java.io.FileWriter;
+
+/* gsdl corba stuff */
+import org.nzdl.gsdl.corba.gsdlInterface.corbaFilterRequest;
+import org.nzdl.gsdl.util.NzdlCorbaFactory;
+
+/**
+ *  A Wrapper around an NzdlService object that adds functionality. 
+ *
+ * Typically one or more of the methods will be overridden to 
+ * add that functionality
+ *
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class NzdlDocSaveWrapper
+  extends NzdlWrapper {
+
+  static String dirPath = "/tmp/docs/";
+
+  /**
+   * The bean constructor ...
+   */  
+  public NzdlDocSaveWrapper() {
+  }
+
+  /**
+   * The normal constructor ...
+   */  
+  public NzdlDocSaveWrapper(NzdlService service) {
+    super(service);
+    try {
+      File directory = new File(dirPath);
+      if (!directory.exists())
+	directory.mkdirs();
+    }  catch (Exception exception) {
+      System.err.println("unable to create directory: " + exception);
+    } 
+  }
+  
+  /**
+   * Wraps a getDocument and saves to disk any documents we see ...
+   * @see NzdlService#getDocument
+   */
+  public String getDocument( String _name, String _docID ) {
+    
+    String doc =  super.getDocument(_name,_docID);
+    
+    try {
+      File dir = new File(dirPath, _name);
+      if (!dir.exists())
+	dir.mkdirs();
+      File file = new File(dir, _docID);
+      if (!file.exists()) {
+	FileWriter writer = new FileWriter(file);
+	writer.write("<gsdlsection>");
+	writer.write(doc);
+	writer.write("</gsdlsection>");
+	writer.flush();
+	writer.close();
+      }
+    } catch (Exception exception) {
+      System.err.println("Exception: " + exception);
+    } 
+    
+    return doc;
+  }
+
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlDocumentInfo.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlDocumentInfo.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlDocumentInfo.java	(revision 21017)
@@ -0,0 +1,134 @@
+/*
+ *    NzdlDocumentInfo.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+/** gsdl corba stuff */
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+import java.util.*;
+
+/**
+ * An object that stores information on a collection. Information is obtained from
+ * {@link NzdlService NzdlService.getDocumentInfo(name)}
+ * Easily interrogated by a user.
+ *
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui    (amahoui@yahoo.com)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Dave Nichols   (daven@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @version $Revision$
+ */
+public class NzdlDocumentInfo extends Object {
+
+  private Vector keys = new Vector();
+  private Vector values = new Vector();
+
+  /**
+   * Create an instance of NzdlDocumentInfo.
+   */
+  public NzdlDocumentInfo(NzdlService nzdl, 
+			  String  collectionName,
+			  String docID ) {
+    String[] fields= { 
+      "Audio",
+      "Author",
+      "Creator",
+      "Date",
+      "DateText",
+      "DocIcon",
+      "Encoding",
+      "Filename",
+      "FiltText",
+      "From",
+      "GENERATOR",
+      "Generator",
+      "Headers",
+      "Howto",
+      "Identifier",
+      "Image",
+      "Issue",
+      "Language",
+      "Link",
+      "Magazine",
+      "Organization",
+      "Page" ,
+      "Series",
+      "Source",
+      "Subject",
+      "Template",
+      "Title", 
+      "To",
+      "Type", 
+      "URL",
+      "first200",
+      "first100",
+      "gsdlassocfile",
+      "gsdldoctype",
+      "gsdlnum", 
+      "gsdlsourcefilename",
+      "href",
+      "srcicon",
+      "srclink"
+    };
+
+    for(int i=0;i<fields.length;i++) {
+     
+      Set set = nzdl.getMetaData( collectionName, docID, fields[i] );
+      Iterator iterator = set.iterator();
+      while(iterator.hasNext()) {
+	String value = (String) iterator.next();
+	if (value != null && value != "" && value.length() > 0) {
+	  keys.add(fields[i]);
+	  values.add(value);
+	}
+      }
+    }
+  }
+
+/**
+ * Returns all metadata keys for each metadata value in the document.
+ * Each item returned corresponds to a value in the 'values' Vector.
+ *  The keys may include such Strings as title, author, creator etc.
+ * Where there is more than one instance of a metadata value (for
+ * example, if there are two authors) then two author keys will be
+ * produced each corresponding to an author name in the values Vector.
+ * @return an enumerated set of key strings
+ */
+  public Enumeration getKeys() {return keys.elements();};
+
+
+ /**
+ * Returns all metadata values in the document.
+ * Each item returned corresponds to a key in the 'keys' Vector.
+ *  The keys may include such Strings as title, author, creator etc.
+ * @return an enumerated set of value strings
+ */
+  public Enumeration getValues() {return values.elements();};
+}
+
+
+
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlFilterOption.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlFilterOption.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlFilterOption.java	(revision 21017)
@@ -0,0 +1,69 @@
+/*
+ *    NzdlFilterOption.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+/** gsdl corba stuff */
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+import java.util.*;
+
+/**
+ * The FilterOption object
+ *
+ * @author Katherine Don (kjdon@cs.waikato.ac.nz)
+ * 
+ */
+
+public class NzdlFilterOption extends Object {
+
+    public String name=null;
+    public int type=-1;
+    public int repeatable=-1;
+    public String defaultValue=null;
+    public List validValues=null;
+
+    private void initialise() {
+	validValues = new ArrayList();
+    }
+
+    /**
+     * creates an empty FilterOption
+     */
+    public NzdlFilterOption() {
+	initialise();
+    }
+    /**
+     * creates a FilterOption from a corbaFilterOption
+     */
+    public NzdlFilterOption(corbaFilterOption _filt) {
+	initialise();
+
+	name = NzdlCorbaFactory.toString(_filt.name);
+	type = _filt.type.value();
+	repeatable = _filt.repeatable.value();
+	defaultValue = NzdlCorbaFactory.toString(_filt.defaultValue);
+	
+	for (int i=0; i<_filt.validValues.length; i++) {
+	    validValues.add(NzdlCorbaFactory.toString(_filt.validValues[i]));
+	}
+	
+    }
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlFilterOptions.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlFilterOptions.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlFilterOptions.java	(revision 21017)
@@ -0,0 +1,77 @@
+/*
+ *    NzdlFilterOptions.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+/** gsdl corba stuff */
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+import java.util.*;
+
+/**
+ * An object that returns the filter options for a particular filter. Information is obtained from
+ * {@link NzdlService NzdlService.getFilterOptionSet(name, filter)}
+ * 
+ * @author Katherine Don (kjdon@cs.waikato.ac.nz)
+ * 
+ */
+
+public class NzdlFilterOptions extends Object {
+
+  private corbaFilterOptionsResponse m_FilterOps = null;
+    private HashMap optionMap;
+  /**
+   * Create an instance of NzdlFilterOptions.
+   */
+    public NzdlFilterOptions( corbaFilterOptionsResponse _filt ) {
+	m_FilterOps = _filt;
+	optionMap = new HashMap();
+
+	for (int i=0;i< m_FilterOps.names.length; i++) {
+	   
+	    optionMap.put( NzdlCorbaFactory.toString(m_FilterOps.names[i]), new NzdlFilterOption(m_FilterOps.options[i]));
+	       
+	}
+    }
+
+  /**
+   * Returns the corbaFilterOptionsResponse.
+   */
+  public corbaFilterOptionsResponse getInfo(){
+    return m_FilterOps;
+  }
+    /** returns the FilterOption with name _name*/
+    public NzdlFilterOption getFilterOption(String _name) {
+	return (NzdlFilterOption) optionMap.get(_name);
+    }
+
+    /** returns true if there is a FilterOption called _name*/
+    public boolean hasOption(String _name) {
+	return optionMap.containsKey(_name);
+    }
+}
+
+
+
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlLogWrapper.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlLogWrapper.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlLogWrapper.java	(revision 21017)
@@ -0,0 +1,273 @@
+/*
+ *    NzdlWrapper.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.Date;
+import java.io.Writer;
+import java.io.FileWriter;
+
+
+/**
+ *  A Wrapper around an NzdlService object that adds logging functionality. 
+ *
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+public class NzdlLogWrapper
+  extends NzdlWrapper {
+
+  Writer logFile = null;
+  String tag = "NzdlLogWrapper: ";
+  boolean calculateDiff = true;
+  boolean logBefore = false;
+  boolean logAfter = false;
+  Date whenCallStarted = null;
+   
+
+  /** 
+   * The bean constructor ...
+   */
+  public NzdlLogWrapper() {
+  }
+  /** 
+   * The normal constructor
+   */
+  public NzdlLogWrapper(NzdlService nzdl, String logFilename, 
+			String tag) {
+    super(nzdl);
+    this.tag = tag;
+    try {
+      Date date = new Date();
+      // the true is append ...
+      String dir = System.getProperties().getProperty("user.home");
+      String sep = System.getProperties().getProperty("file.separator");
+      logFile = new FileWriter(dir+sep+logFilename, true);
+      logFile.write(tag + "Log started at:" + date + " == " + 
+		    date.getTime() + "\n");
+      logFile.write(tag + "timestamps in milliseconds since January 1, 1970, 00:00:00 GMT \n");
+      logFile.flush();
+    } catch (Exception exception) {
+      System.err.println("unable to create log file:" + exception);
+    }    
+  }
+
+  protected void logBefore(String method) {
+    if (whenCallStarted != null)
+      throw new Error ("synchronisation required ! (whenCallStarted != null)");
+    whenCallStarted = new Date();
+    if (logBefore)
+      try {
+	logFile.write(this.tag + "before " + method + "() " + 
+		      whenCallStarted.getTime() + "\n");
+	logFile.flush();
+      } catch (Exception exception) {
+	System.err.println("unable to write log file:" + exception);
+      } 
+  }
+   
+  protected void logAfter(String method) {
+    if (whenCallStarted == null)
+      throw new Error ("synchronisation required ! (whenCallStarted == null)");
+    Date now = new Date();
+    try {
+      if (logAfter)
+	logFile.write(this.tag + "after " + method + "() " + 
+		      whenCallStarted.getTime() + "\n");
+      if (calculateDiff)
+	logFile.write(this.tag + "time for  " + method + "() " + 
+		      (now.getTime() -whenCallStarted.getTime()) + "ms\n");
+      logFile.flush();
+    } catch (Exception exception) {
+      System.err.println("unable to write log file:" + exception);
+    } 
+    whenCallStarted = null;
+  }
+   
+  /**
+   * Allow the client to configure a CORBA server.
+   * @param key the parameter to be set.
+   * @param values what that parameter will be set to.
+   */
+  public void configure( String _key, Set _values ) {
+    logBefore("configure");
+    super.configure(_key, _values);
+    logAfter("configure");
+  }
+
+  /**
+   * Obtain the set of collection names for a Greenstone library.
+   * @return A set of collection names in string format.
+   */
+  public Set getCollectionSet( ) {
+    logBefore("getCollectionSet");
+    Set result = super.getCollectionSet();
+    logAfter("getCollectionSet");
+    return result;
+  }
+
+  /**
+   * Check if ORB knows of this collection.
+   * @param name the name of a collecion to be searched for.
+   * @return boolean <TT>true</TT> if collection is found, else <TT>false</TT>.
+   */
+  public boolean hasCollection( String _name ) {
+    logBefore("hasCollection");
+    boolean result = super.hasCollection(_name);
+    logAfter("hasCollection");
+    return result;
+  }
+
+
+  /**
+   * Check if ORB can communicate with of this collection.
+   * @param name the name of a collecion to be pinged.
+   * @return boolean <TT>true</TT> if collection returned ping, else
+   * <TT>false</TT>.
+   */
+  public boolean pingCollection( String _name ) {
+    logBefore("pingCollection");
+    boolean result = super.pingCollection(_name);
+    logAfter("pingCollection");
+    return result;
+  }
+
+  /**
+   * Extract information on this collection into a
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} object
+   * @param name the collection to be retrieved.
+   * @return an instance of
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} containing data on a
+   * collection
+   */
+  public NzdlCollectionInfo getCollectionInfo( String _name ) {
+    logBefore(" getCollectionInfo");
+    NzdlCollectionInfo  result = super.getCollectionInfo(_name);
+    logAfter(" getCollectionInfo");
+    return result;
+  }
+
+  /**
+   * Returns the set of filters for the service object.
+   * @param name the collection name
+   * @return a set of strings that name the filters, for example
+   * BrowseFilter, QueryFilter and NullFilter.
+   */
+  public Set getFilterSet( String _name ) {
+    logBefore("getFilterSet");
+    Set result = super.getFilterSet(_name);
+    logAfter("getFilterSet");
+    return result;
+  }
+
+  /**
+   * Returns the set of filter options for a particular filter
+   * @param name the collection name
+   * @param filter the filter name, eg QueryFilter
+   * @return an instance of
+   * {@link NzdlFilterOptions NzdlFilterOptions} containing the filter
+   * options for a filter
+   */
+  public NzdlFilterOptions getFilterOptionSet(String _name, String _filter) {
+      logBefore("getFilterOptionSet");
+      NzdlFilterOptions result = super.getFilterOptionSet(_name, _filter);
+      logAfter("getFilterOptionSet");
+      return result;
+  }
+  /**
+   * @param name the collection name
+   * @return the Set of (name, value) value pairs for all metadata 
+   * associated with a collection  
+   */
+  public Set getMetaTagSet( String _name ) {
+    logBefore("getMetaTagSet");
+    Set result = super.getMetaTagSet(_name);
+    logAfter("getMetaTagSet");
+    return result;
+  }
+
+  /**
+   * Returns the Greenstone Markup Language (GML) text for a particular
+   * document from a collection.
+   * @param name the name of the collection.
+   * @param docID the document identity string
+   * @return the GML document in the form of a string.
+   */
+  public String getDocument( String _name, String _docID ) {
+    logBefore("getDocument");
+    String result = super.getDocument(_name, _docID);
+    logAfter("getDocument");
+    return result;
+  }
+
+  /**
+   * Returns the set of value(s) for a metatag from a particular document.
+   * @param name collection name
+   * @param docID the document identifier.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The set of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Set getMetaData( String _name, String _docID, String _metaTag ) {
+    logBefore("getMetaData");
+    Set result = super.getMetaData( _name, _docID, _metaTag );
+    logAfter("getMetaData");
+    return result;
+  }
+
+  /**
+   * Returns a map of value(s) for a metatag from a list of documents.
+   * @param name collection name
+   * @param docIDs a list of document identifier strings.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The map of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Map getMetaData( String _name, List _docIDs, String _metaTag ) {
+    logBefore("getMetaData");
+    Map result = super.getMetaData( _name, _docIDs, _metaTag );
+    logAfter("getMetaData");
+    return result;
+  }
+
+  /**
+   * Services a {@link NzdlRequest NzdlRequest} to a collection and places
+   * the results into a {@link NzdlResponse NzdlResponse} object. <br>
+   * Pre:   Created instances of NzdlRequest and NzdlResponse. <br>
+   * Post: Placed the result data into NzdlResponse object.
+   * @param name the collection name.
+   * @param request an instance of NzdlRequest with query data to be serviced
+   * @param response an instance of NzdlResponse. where the results of
+   * sevciving the query will be placed
+   */
+  public void service( String _name, NzdlRequest _request, 
+		       NzdlResponse _response ) {    
+    logBefore("service");
+    super.service(_name,_request,_response);
+    logAfter("service");
+  }
+  
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlMultiWayWrapper.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlMultiWayWrapper.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlMultiWayWrapper.java	(revision 21017)
@@ -0,0 +1,296 @@
+/*
+ *    NzdlMultiWayWrapper.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.io.Writer;
+import java.io.FileWriter;
+import org.nzdl.gsdl.util.NzdlServiceFactory;
+import org.nzdl.gsdl.util.NzdlPreferences;
+
+
+/**
+ * A NzdlMultiWayWrapper is a wrapper around multiple NzdlServices. 
+ * It attempts to connect to as many servers as possible and present 
+ * them to the user a single collection.
+ *
+ * When two collections are found to be the same, then only the 
+ * collection with the fastest response time for a getCollectionInfo()
+ * call is added.
+ *
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @see org.nzdl.gsdl.service.NzdlCollectionInfo
+ * @version $Revision$
+ */
+public class NzdlMultiWayWrapper
+  extends NzdlWrapper {
+
+  Hashtable services;
+   
+  /** 
+   * The bean constructor ...
+   */
+  public NzdlMultiWayWrapper() {
+    super(null);
+    services = new Hashtable();
+  }
+  /** 
+   * The normal constructor
+   */
+  public NzdlMultiWayWrapper(String [] _args,
+			     Properties _props,
+			     String _URL,
+			     String _filename,
+			     String _IOR) {
+    super(null);
+    services = new Hashtable();
+
+    NzdlPreferences.saving = false;
+
+    Hashtable servers = NzdlServiceFactory.findIORs(_args,_props,_URL,_filename,_IOR);
+    
+    Enumeration e = servers.keys() ;
+    for (int i = 0; e.hasMoreElements(); i++) {
+      String key = (String)  e.nextElement();
+      NzdlService server = (NzdlService) servers.get(key);
+      
+      if (NzdlPreferences.getBoolean("Log at the NzdlService level"))
+	server = new NzdlLogWrapper(server, 
+				    "log.file.after.split." + i + ".cache", 
+				    "AFTER:" + key + ": ");
+      services.put("" +i, server);
+    }
+  }
+
+  static String findServer(String _name) {
+    int separator = _name.indexOf(':');   
+    String result = _name.substring(0,separator);
+    return result;
+  }
+
+  static String findCollection(String _name) {
+    String result = "";
+    try {
+      int separator = _name.indexOf(':');   
+      result = _name.substring(separator+1,_name.length());
+    } catch (Throwable t) {
+      System.err.println("Throwable: "+ t);
+    }
+    return result;
+  }
+
+  /**
+   * Allow the client to configure a CORBA server.
+   * @param key the parameter to be set.
+   * @param values what that parameter will be set to.
+   */
+  public void configure( String _key, Set _values ) {
+    Enumeration e = services.keys();
+    for (int i = 0; e.hasMoreElements(); i++) {
+      NzdlService server = (NzdlService) e.nextElement();
+      server.configure(_key,_values);
+    }
+  }
+
+  /**
+   * Obtain the set of collection names for a Greenstone library.
+   * @return A set of collection names in string format.
+   */
+  public Set getCollectionSet( ) {
+    Set results = new HashSet();
+    Hashtable intermediate = new Hashtable();
+
+    Enumeration e = services.keys();
+    for (int i = 0; e.hasMoreElements(); i++) {
+      String name = (String) e.nextElement();
+      NzdlService server = (NzdlService) services.get(name);
+      Set set = server.getCollectionSet();
+      Iterator s = set.iterator();
+      while (s.hasNext()) {
+	String coll = (String) s.next();
+	String collname = "" + i + ":" + coll;
+	boolean hit = false;
+	for (int j = 0; j < i; j++) {
+	  String oldcollname = "" + j + ":" + coll;
+	  if (intermediate.get(oldcollname) != null) {
+	    
+	    NzdlService oldServer = (NzdlService) services.get( "" + j );
+	    Date startOld = new Date();
+	    NzdlCollectionInfo oldColl = oldServer.getCollectionInfo(coll);
+	    Date endOld = new Date();
+	    Date startNew = new Date();
+	    NzdlCollectionInfo newColl = server.getCollectionInfo(coll);
+	    Date endNew = new Date();
+	    
+	    if (oldColl.getBuildDate() == newColl.getBuildDate() &&
+		oldColl.getNumOfDocs() == newColl.getNumOfDocs() &&
+		oldColl.getNumOfWords() == newColl.getNumOfWords() &&
+		oldColl.getNumOfBytes() == newColl.getNumOfBytes() &&
+		oldColl.isPublic() == newColl.isPublic() )
+	      {
+		if ((endOld.getTime() - startOld.getTime()) >
+		    (endNew.getTime() - startNew.getTime()))
+		  {
+		    results.remove(oldcollname);
+		    results.add(collname);
+		  }
+	      }
+	    hit = true;
+	  }
+	}
+	if (hit == false) {
+	  intermediate.put(collname,collname);
+	  results.add("" + i + ":" + coll); 
+	}
+      }
+    }
+    return results;
+  }
+
+  /**
+   * Check if ORB knows of this collection.
+   * @param name the name of a collecion to be searched for.
+   * @return boolean <TT>true</TT> if collection is found, else <TT>false</TT>.
+   */
+  public boolean hasCollection( String _name ) {
+
+    NzdlService server = (NzdlService) services.get( findServer(_name));
+    return  server.hasCollection(findCollection(_name));
+   }
+
+  /**
+   * Check if ORB can communicate with of this collection.
+   * @param name the name of a collecion to be pinged.
+   * @return boolean <TT>true</TT> if collection returned ping, else
+   * <TT>false</TT>.
+   */
+  public boolean pingCollection( String _name ) {
+    NzdlService server = (NzdlService) services.get( findServer(_name));
+    return server.pingCollection(findCollection(_name));
+  }
+
+  /**
+   * Extract information on this collection into a
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} object
+   * @param name the collection to be retrieved.
+   * @return an instance of
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} containing data on a
+   * collection
+   */
+  public NzdlCollectionInfo getCollectionInfo( String _name ) {
+    NzdlService server = (NzdlService) services.get( findServer(_name));
+    NzdlCollectionInfo result = server.getCollectionInfo(findCollection(_name));
+    return result;
+  }
+
+  /**
+   * Returns the set of filters for the service object.
+   * @param name the collection name
+   * @return a set of strings that name the filters, for example
+   * BrowseFilter, QueryFilter and NullFilter.
+   */
+  public Set getFilterSet( String _name ) {
+    NzdlService server = (NzdlService) services.get( findServer(_name));
+    Set result = server.getFilterSet(findCollection(_name));
+    return result;
+  }
+
+  /**
+   * @param name the collection name
+   * @return the Set of (name, value) value pairs for all metadata 
+   * associated with a collection  
+   */
+  public Set getMetaTagSet( String _name ) {
+    NzdlService server = (NzdlService) services.get( findServer(_name));
+    Set result = server.getMetaTagSet(findCollection(_name));
+    return result;
+  }
+
+  /**
+   * Returns the Greenstone Markup Language (GML) text for a particular
+   * document from a collection.
+   * @param name the name of the collection.
+   * @param docID the document identity string
+   * @return the GML document in the form of a string.
+   */
+  public String getDocument( String _name, String _docID ) {
+    NzdlService server = (NzdlService) services.get( findServer(_name));
+    String result = server.getDocument(findCollection(_name), _docID);
+    return result;
+  }
+
+  /**
+   * Returns the set of value(s) for a metatag from a particular document.
+   * @param name collection name
+   * @param docID the document identifier.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The set of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Set getMetaData( String _name, String _docID, String _metaTag ) {
+    NzdlService server = (NzdlService) services.get( findServer(_name));
+    Set result = server.getMetaData( findCollection(_name), _docID, _metaTag );
+    return result;
+  }
+
+  /**
+   * Returns a map of value(s) for a metatag from a list of documents.
+   * @param name collection name
+   * @param docIDs a list of document identifier strings.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The map of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Map getMetaData( String _name, List _docIDs, String _metaTag ) {
+    NzdlService server = (NzdlService) services.get( findServer(_name));
+    Map result = server.getMetaData( findCollection(_name), _docIDs, _metaTag );
+    return result;
+  }
+
+  /**
+   * Services a {@link NzdlRequest NzdlRequest} to a collection and places
+   * the results into a {@link NzdlResponse NzdlResponse} object. <br>
+   * Pre:   Created instances of NzdlRequest and NzdlResponse. <br>
+   * Post: Placed the result data into NzdlResponse object.
+   * @param name the collection name.
+   * @param request an instance of NzdlRequest with query data to be serviced
+   * @param response an instance of NzdlResponse. where the results of
+   * sevciving the query will be placed
+   */
+  public void service( String _name, NzdlRequest _request, 
+		       NzdlResponse _response ) {    
+    NzdlService server = (NzdlService) services.get( findServer(_name));
+    server.service(findCollection(_name),_request,_response);
+  }
+  
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlQuery.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlQuery.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlQuery.java	(revision 21017)
@@ -0,0 +1,317 @@
+/*
+ *    NzdlQuery.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.Collection;
+
+import org.nzdl.gsdl.util.NzdlConstants;
+
+/**
+ * NzdlQuery is an object that holds the options for a query and is
+ * easily configured by the user.
+ *
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui    (amahoui@yahoo.com)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @version $Revision$
+ */
+
+public class NzdlQuery extends java.lang.Object 
+					implements java.io.Serializable{
+
+
+  private Map m_Options = null;
+
+  /**      
+   * Creates an instance of NzdlQuery with an empty query string.
+   * This can then be used as a constructor parameter when creating a
+   * {@link NzdlRequest NzdlRequest} object for servicing by a
+   * {@link NzdlService NzdlService} object.
+   * Default values for a NzdlQuery object are: maxDocs 200, startResults= 1,
+   *  endResults= 10, queryType= "ranked", caseFolding= true, stemming= false,
+   * queryTerm= "".
+   */
+  public NzdlQuery() {
+    m_Options = new HashMap();
+    setQueryTerm   ( NzdlConstants.DEFAULT_QUERY_TERM );
+    setQueryType   ( NzdlConstants.DEFAULT_QUERY_TYPE );
+    setCaseFolding ( NzdlConstants.DEFAULT_CASE_FOLDING );
+    setStemming    ( NzdlConstants.DEFAULT_STEMMING );
+    setStartResults( NzdlConstants.DEFAULT_START_RESULTS );
+    setEndResults  ( NzdlConstants.DEFAULT_END_RESULTS );
+    setMaxDocs     ( NzdlConstants.DEFAULT_MAX_DOCS );
+    setMetadata    ( NzdlConstants.DEFAULT_QUERY_META);
+    setIndex (new String("")); 
+  }
+
+  /**
+   * Creates an instance of NzdlQuery with a value for query string. Has the
+   * same default values as NzdlQuery(), with the exception of term which is
+   * loaded into the query string field.
+   * @param term the query string
+   */
+  public NzdlQuery( String _term ) {
+    m_Options = new HashMap();
+    setQueryTerm   ( _term );
+    setQueryType   ( NzdlConstants.DEFAULT_QUERY_TYPE );
+    setCaseFolding ( NzdlConstants.DEFAULT_CASE_FOLDING );
+    setStemming    ( NzdlConstants.DEFAULT_STEMMING );
+    setStartResults( NzdlConstants.DEFAULT_START_RESULTS );
+    setEndResults  ( NzdlConstants.DEFAULT_END_RESULTS );
+    setMaxDocs     ( NzdlConstants.DEFAULT_MAX_DOCS );
+    setIndex (new String(""));
+  }
+
+    /** sets index to be queried.
+     */
+    public void setIndex(String _index) {
+	m_Options.put("Index", _index);
+    }
+
+
+  /** 
+   * Sets the expression to be queried. Note: this can also be done using the
+   * constructor.
+   * @param term the query expression string
+   */
+  public void setQueryTerm(String _term) {
+    m_Options.put("Term", _term);
+  }
+
+  /**
+  * Sets the query type as either "ranked" or "boolean". "ranked"
+  * orders results by suitability. "boolean" allows use of operators such as
+  * !, &, |. Default is "ranked"
+  * @param type "ranked" or "boolean"
+  */
+  public void setQueryType(String _type) {
+    m_Options.put("QueryType", _type);
+  }
+
+  /**
+  * Sets query to ignore case. Default is true.
+  * @param case if false then sets query to be case sensitive. If true
+  * then sets query to be case insenstive.
+  *
+  * removed the string version - surely we only need a boolean method here
+  * Dave
+  *
+  public void setCaseFolding(String _case) {
+    m_Options.put("CaseFold", _case);
+  }
+  */
+
+  /**
+  * Sets query to ignore case. Default is true.
+  * @param case if false then sets query to be case sensitive. If true
+  * then sets query to be case insenstive.
+  */
+
+    public void setCaseFolding(boolean _case) {
+	if (_case == false)
+	    m_Options.put("CaseFold", "false");
+	else
+	    m_Options.put("CaseFold", "true");
+    }
+
+  /**
+  * Sets query to ignore word endings. Default is "false."
+  * @param stem if "true", sets query to strip endings such as "...ing",
+  * "...ed". If "false", sets query to only match whole words.
+  *
+  public void setStemming(String _stem) {
+    m_Options.put("Stem", _stem);
+  }
+  *
+  * removed the string version - surely we only need a boolean method here
+  * Dave
+  */
+
+  /**
+  * Sets query to ignore word endings. Default is "false."
+  * @param stem if "true", sets query to strip endings such as "...ing",
+  * "...ed". If "false", sets query to only match whole words.
+  */
+  public void setStemming(boolean _stem) {
+      if (_stem == true) 
+	  m_Options.put("Stem", "true");
+      else
+	  m_Options.put("Stem", "false");
+  }
+
+  /**
+  * Sets the maximum number of documents that can be found by a query.
+  * Default is 200.
+  * @param max The maximum permitted number of documents to be found
+  * by the query
+  */
+  public void setMaxDocs(int _max) {
+    m_Options.put("Maxdocs", new Integer(_max));
+  }
+
+  /**
+  * Sets the start number of the result set. The result set is a subset
+  * of the maximum number of documents that will be found by the query.
+  * Default is 1.
+  * @param start the number of the first document, relative to the found
+  * documents
+  */
+  public void setStartResults(int _start) {
+    m_Options.put("StartResults", new Integer(_start));
+  }
+
+  /**
+  * Sets the end number of the result set. The result set is a subset of the
+  * maximum number documents that could be found by that query.
+  * Default is 10.
+  * @param end the number of the last document relative to the found
+  * documents
+  */
+  public void setEndResults(int _end) {
+    m_Options.put("EndResults", new Integer(_end));
+  }
+
+	/**
+   *	Set the retrieval of extended Metadata information in the result set.
+	 *  The default is off (false)
+	 *  @param whether to retrieve metadata.
+	 */
+	public void setMetadata(boolean _set)
+	{	m_Options.put("Metadata", new Boolean(_set));
+	}
+
+  /**
+  * Returns whether query is "ranked" or "boolean". "ranked" orders results by
+  * suitability. "boolean" allows use of operators such as !, &, |. Default is
+  * "ranked"
+  * @return Either "ranked" or "boolean"
+  */
+  public String getQueryType() {
+    return (String)m_Options.get("QueryType");
+  }
+
+  /**
+  * Returns the query string expression.
+  * @return the query string
+  */
+  public String getQueryTerm() {
+    return (String)m_Options.get("Term");
+  }
+    /** Returns the index to be queried
+     * @return the index
+     */
+    public String getIndex() {
+	return (String)m_Options.get("Index");
+    }
+
+  /**
+  * Returns "true" if query is case insenstive. Default is "true"
+  * @return "true" if query is case insenstive, "false" if the query is case
+  * senstive.
+  */
+  public String getCaseFolding() {
+    return (String)m_Options.get("CaseFold");
+  }
+
+    public boolean isCaseFolding() {
+	return ((String)m_Options.get("CaseFold") == "true");
+    }
+
+  /**
+  * Returns "true" if query ignores word endings. Default is "false".
+  * @return "true" if query strips endings such as "...ing" or "...ed" , false
+  * if query only matches whole words.
+  */
+  public String getStemming() {
+    return (String)m_Options.get("Stem");
+  }
+
+    public boolean isStemming() {
+	return ((String)m_Options.get("Stem") == "true");
+    }
+
+
+    /**
+   * Returns the current setting for the maximum number of documents that
+   * may be found by a query. Default is 200.
+   * @return The maximum number of documents to be found
+   */
+  public int getMaxDocs() {
+    return ((Integer) m_Options.get("Maxdocs")).intValue();
+  }
+
+  /**
+  * Returns the start number of the result set. The result set is a subset of
+  * the maximum number of documents that could be found by the query.
+  * Default is 1.
+  * @return The number of the first document relative to the documents that
+  * were found to match the query
+  */
+  public int getStartResults() {
+    return ((Integer) m_Options.get("StartResults")).intValue();
+  }
+
+  /**
+  * Returns the end number of the result set. The result set is a subset of
+  * the maximum number documents that could be found by the query.
+  * Default is 10.
+  * @return The number of the last document relative to the documents that
+  * were found to match the query.
+  */
+  public int getEndResults() {
+    return ((Integer) m_Options.get("EndResults")).intValue();
+  }
+
+	/**
+   *	Get the retrieval of extended Metadata information in the result set.
+	 *  The default is off (false)
+	 *  @return whether to retrieve metadata.
+	 */
+	public boolean getMetadata()
+    {	
+	if (m_Options.get("Metadata") == null) return false;
+	return ((Boolean) m_Options.get("Metadata")).booleanValue();
+	}
+
+  /**
+  * Returns the set of query terms.
+  * @return This set: "EndResults", "QueryType", "Term", "MaxDocs",
+  * "StartResults", "Stem", "CaseFold"
+  */
+  public Set queryKeySet() {
+    return m_Options.keySet();
+  }
+
+  /**
+  * Returns a collection of the current query values.
+  * @return For a default query this collection: 10, "ranked", "", 200, 1
+  * , false, true
+  */
+  public Collection queryValues() {
+    return m_Options.values();
+  }
+
+}
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlQueryHit.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlQueryHit.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlQueryHit.java	(revision 21017)
@@ -0,0 +1,177 @@
+/*
+ *    NzdlQueryHit.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.Collection;
+
+/**
+ * Holds a single result from a query. NzdlQueryHit is used by
+ * {@link NzdlResponse NzdlResponse} and
+ * {@link NzdlResultSet NzdlResultSet}
+ *
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui    (amahoui@yahoo.com)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ */
+public class NzdlQueryHit extends java.lang.Object 
+					implements java.io.Serializable{
+
+  private String m_docID = null;
+  private long    m_resultNum = -1;   // I don't actually know what it means !!!
+  private long    m_ranking = -1;
+  private long    m_numTermsMatched = -1;
+  private long    m_numPhrasesMatched = -1;
+  private long [] m_docFreqs = null; // I don't actually know what it means !!!
+  /*
+   * The key in the map will be the metaData Tag
+   * The value for the key will be a Set of strings
+   * Ex: key = "Author", value = {A. Mahoui, S. Franks}
+   */
+  private Map m_metaData = null;
+
+  /**
+   * Sets the document ID.
+   * @param docID a string representaion of the document ID.
+   */
+  public void setDocumentID( String _docID ) {
+    m_docID = _docID;
+  }
+
+  /**
+   * Sets the ranking.
+   * @param the ranking an longeger representaion of the the hit's ranking.
+   */
+  public void setRanking( long _ranking ) {
+    m_ranking = _ranking;
+  }
+
+  /**
+   * Sets the result number.
+   * @param resultNum is the longeger representation of the result number.
+   */
+  public void setResultNumber( long _resultNum ) {
+    m_resultNum = _resultNum;
+  }
+
+  /**
+   * Sets the number of terms matched.
+   * @param numTermsMatched the number of terms matched.
+   */
+  public void setNumOfTermsMatched( long _numTermsMatched ) {
+    m_numTermsMatched = _numTermsMatched;
+  }
+
+  /**
+   * Sets the number of phrases matched.
+   * @param numPhrasesMatched the number of phrases matched.
+   */
+  public void setNumOfPhrasesMatched( long _numPhrasesMatched ) {
+    m_numPhrasesMatched = _numPhrasesMatched;
+  }
+
+  /**
+   * Sets the metedata
+   * @param metaData the key in the map will be the metaData tag.
+   * The value for the key will be a Set of strings.
+   * For example: key = "Author", value = {A. Mahoui, S. Franks}
+   */
+  public void setMetaData( Map _metaData ) {
+    m_metaData = _metaData;
+  }
+
+  /**
+   * Gets the document ID of the query hit.
+   * @return document ID in string form.
+   */
+  public String getDocumentID() {
+    return m_docID;
+  }
+
+  /**
+   * Gets the ranking of the query hit.
+   * @return longeger representing the hits ranking.
+   */
+  public long getRanking() {
+    return m_ranking;
+  }
+
+  /**
+   * Gets the result number of the query hit.
+   * @return longeger representing the result number.
+   */
+  public long getResultNumber() {
+    return m_resultNum;
+  }
+
+  /**
+   * Gets the number of terms matched in the hit. A term is an individual word
+   * in a query phrase.
+   * @return longeger representing the number of terms matched.
+   */
+  public long getNumOfTermsMatched() {
+    return m_numTermsMatched;
+  }
+
+  /**
+   * Gets the number of phrases matched in the hit.
+   * @return longeger representing the number of phrases matched.
+   */
+  public long getNumOfPhrasesMatched() {
+    return m_numPhrasesMatched;
+  }
+
+  /**
+   * Gets the metaData of the hit document.
+   * @return a map of the metadata. For example: key = "Author", value =
+   * {A. Mahoui, S. Franks}
+   */
+  public Map getMetaData() {
+    return m_metaData;
+  }
+
+  /**
+  * Gets a set of values for a metatag.
+  * @param a metatag, such as author.
+  * @return A set of string values for that metatag.
+  */
+  public Set getMetaDataValues( String _metaTag ) {
+    return (Set) m_metaData.get( _metaTag );
+  }
+
+  /** Gets the metatags for a hit.
+   * @return a set of key (String) objects such as Author, Title etc.
+   */
+  public Set getMetaDataTags() {
+    return m_metaData.keySet();
+  }
+
+  /**
+   * Gets a collection of metatag values for a hit.
+   * @return a collection of metatag values.
+   */
+  public Collection getMetaDataValues() {
+    return m_metaData.values();
+  }
+
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlRequest.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlRequest.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlRequest.java	(revision 21017)
@@ -0,0 +1,121 @@
+/*
+ *    NzdlRequest.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.List;
+
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+
+/**
+ * An object that holds CORBA request data ready for by servicing by
+ * {@link NzdlService NzdlService}. NzdlRequest can receive data from: <br>
+ * - a {@link NzdlQuery NzdlQuery} object <br>
+ * - a document ID <br>
+ * - document ID's and a metatag.
+ *
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui    (amahoui@yahoo.com)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @author George Buchanan (g.buchanan@mdx.ac.uk)
+ * @version $Revision$
+ */
+public class NzdlRequest extends java.lang.Object {
+
+  private corbaFilterRequest m_Filter = null;
+
+
+    public NzdlRequest( corbaFilterRequest request ) {
+	m_Filter = request;
+    }
+
+  /**
+   * Creates an instance of NzdlRequest based on a search string inside a
+   * {@link NzdlQuery NzdlQuery} object. When serviced by
+   * {@link NzdlService NzdlService}, this type of request will return
+   * references to zero or more documents. <br>
+   * Pre:  Have already created instance of NzdlQuery object containing a
+   * search string.<br>
+   * Post: Created a query filter request that is ready for servicing.
+   * @param query a {@link NzdlQuery NzdlQuery} object containing a string
+   * search and options.
+   */
+  public NzdlRequest( NzdlQuery _query ) {
+    m_Filter = NzdlCorbaFactory.createQueryFilterRequest( _query );
+  }
+
+  /**
+   *  Creates an instance of NzdlRequest based on a classifier string
+   *  inside a {@link NzdlBrowse NzdlBrowse} object.
+   */
+  public NzdlRequest( NzdlBrowse _browse) {
+    m_Filter = NzdlCorbaFactory.createBrowseFilterRequest( _browse );
+  }
+
+  /**
+   * Creates an instance of NzdlRequest based on a document ID. When serviced
+   * by {@link NzdlService NzdlService} this type of request will return
+   * exactly one document reference. <br>
+   * Pre:  Have obtained a valid document ID.<br>
+   * Post: Created a browse filter request
+   * @param docID a string containing a valid GSDL document identifier.
+   */
+  public NzdlRequest( String _docID ) {
+    m_Filter = NzdlCorbaFactory.createBrowseFilterRequest( _docID );
+  }
+
+  /**
+   * Creates an instance of NzdlRequest based on a document ID and
+   * a metatag. <br>
+   * Pre:  Have obtained a valid document ID and a metatag field.<br>
+   * Post: Created a metadata filter request.
+   * @param docID a string containing a valid GSDL document identifier.
+   * @param metatag a string containing a valid GSDL metadata such as Title
+   * or Author.
+   */
+  public NzdlRequest( String _docID, String _metaTag ) {
+    m_Filter = NzdlCorbaFactory.createMetaDataFilterRequest( _docID, _metaTag );
+  }
+
+  /**
+   * Creates an instance of NzdlRequest based on a list of document ID's and
+   * a metatag. <br>
+   * Pre:  Have obtained a list of valid document ID's and a metatag field.<br>
+   * Post: Created a metadata filter request.
+   * @param docIDs a list of strings containing a valid GSDL document
+   * identifiers.
+   * @param metatag a string containing a valid GSDL metadata type such as
+   * Title Author.
+   */
+  public NzdlRequest( List _docIDs, String _metaTag ) {
+    m_Filter = NzdlCorbaFactory.createMetaDataFilterRequest( _docIDs, _metaTag );
+  }
+
+  /**
+   * Returns the corbaFilterRequest for the NzdlRequest object.
+   * @return The corbaFilterRequest Object.
+   */
+  public corbaFilterRequest getFilter() {
+    return m_Filter;
+  }
+  
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlResponse.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlResponse.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlResponse.java	(revision 21017)
@@ -0,0 +1,236 @@
+/*
+ *    NzdlResponse.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.HashMap;
+import java.util.TreeMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.nzdl.gsdl.service.*;
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+
+/**
+ * An object that holds data from a response after a
+ * {@link NzdlRequest NzdlRequest} has been serviced by
+ * {@link NzdlService NzdlService}.
+ *
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui    (amahoui@yahoo.com)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @version $Revision$
+ */
+
+public class NzdlResponse extends java.lang.Object 
+					implements java.io.Serializable{
+
+  private corbaFilterResponseHolder m_responseHolder = null;
+  private corbaFilterResponse m_response = null;
+  private NzdlResultSet m_resultSet = null;
+  private TreeMap m_frequencies = null;
+  private List m_queryTerms = null;
+
+  /**
+   * Create an empty instance of a NzdlResponse object.
+   */
+  public NzdlResponse( ){
+
+    m_responseHolder = NzdlCorbaFactory.createFilterResponseHolder();
+    m_response = m_responseHolder.value;
+  }
+
+  /**
+   * 
+   */
+  public void copyData(NzdlResponse old) {
+    m_responseHolder = old.m_responseHolder ;
+    m_response = old.m_response;
+    m_resultSet =  old.m_resultSet;
+    m_frequencies = old.m_frequencies;
+    m_queryTerms = old.m_queryTerms;
+  }
+
+  /**
+   * Get the corbaFilterReponse.
+   */
+  public corbaFilterResponse getResponse() {
+    return m_response;
+  }
+
+  /**
+   * Set the corbaFilterReponse.
+   */
+  public void setResponse(corbaFilterResponse response) {
+    m_response = response;
+    m_responseHolder.value = response;
+    parseResponse();
+  }
+
+  /**
+   * Get the corbaFilterReponse holder.
+   */
+  public corbaFilterResponseHolder getHolder() {
+    return m_responseHolder;
+  }
+
+  /**
+   * Get the result of {@link NzdlService NzdlService} servicing a
+   * {@link NzdlRequest NzdlRequest}. <br>
+   * Pre: <br>
+   * - Created instances of: NzdlRequest, NzdlService and
+   * {@link NzdlResponse NzdlResponse}. <br>
+   * - NzdlService has serviced NzdlRequest. <br>
+   * - Created instance of {@link NzdlResultSet NzdlResultSet}. <br>
+   * Post: Copied result data from a NzdlResponse object into a NzdlResult
+   * set object <br><br>
+   *
+   * <B>Example Code</B> <br>
+   * <TT>NzdlQuery query = new NzdlQuery( "snail farming" );          <br>
+   * NzdlRequest request = new NzdlRequest( query );                  <br>
+   * NzdlResponse response = new NzdlResponse( );                     <br><br>
+   * // use service to get response from request to "demo" collection <br>
+   * NzdlService myService = new NzdlServiceClient( _args );          <br>
+   * myService.service( "demo", request, response );                  <br><br>
+   * // use getResultSet to get "results" from "response"             <br>
+   * NzdlResultSet results = <B>response.getResultSet();</B> </TT>
+   */
+  public NzdlResultSet getResultSet() {
+    if ( m_resultSet == null ) {
+      parseResponse();
+    }
+    return m_resultSet;
+  }
+
+  /*
+    This is a short expansion of the content of a corbaFilterResponse object.
+    Some of the fields are not that clear to me (those with ?????). Therefore
+    I am ignoring some of them for the time being.
+
+    o Number of Documents
+    o Type of results
+    o Info on each of the search terms used:
+
+      o Term string
+      o Term frequency
+      o Matched terms ?????
+
+    o Info on each of the result docs returned:
+
+      o Document ID
+      o Result number ?????
+      o Number of terms matched in this document
+      o Number of phrases matched in this document
+      o Array of document frequencies ?????
+      o Info on the metadata:
+
+         o Array of the names of the meta tags
+         o Info on each of the meta data:
+
+           o Params string ?????
+           o Is the metadata a reference ?????
+           o Array of values
+	   o Id ?????
+	   o Parentid ?????
+  */
+
+
+  /**
+   * Parse the CORBA filter response object
+   */
+  private void parseResponse () {
+    m_response = m_responseHolder.value;
+    m_resultSet = new NzdlResultSet();
+    m_resultSet.setNumOfDocs( m_response.numDocs );
+    if (m_response.isApprox == null)
+      throw new Error ("null m_response.isApprox in parseResponse");
+    m_resultSet.setResultType( m_response.isApprox.value() );
+    /** HAS SIDE EFFECT ! */
+    parseTermsInfo( m_response.termInfo );
+    /** HAS SIDE EFFECT ! */
+    parseDocsInfo( m_response.docInfo );
+  }
+
+  private void parseTermsInfo( corbaTermInfo [] _termsInfo ) {
+    String term = null;
+    m_frequencies = new TreeMap();
+    m_queryTerms = new ArrayList();
+    for (int i=0; i<_termsInfo.length; i++) {
+      term = NzdlCorbaFactory.toString(_termsInfo[i].term);
+      m_queryTerms.add( term );
+      m_frequencies.put( term, new Long(_termsInfo[i].frequency) );
+    }
+    m_resultSet.setQueryTerms( m_queryTerms );
+    m_resultSet.setTermFrequencies( m_frequencies );
+  }
+
+  private void parseDocsInfo( corbaResultDocInfo [] _docsInfo ) {
+    NzdlQueryHit queryHit = null;
+    //System.err.println("Size of DocsInfo: " + _docsInfo.length);
+    for (int i=0; i < _docsInfo.length; i++) {
+      queryHit = new NzdlQueryHit();
+      queryHit.setDocumentID( NzdlCorbaFactory.toString(_docsInfo[i].OID) );
+      queryHit.setResultNumber( _docsInfo[i].resultNum );
+      queryHit.setRanking( _docsInfo[i].ranking );
+      queryHit.setNumOfTermsMatched( _docsInfo[i].termsMatched );
+      queryHit.setNumOfPhrasesMatched( _docsInfo[i].phraseMatched );
+      /** TO DO: extract corbaDocFreq_array value */
+      queryHit.setMetaData( parseMetaData(_docsInfo[i].metadata) );
+      // add to the result set
+      m_resultSet.add( queryHit ) ;
+    }
+  }
+
+  private Map parseMetaData( corbaMetadataInfo_map _metaData ) {
+    /*
+     * The key in the map will be the metaData Tag
+     * The value for the key will be a Set of strings
+     * Ex: key = "Author", value = {A. Mahoui, S. Franks}
+     */
+    Map metaData = new HashMap();
+    // For each meta tag can be associated more than one value (example above)
+    Set metaTagValues;
+    corbaMetadataInfo c_metaDataInfo = null;
+
+    for (int i=0; i < _metaData.names.length; i++) {
+      // one meta data at a time please ...
+      c_metaDataInfo = _metaData.values[i];
+
+      // get a fresh meta tag values item
+      metaTagValues = new HashSet();
+
+      // get the set of values associated with this meta tag ...
+      for (int j=0; j < c_metaDataInfo.values.length; j++) {
+	metaTagValues.add( NzdlCorbaFactory.toString(c_metaDataInfo.values[j]) );
+      }
+
+      // map the meta tag with its set of values ...
+      metaData.put( NzdlCorbaFactory.toString(_metaData.names[i]), metaTagValues);
+    }
+    return metaData;
+  }
+
+}
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlResultSet.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlResultSet.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlResultSet.java	(revision 21017)
@@ -0,0 +1,302 @@
+/*
+ *    NzdlResultSet.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.Set;
+import java.util.Map;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map.*;
+import java.util.HashMap;
+import java.util.TreeMap;
+import java.util.SortedMap;
+import java.util.TreeSet;
+import java.util.HashSet;
+import java.util.ListIterator;
+import java.util.Iterator;
+import java.util.Comparator;
+import java.util.*;
+
+/**
+ * An object that holds results extracted from a response by
+ * {@link NzdlResponse#getResultSet() NzdlResponse.getResultSet()}.
+ * Easily interrogated by a user.
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui    (amahoui@yahoo.com)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Dave Nichols   (daven@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ */
+public class NzdlResultSet extends java.lang.Object 
+					implements java.io.Serializable{
+
+  private List m_resultSet   = null;
+  private long m_numDocs     = -1;
+  private long m_resultType  = -1;
+  private List m_queryTerms  = null;
+  private List m_docIDs = null;
+
+  /* The key is the query term, the value its frequency */
+  private TreeMap m_frequencies = null;
+
+  /*
+   * The key is the docID, the value is the doc corresponding
+   * meta data which is also a Map where the key is the meta tag
+   * and the value is a set of values for that tag
+   */
+  private Map m_docToMetaDataMap = null;
+
+  /**
+   * Creates an empty instance of NzdlResultSet.
+   */
+  public NzdlResultSet() {
+    m_resultSet = new ArrayList();
+    m_docToMetaDataMap = new HashMap();
+    m_docIDs = new ArrayList();
+  }
+
+    /* 
+     * display term frequency results in descending frequency order 
+     * for alternative sorting orders alter the compareTo method
+     */
+
+    public String getTermFrequencyString() {
+  
+	class TermFrequency implements Comparable {
+	    String term; long frequency;
+	    TermFrequency( String _term, Long _frequency) {
+		term = _term; frequency = _frequency.longValue(); 
+	    }
+	    public int compareTo (Object o1) {
+		TermFrequency test = (TermFrequency) o1;
+		if (frequency == test.frequency) return 0;
+		if (frequency < test.frequency) 
+		    return -1;
+		else
+		    return 1;
+	    }
+	}
+
+	ArrayList freqList = new ArrayList();
+	Iterator iter = m_frequencies.entrySet().iterator();
+	while (iter.hasNext()) {
+	    Map.Entry mapEntry = (Map.Entry) iter.next();
+	    freqList.add( new TermFrequency((String)mapEntry.getKey(), (Long)(mapEntry.getValue())));
+	}
+	Collections.sort(freqList, Collections.reverseOrder());
+	StringBuffer buf = new StringBuffer();
+	iter = freqList.iterator();
+	while(iter.hasNext()) {
+	    TermFrequency next = (TermFrequency) iter.next();
+	    buf.append(next.term).append(':').append(next.frequency).append(' ').append(' ');
+	}
+	return buf.toString();
+    }
+  
+  /**
+   * Adds a {@link NzdlQueryHit NzdlQueryHit} to a result set.
+   * @param hit - is an instance of NzdlQueryHit.
+   */
+  public void add( NzdlQueryHit _hit ) {
+    m_resultSet.add( _hit ) ;
+    String id = _hit.getDocumentID();
+    m_docIDs.add( id );
+    m_docToMetaDataMap.put( id, _hit.getMetaData() );
+  }
+
+    /**
+   * Sets the number of documents in a NzdlResultSet.
+   * @param num the number of documents in the result set
+   */
+  public void setNumOfDocs( long _num ) {
+    m_numDocs = _num;
+  }
+
+
+  /**
+   * Sets the result type.
+   * @param type an integer representing the result type.
+   */
+  public void setResultType( long _type ) {
+    m_resultType = _type;
+  }
+
+  /**
+   * Sets the Query terms of a NzdlResultSet.
+   * @param terms a list of words within the query string.
+   */
+  public void setQueryTerms( List _terms ) {
+    m_queryTerms = _terms;
+  }
+
+//    public void setTermFrequency( String _term, int _freq ) {
+//      m_frequencies.put( _term, new Integer(_freq) );
+//    }
+
+  /**
+   * Sets the term frequencies within a NzdlResultSet.
+   * @param freqs a map of the term frequencies. The map key is the query term.
+   */
+  public void setTermFrequencies( TreeMap _freqs ) {
+    m_frequencies = _freqs;
+  }
+
+  /**
+   * Returns the number of documents that matched a query. <br>
+   * Pre: A {@link NzdlResponse NzdlResponse} object has been created. A
+   * {@link NzdlService NzdlService} object has filled the NzdlResponse
+   * object with results from servicing a {@link NzdlRequest NzdlRequest}.<br>
+   * @return The number of documents that matched a query. This is limited
+   * by the maxDocs set in {@link NzdlQuery NzdlQuery}
+   */
+  public long getNumOfDocs() {
+    return m_numDocs;
+  }
+
+  /**
+   * Returns the result type for the NzdlResultSet. <br>
+   * Pre: A {@link NzdlResponse NzdlResponse} object has been created. A
+   * {@link NzdlService NzdlService} object has filled the NzdlResponse
+   * object with results from servicing a {@link NzdlRequest NzdlRequest}.<br>
+   * @return result type as an integer.
+   */
+  public long getResultType() {
+    return m_resultType;
+  }
+
+  /**
+   * Returns a list of the words within the query string. <br>
+   * Pre: A {@link NzdlResponse NzdlResponse} object has been created. A
+   * {@link NzdlService NzdlService} object has filled the NzdlResponse
+   * object with results from servicing a {@link NzdlRequest NzdlRequest}.<br>
+   * @return A list of words within the query string.
+   */
+  public List getQueryTerms() {
+    return m_queryTerms;
+  }
+
+   /**
+   * Returns the number of hits for each word within the query string. <br>
+   * Pre: A {@link NzdlResponse NzdlResponse} object has been created. A
+   * {@link NzdlService NzdlService} object has filled the NzdlResponse
+   * object with results from servicing a {@link NzdlRequest NzdlRequest}.<br>
+   * @return A map of the frequency of each query word. The map key is the query term..
+   */
+  public Map getTermFrequencies() {
+    return m_frequencies;
+  }
+  
+//    public int getTermFrequency( String _term ) {
+//      return ((Integer)m_frequencies.get(_term)).intValue();
+//    }
+
+//    public List getDocumentIDs() {
+//      NzdlQueryHit hit = null;
+//      //Set docIDs = new HashSet();
+//      List docIDs = new ArrayList();
+//      for (ListIterator itr = m_resultSet.listIterator(); itr.hasNext(); ) {
+//        hit = (NzdlQueryHit) itr.next();
+//        docIDs.add( hit.getDocumentID() );
+//      }
+//      return docIDs;
+//    }
+
+  /**
+   * Returns a list of Document ID's in the NzdlResultSet. <br>
+   * Pre: A {@link NzdlResponse NzdlResponse} object has been created. A
+   * {@link NzdlService NzdlService} object has filled the NzdlResponse
+   * object with results from servicing a {@link NzdlRequest NzdlRequest}.<br>
+   * @return A list of Document ID's in the NzdlResultSet.
+   */
+    public List getDocumentIDs() {
+      return m_docIDs;
+    }
+
+//    public Set getMetaData( String _docID, String _metaTag ) {
+//      NzdlQueryHit hit = null;
+//      for (ListIterator itr = m_resultSet.listIterator(); itr.hasNext(); ) {
+//        hit = (NzdlQueryHit) itr.next();
+//        if ( _docID.equals( hit.getDocumentID() ) ) {
+//  	return hit.getMetaDataValues( _metaTag );
+//        }
+//      }
+//      return null;
+//    }
+
+  /**
+   * Returns metatag values for a document. <br>
+   * Pre: A {@link NzdlResponse NzdlResponse} object has been created. A
+   * {@link NzdlService NzdlService} object has filled the NzdlResponse
+   * object with results from servicing a {@link NzdlRequest NzdlRequest}.<br>
+   * @return A map of metatag values in the specified document. The map key
+   * is the metatag field such as Author or Title.
+   */
+  public Set getMetaData( String _docID, String _metaTag ) {
+    Map metaData = (Map) m_docToMetaDataMap.get( _docID );
+    if (metaData != null)
+      return (Set) metaData.get( _metaTag );
+    else
+      return new HashSet();
+  }
+
+  /**
+   * Returns all values for a particular metatag in the result set. <br>
+   * Pre: A {@link NzdlResponse NzdlResponse} object has been created. A
+   * {@link NzdlService NzdlService} object has filled the NzdlResponse
+   * object with results from servicing a {@link NzdlRequest NzdlRequest}.<br>
+   * @param metaTag Descriptive data such as Author, Title or Date.
+   * @return A map of all values for a particular metatag in all documents
+   * in the NzdlResultSet. The map key is document ID.
+   */
+  public Map getMetaData( String _metaTag ) {
+    Map metaData = new HashMap();
+    for (ListIterator itr = m_resultSet.listIterator(); itr.hasNext(); ) {
+      NzdlQueryHit hit = (NzdlQueryHit) itr.next();
+      metaData.put( hit.getDocumentID(), hit.getMetaDataValues(_metaTag) );
+    }
+    return metaData;
+  }
+
+  /**
+   * Returns all values for all metatags in the result set. <br>
+   * Pre: A {@link NzdlResponse NzdlResponse} object has been created. A
+   * {@link NzdlService NzdlService} object has filled the NzdlResponse
+   * object with results from servicing a {@link NzdlRequest NzdlRequest}.<br>
+   * @return The metatag values for all metatags in all documents
+   * in the NzdlResultSet. The map key is document ID.
+   */
+  public Map getAllMetaData( ) {
+    return m_docToMetaDataMap;
+  }
+
+    /**
+   * Returns the number of document ID's retrieved <br>
+   * Pre: A {@link NzdlResponse NzdlResponse} object has been created. A
+   * {@link NzdlService NzdlService} object has filled the NzdlResponse
+   * object with results from servicing a {@link NzdlRequest NzdlRequest}.<br>
+   * @return The number of documents IDs that have been retrieved from the
+   * collection
+   */
+  public long getNumOfDocIdsRetrieved() {
+    return m_docIDs.size();
+  }
+
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlService.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlService.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlService.java	(revision 21017)
@@ -0,0 +1,143 @@
+/*
+ *    NzdlService.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.Set;
+import java.util.Map;
+import java.util.List;
+
+/**
+ * An object that services CORBA client requests to a Greenstone Digital
+ * Library.
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui    (amahoui@yahoo.com)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @version $Revision$
+ */
+public interface NzdlService {
+
+  /**
+   * Allow the client to configure a CORBA server.
+   * @param key the parameter to be set.
+   * @param values what that parameter will be set to.
+   */
+  public void configure( String key, Set values );
+
+  /**
+   * Obtain the set of collection names for a Greenstone library.
+   * @return A set of collection names in string format.
+   */
+  public Set getCollectionSet( );
+
+  /**
+   * Check if ORB knows of this collection.
+   * @param collectionName the name of a Greenstone collection.
+   * @return boolean <TT>true</TT> if collection is found, else <TT>false</TT>.
+   */
+  public boolean hasCollection( String collectionName );
+
+  /**
+   * Check if ORB can communicate with of this collection.
+   * @param collectionName the name of a collection to be pinged.
+   * @return boolean <TT>true</TT> if collection returned ping, else
+   * <TT>false</TT>.
+   */
+  public boolean pingCollection( String collectionName );
+
+ /**
+   * Extract information on this collection into a
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} object
+   * @param collectionName the Greenstone collection to be retrieved.
+   * @return an instance of
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} containing data on a
+   * collection
+   */
+  public NzdlCollectionInfo getCollectionInfo( String collectionName );
+
+  /**
+   * Returns the set of filters for the service object.
+   * @param collectionName the name of the Greenstone collection.
+   * @return a set of strings that name the filters, for example
+   * BrowseFilter, QueryFilter and NullFilter.
+   */
+  public Set getFilterSet( String collectionName );
+
+    // 24-5-02 kjdon
+  /**
+   * Returns the set of filter options for a particular filter
+   * @param name the collection name
+   * @param filter the filter name
+   * @return an instance of
+   * {@link NzdlFilterOptions NzdlFilterOptions} containing the filter
+   * options for a filter
+   */
+    public NzdlFilterOptions getFilterOptionSet(String _name, String _filter);
+
+  /**
+   * Not Currently implemented.
+   */
+  public Set getMetaTagSet( String collectionName );
+
+  /**
+   * Returns the Greenstone Markup Language (GML) text for a particular
+   * document from a collection.
+   * @param collectionName the name of the Greenstone collection.
+   * @param documentID the document identity string
+   * @return the GML document in the form of a string.
+   */
+  public String getDocument( String collectionName, String documentID );
+
+  /**
+   * Returns the set of value(s) for a metatag from a particular document.
+   * @param collectionName the name of the Greenstone collection.
+   * @param documentID the document identifier.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The set of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Set getMetaData( String collectionName, String documentID, String metaTag );
+
+  /**
+   * Returns a map of value(s) for a metatag from a list of documents.
+   * @param collectionName name of the Greenstone collection
+   * @param docIDs a list of document identifier strings.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The map of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Map getMetaData( String collectionName, List documentIDs, String metaTag );
+
+  /**
+   * Services a {@link NzdlRequest NzdlRequest} to a collection and places
+   * the results into a {@link NzdlResponse NzdlResponse} object. <br>
+   * Pre:   Created instances of NzdlRequest and NzdlResponse. <br>
+   * Post: Placed the result data into NzdlResponse object.
+   * @param collectionName name of the Greenstone collection.
+   * @param request an instance of NzdlRequest with query data to be serviced
+   * @param response an instance of NzdlResponse. where the results of
+   * sevciving the query will be placed
+   */
+  public void service( String collectionName, NzdlRequest request, NzdlResponse response );
+
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlServiceClient.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlServiceClient.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlServiceClient.java	(revision 21017)
@@ -0,0 +1,377 @@
+/*
+ *    NzdlServiceClient.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+//import java.io.*;
+//import java.util.*;
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.HashSet;
+import java.util.Properties;
+
+/* jdk 1.3 orb */
+import org.omg.CORBA.ORB;
+/* gsdl corba stuff */
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.*;
+
+/**
+ * Used to implement the {@link NzdlService NzdlService} object.
+ * NzdlService is an object that services CORBA client requests to a
+ * Greenstone Digital Library.
+ *
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui    (amahoui@yahoo.com)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @version $Revision$
+ */
+public class NzdlServiceClient 
+  extends java.lang.Object 
+  implements NzdlService {
+
+  private corbaiface m_nzdlServer = null;
+
+  /**
+   * Creates an instance of Java's ORB (Object Request Broker) to interface
+   * to a Greenstone Digital Library.
+   * @param <b>args</b> command-line arguments from the application's main method, or
+   * alternatively, the name of the applet. This parameter is passed to
+   * <TT>ORB.init( _args, _props)</TT>. Args may be a <TT>null</TT>.
+   * @param <b>props</b> application specific properties.
+   * This parameter is passed to
+   * <TT>ORB.init( _args, _props)</TT>. props may be a <TT>null</TT>.
+   * @param <b>IOR</b> the Interoperable Object Reference, a string that identifies
+   * the computer on which corbaserver is running and the interface it
+   * supports.
+   * @see The Java documentation on the ORB class.
+   */
+  public NzdlServiceClient( String [] _args, Properties _props, String _IOR) {
+    corbaComErrorHolder error = NzdlCorbaFactory.createComErrorHolder();
+
+    try {
+
+      // getting a reference to the remote NZDL server
+      org.omg.CORBA.ORB orb = ORB.init( _args, _props);
+      org.omg.CORBA.Object obj = orb.string_to_object(_IOR) ;
+      m_nzdlServer = corbaifaceHelper.narrow(obj);
+      
+      // basic setup
+      if (m_nzdlServer.initialise(error)) {
+      } else {
+	  throw new Error("NzdlServiceClient initialisation unsuccessful.");
+      }
+      
+    } catch (Exception e) {
+      System.err.println("Exception in NzdlServiceClient initialisation: \n" + e) ;
+      System.err.println("corbaComError value: " + error.value.value());
+      System.err.println("NzdlServiceClient initialisation unsuccessful.");
+      throw new Error("NzdlServiceClient initialisation unsuccessful.");
+    }
+    if (error.value.value() != corbaComError._corbaNoError) {
+      System.err.println("corbaComError value: " + error.value.value());
+    }
+    
+    System.out.println("NzdlServiceClient initialisation successful.");
+  }
+
+
+  /**
+   * Allow the client to configure a CORBA server.
+   * @param key the parameter to be set.
+   * @param values what that parameter will be set to.
+   */
+  public void configure( String _key, Set _values ) {
+    if (_key == null || _key.equals("")){
+      throw new Error ("null or empty collection _key");
+    }
+    if (_values == null ){
+      throw new Error ("null or empty collection _values");
+    }
+    corbaComErrorHolder error = NzdlCorbaFactory.createComErrorHolder();
+    m_nzdlServer.configure( NzdlCorbaFactory.toCorbaText( _key ),
+			    NzdlCorbaFactory.toCorbaTextArray( _values ),
+			    error);
+    if (error.value.value() != corbaComError._corbaNoError) {
+      System.err.println("CORBA error:" + error.value.value());
+    }
+  }
+
+  /**
+   * Obtain the set of collection names for a Greenstone library.
+   * @return A set of collection names in string format.
+   */
+  public Set getCollectionSet( ) {
+    //System.err.println("Client::getCollectionSet() start");
+    corbaComErrorHolder error = NzdlCorbaFactory.createComErrorHolder();
+    corbatext_tarrayHolder c_collSet = NzdlCorbaFactory.createCorbaTextArrayHolder();
+    m_nzdlServer.collectionList(c_collSet, error);
+    Set collSet = new HashSet();
+    for (int i=0; i<c_collSet.value.length; i++) {
+      String collName = NzdlCorbaFactory.toString( c_collSet.value[i] );
+      if (collName.indexOf("nuipepa") == -1)
+	collSet.add(collName);
+    }
+    if (error.value.value() != corbaComError._corbaNoError) {
+      System.err.println("CORBA error:" + error.value.value());
+    }
+    //System.err.println("Client::getCollectionSet() end " + error.value.value());
+    return collSet ;
+  }
+
+  /**
+   * Check if ORB knows of this collection.
+   * @param name the name of a collecion to be searched for.
+   * @return boolean <TT>true</TT> if collection is found, else <TT>false</TT>.
+   */
+  public boolean hasCollection( String _name ) {
+    if (_name == null || _name.equals("")){
+      throw new Error ("null or empty collection _name");
+    }
+    corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    org.omg.CORBA.BooleanHolder c_has = new org.omg.CORBA.BooleanHolder();
+    m_nzdlServer.hasCollection( NzdlCorbaFactory.toCorbaText(_name), c_has, c_err );
+    if (c_err.value.value() != 0)
+      System.err.println("hasCollection error " + c_err.value.value());
+    return c_has.value;
+  }
+
+
+  /**
+   * Check if ORB can communicate with of this collection.
+   * @param name the name of a collecion to be pinged.
+   * @return boolean <TT>true</TT> if collection returned ping, else
+   * <TT>false</TT>.
+   */
+  public boolean pingCollection( String _name ) {
+    if (_name == null || _name.equals("")){
+      throw new Error ("null or empty collection _name");
+    }
+    corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    org.omg.CORBA.BooleanHolder c_ping = new org.omg.CORBA.BooleanHolder();
+    m_nzdlServer.ping( NzdlCorbaFactory.toCorbaText(_name), c_ping, c_err );
+    if (c_err.value.value() != 0)
+      System.err.println("pingCollection() error " + c_err.value.value());
+    return c_ping.value;
+  }
+
+  /**
+   * Extract information on this collection into a
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} object
+   * @param name the collection to be retrieved.
+   * @return an instance of
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} containing data on a
+   * collection
+   */
+  public NzdlCollectionInfo getCollectionInfo( String _name ) {
+    System.err.println("getCollectionInfo " + _name);
+    if (_name == null || _name.equals("")){
+      throw new Error ("null or empty collection _name");
+    }
+    corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    corbaColInfoResponseHolder c_info = NzdlCorbaFactory.createColInfoResponseHolder();
+    m_nzdlServer.getCollectInfo( NzdlCorbaFactory.toCorbaText(_name), c_info, c_err );
+    if (c_err.value.value() != 0)
+      System.err.println("getCollectionInfo() error " + c_err.value.value());
+    return new NzdlCollectionInfo( c_info.value );
+  }
+
+  /**
+   * Returns the set of filters for the service object.
+   * @param name the collection name
+   * @return a set of strings that name the filters, for example
+   * BrowseFilter, QueryFilter and NullFilter.
+   */
+  public Set getFilterSet( String _name ) {
+    if (_name == null || _name.equals("")){
+      throw new Error ("null or empty filter _name");
+    }
+    corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    corbatext_t c_name = NzdlCorbaFactory.toCorbaText( _name );
+    corbatext_tarrayHolder c_collSet = NzdlCorbaFactory.createCorbaTextArrayHolder();
+    m_nzdlServer.getFilterInfo(c_name, c_collSet,c_err);
+    if (c_err.value.value() != 0)
+      System.err.println("getCollectionInfo() error " + c_err.value.value());
+
+    Set collSet = new HashSet();
+    for (int i=0; i<c_collSet.value.length; i++) {
+      collSet.add( NzdlCorbaFactory.toString( c_collSet.value[i] ) );
+    }
+    return collSet ;
+
+  }
+  // added 24-4-02 kjdon
+  /**
+   * Returns the set of filter options for a particular filter
+   * @param name the collection name
+   * @param filter the filter name
+   * @return an instance of
+   * {@link NzdlFilterOptions NzdlFilterOptions} containing the filter
+   * options for a filter
+   */
+  public NzdlFilterOptions getFilterOptionSet(String _name, String _filter) {
+    if (_name == null || _name.equals("")){
+      throw new Error ("null or empty _name");
+    }
+    if (_filter == null || _filter.equals("")){
+      throw new Error ("null or empty _filter");
+    }
+    corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    corbatext_t c_name = NzdlCorbaFactory.toCorbaText( _name );
+    corbatext_t c_filter = NzdlCorbaFactory.toCorbaText( _filter);
+    corbaFilterOptionsResponseHolder c_options = 
+      NzdlCorbaFactory.createFilterOptionsResponseHolder();
+
+    m_nzdlServer.getFilterOptions(c_name, c_filter, c_options, c_err);
+    if (c_err.value.value() != 0)
+      System.err.println("getFilterOptionSet() error " + c_err.value.value());
+    return new NzdlFilterOptions( c_options.value );
+    
+  }
+
+  /**
+   * Not Currently implemented.
+   */
+  public Set getMetaTagSet( String _name ) {
+    if (_name == null || _name.equals("")){
+      throw new Error ("null or empty _name");
+    }
+    System.err.println("TO BE IMPLEMENTED: DON'T KNOW HOW YET !!! (getMetaTagSet)");
+    return null ;
+  }
+
+  /**
+   * Returns the Greenstone Markup Language (GML) text for a particular
+   * document from a collection.
+   * @param name the name of the collection.
+   * @param docID the document identity string
+   * @return the GML document in the form of a string.
+   */
+  public String getDocument( String _name, String _docID ) {
+    if (_name == null || _name.equals("")){
+      throw new Error ("null or empty _name");
+    }
+    if (_docID == null || _docID.equals("")){
+      throw new Error ("null or empty _docID");
+    }
+    corbatext_t c_name = NzdlCorbaFactory.toCorbaText( _name );
+    corbaDocRequestHolder c_request = NzdlCorbaFactory.createDocRequestHolder( _docID );
+    corbaDocResponseHolder c_response = NzdlCorbaFactory.createDocResponseHolder( );
+    corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    m_nzdlServer.getDocument( c_name, c_request, c_response, c_err );
+    if (c_err.value.value() != 0)
+      System.err.println("getDocument() error " + c_err.value.value());
+    return NzdlCorbaFactory.toString( c_response.value.doc );
+  }
+
+  /**
+   * Returns the set of value(s) for a metatag from a particular document.
+   * @param name collection name
+   * @param docID the document identifier.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The set of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Set getMetaData( String _name, String _docID, String _metaTag ) {
+    if (_name == null || _name.equals("")){
+      throw new Error ("null or empty _name");
+    }
+    if (_docID == null || _docID.equals("")){
+      throw new Error ("null or empty _docID");
+    }
+    if (_metaTag == null || _metaTag.equals("")){
+      throw new Error ("null or empty _metaTag");
+    }
+    NzdlRequest request  = new NzdlRequest( _docID, _metaTag );
+    NzdlResponse response = new NzdlResponse( );
+    service( _name, request, response );
+    if (response == null || response.getResponse() == null) {
+      return new HashSet();
+    }
+    NzdlResultSet resultSet = response.getResultSet();
+    /*
+     * Because a result set may contain several hits, we only return
+     * the set of metadata values of the specifed meta tag for the
+     * specified document ID.
+     */
+    return resultSet.getMetaData( _docID, _metaTag );
+  }
+
+  /**
+   * Returns a map of value(s) for a metatag from a list of documents.
+   * @param name collection name
+   * @param docIDs a list of document identifier strings.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The map of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Map getMetaData( String _name, List _docIDs, String _metaTag ) {
+    if (_name == null || _name.equals("")){
+      throw new Error ("null or empty _name");
+    }
+    if (_docIDs == null){
+      throw new Error ("null _docIDs");
+    }
+    if (_metaTag == null || _metaTag.equals("")){
+      throw new Error ("null or empty _metaTag");
+    }
+    NzdlRequest request  = new NzdlRequest( _docIDs, _metaTag );
+    NzdlResponse response = new NzdlResponse( );
+    service( _name, request, response );
+    NzdlResultSet resultSet = response.getResultSet();
+    //return resultSet.getMetaData( _docID, _metaTag );
+    return resultSet.getMetaData( _metaTag );
+    //return resultSet.getAllMetaData( );
+  }
+
+  /**
+   * Services a {@link NzdlRequest NzdlRequest} to a collection and places
+   * the results into a {@link NzdlResponse NzdlResponse} object. <br>
+   * Pre:   Created instances of NzdlRequest and NzdlResponse. <br>
+   * Post: Placed the result data into NzdlResponse object.
+   * @param name the collection name.
+   * @param request an instance of NzdlRequest with query data to be serviced
+   * @param response an instance of NzdlResponse. where the results of
+   * sevciving the query will be placed
+   */
+  public void service( String _name, NzdlRequest _request, NzdlResponse _response ) {    
+    if (_name == null || _name.equals("")) {
+      throw new Error ("null or empty _name");
+    }
+    if (_request == null) {
+      throw new Error ("null _request");
+    }
+    if (_response == null) {
+      throw new Error ("null _response");
+    }
+    corbatext_t c_name = NzdlCorbaFactory.toCorbaText( _name );
+    corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    m_nzdlServer.filter( c_name, _request.getFilter(), _response.getHolder(), c_err );
+    if (c_err.value.value() != 0) {
+      System.err.println("service() error " + c_err.value.value());
+      new Error().printStackTrace();
+    }
+  }
+  
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlServiceServer.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlServiceServer.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlServiceServer.java	(revision 21017)
@@ -0,0 +1,263 @@
+/*
+ *    SimpleServer.java
+ *    Copyright (C) 2000 Stuart Yeates 
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl.service;
+
+// java standard library classes used
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.Cloneable;
+import java.util.Set;
+import java.util.Iterator;
+
+import org.omg.CORBA.ORB;
+
+// local libraries
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.service.NzdlCollectionInfo; 
+import org.nzdl.gsdl.service.NzdlQuery;
+import org.nzdl.gsdl.service.NzdlRequest;
+import org.nzdl.gsdl.service.NzdlResponse;
+import org.nzdl.gsdl.service.NzdlResultSet;
+import org.nzdl.gsdl.service.NzdlService;
+import org.nzdl.gsdl.util.NzdlCorbaFactory;
+
+
+/**
+ * Act as a Server.
+ *
+ * Designed as a mirror image of NzdlServiceClient
+ *
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.service.NzdlService
+ * @see org.nzdl.gsdl.service.NzdlServiceClient
+ * @see org.nzdl.gsdl.service.NzdlServiceWrapper
+ * @see org.nzdl.gsdl.corba.gsdlInterface._corbaifaceImplBase
+ * 
+ */
+
+
+public class NzdlServiceServer extends _corbaifaceImplBase {
+
+  /** The underlying interface */
+  NzdlService nzdl = null;
+  
+  /** The normal constructor */
+  public NzdlServiceServer(NzdlService service) {
+    nzdl = service;
+  }
+
+  /** The beans constructor */
+  protected NzdlServiceServer() {
+    nzdl = null;
+  }
+
+  /** initialisation (not guaranteed to be called ...) */
+  public boolean initialise (corbaComErrorHolder error) {
+    // TODO should map the anything in NzdlService?
+    if (nzdl == null)
+      throw new Error ("NzdlServer needs a NzdlService to foward calls to ...");
+    error.value = corbaComError.from_int(corbaComError._corbaNoError);
+    return true;
+  }
+  
+  /**
+   * Allow the client to configure a CORBA server.
+   * @param key the parameter to be set.
+   * @param values what that parameter will be set to.
+   */
+  public void configure (corbatext_t key, 
+			 corbatext_t[] cfgline,
+			 corbaComErrorHolder error) {
+    //      m_nzdlServer.configure( NzdlCorbaFactory.toCorbaText( _key ),
+    //  			    NzdlCorbaFactory.toCorbaTextArray( _values ));
+
+    nzdl.configure( NzdlCorbaFactory.toString(key),
+		    NzdlCorbaFactory.toSet(cfgline));
+    error.value = corbaComError.from_int(corbaComError._corbaNoError);
+  }
+
+
+  /**
+   * Obtain the set of collection names for a Greenstone library.
+   * @param collist A set of collection names in string format.
+   * @param error a corba error object
+   */
+  public void collectionList (corbatext_tarrayHolder collist,
+			      corbaComErrorHolder error) {
+    System.err.println("Server::getCollectionSet() start " + error.value.value());
+    //corbatext_tarrayHolder c_collSet = NzdlCorbaFactory.createCorbaTextArrayHolder();
+    //m_nzdlServer.collectionList(c_collSet);
+    //Set collSet = new HashSet();
+    //for (int i=0; i<c_collSet.value.length; i++) {
+    //  collSet.add( NzdlCorbaFactory.toString( c_collSet.value[i] ) );
+    //}
+    //return collSet ;
+    Set set = nzdl.getCollectionSet();
+    System.err.println("Server::getCollectionSet() in " + error.value.value());
+    System.err.println("Server::getCollectionSet() in " + set);
+
+    collist.value = new corbatext_t[set.size()];
+
+    Iterator itr = set.iterator();
+    int i = 0;
+    while (itr.hasNext()) {
+      String s = (String) itr.next();
+      if (s.indexOf("nuipepa") == -1)
+	collist.value[i++] = NzdlCorbaFactory.toCorbaText(s);
+    }
+    error.value = corbaComError.from_int(corbaComError._corbaNoError);
+    System.err.println("Server::getCollectionSet() end " + error.value.value());
+
+    return;
+  }
+
+  /**
+   * Does the server have a specific collections? 
+   * @param has a boolean
+   * @param error a corba error object
+   */
+  public void hasCollection (corbatext_t corbaCollection,
+			     org.omg.CORBA.BooleanHolder has, 
+			     corbaComErrorHolder error) {
+    //      corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    //      org.omg.CORBA.BooleanHolder c_has = new org.omg.CORBA.BooleanHolder();
+    //      m_nzdlServer.hasCollection( NzdlCorbaFactory.toCorbaText(_name), c_has, c_err );
+    //      if (c_err.value.value() != 0)
+    //        System.err.println("hasCollection error " + c_err.value.value());
+    //      return c_has.value;
+    String name = NzdlCorbaFactory.toString(corbaCollection);
+    has.value  = nzdl.hasCollection(name);
+    error.value = corbaComError.from_int(corbaComError._corbaNoError);
+    return;
+  }
+
+  /**
+   * Is the collection avalibale for use?
+   * @param error a corba error object
+   * @return <tt>true</tt> if the collection is avaliable, 
+   *    <tt>false</tt> otherwise
+   */
+  public void ping (corbatext_t collection, 
+		    org.omg.CORBA.BooleanHolder has, 		    
+		    corbaComErrorHolder error) {
+    String name = NzdlCorbaFactory.toString(collection);
+    has.value = nzdl.hasCollection(name);
+  }
+
+  /**
+   * Get a document
+   * @param collection the collection the document is in
+   * @param request the details of the document
+   * @param response the document
+   * @param error a corba error object
+   */
+  public void getDocument (corbatext_t collection, 
+			   corbaDocRequestHolder request, 
+			   corbaDocResponseHolder response, 
+			   corbaComErrorHolder error) {
+    //      corbatext_t c_name = NzdlCorbaFactory.toCorbaText( _name );
+    //      corbaDocRequestHolder c_request = NzdlCorbaFactory.createDocRequestHolder( _docID );
+    //      corbaDocResponseHolder c_response = NzdlCorbaFactory.createDocResponseHolder( );
+    //      corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    //      m_nzdlServer.getDocument( c_name, c_request, c_response, c_err );
+    //      if (c_err.value.value() != 0)
+    //        System.err.println("getDocument() error " + c_err.value.value());
+    //      return NzdlCorbaFactory.toString( c_response.value.doc );
+    String collectionName = NzdlCorbaFactory.toString(collection);
+    String documentID = NzdlCorbaFactory.toString(request.value.OID);
+    String doc = nzdl.getDocument( collectionName, documentID );
+    response.value.doc = NzdlCorbaFactory.toCorbaText(doc);
+    error.value = corbaComError.from_int(corbaComError._corbaNoError);
+    return;
+  }
+
+  public void getCollectInfo (corbatext_t collection, 
+			      corbaColInfoResponseHolder response, 
+			      corbaComErrorHolder error) {
+    //      corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    //      corbaColInfoResponseHolder c_info = NzdlCorbaFactory.createColInfoResponseHolder();
+    //      m_nzdlServer.getCollectInfo( NzdlCorbaFactory.toCorbaText(_name), c_info, c_err );
+    //      if (c_err.value.value() != 0)
+    //        System.err.println("getCollectionInfo() error " + c_err.value.value());
+    //      return new NzdlCollectionInfo( c_info.value );
+    String collectionName = NzdlCorbaFactory.toString(collection);
+    NzdlCollectionInfo info = nzdl.getCollectionInfo( collectionName );
+    response.value = info.getInfo();
+    error.value = corbaComError.from_int(corbaComError._corbaNoError);
+    return;
+  }
+
+  public void getFilterInfo (corbatext_t collection, 
+			     corbatext_tarrayHolder filterNames, 
+			     corbaComErrorHolder error) {
+    String collectionName = NzdlCorbaFactory.toString(collection);
+ 
+    Set set = nzdl.getFilterSet(collectionName);
+
+    Iterator itr = set.iterator();
+    int i = 0;
+    while (itr.hasNext()) {
+      String s = (String) itr.next();
+      filterNames.value[i++] = NzdlCorbaFactory.toCorbaText(s);
+    }
+
+    error.value = corbaComError.from_int(corbaComError._corbaNoError);
+    return;
+  }
+
+  public void getFilterOptions (corbatext_t collection, 
+				corbatext_t option, 
+				corbaFilterOptionsResponseHolder response, 
+				corbaComErrorHolder error) {
+    String collectionName = NzdlCorbaFactory.toString(collection);
+    System.err.println("TO BE IMPLEMENTED: DON'T KNOW HOW YET !!! (getFilterOptions)");
+
+    error.value = corbaComError.from_int(corbaComError._corbaProtocolError);
+    return;
+  }
+
+  public  void filter (corbatext_t collection, 
+		       corbaFilterRequest request, 
+		       corbaFilterResponseHolder response, 
+		       corbaComErrorHolder error) {
+    //corbatext_t c_name = NzdlCorbaFactory.toCorbaText( _name );
+    //corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
+    //m_nzdlServer.filter( c_name, _request.getFilter(), _response.getHolder(), c_err );
+    //if (c_err.value.value() != 0)
+    //  System.err.println("service() error " + c_err.value.value());
+    error.value = corbaComError.from_int(corbaComError._corbaNoError);
+
+    String collectionName = NzdlCorbaFactory.toString(collection);
+    NzdlRequest _request = new NzdlRequest(request);
+    NzdlResponse _response = new NzdlResponse();
+    _response.setResponse(response.value);
+
+    try {
+      nzdl.service(collectionName,_request,_response);
+    } catch (Throwable t) {
+          error.value = corbaComError.from_int(corbaComError._corbaProtocolError);
+    }
+    return;
+  }
+}
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlWrapper.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlWrapper.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/NzdlWrapper.java	(revision 21017)
@@ -0,0 +1,188 @@
+/*
+ *    NzdlWrapper.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.service;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+
+
+/**
+ *  A Wrapper around an NzdlService object that adds functionality. 
+ *
+ * Typically one or more of the methods will be overridden to 
+ * add that functionality
+ *
+ * @author Brett Sheeran (bsheeran@xtra.co.nz) (comments)
+ * @author Stuart Yeates  (say1@cs.waikato.ac.nz)
+ * @version $Revision$
+ */
+abstract public class NzdlWrapper
+  extends java.lang.Object 
+  implements NzdlService {
+
+  private NzdlService service = null;
+  /** 
+   * The bean constructor ...
+   */
+  public NzdlWrapper() {
+    this.service = null;
+  }
+  /** 
+   * The normal constructor
+   */
+  public NzdlWrapper(NzdlService service) {
+    this.service = service;
+  }
+
+  /**
+   * Allow the client to configure a CORBA server.
+   * @param key the parameter to be set.
+   * @param values what that parameter will be set to.
+   */
+  public void configure( String _key, Set _values ) {
+    service.configure(_key, _values);
+  }
+
+  /**
+   * Obtain the set of collection names for a Greenstone library.
+   * @return A set of collection names in string format.
+   */
+  public Set getCollectionSet( ) {
+    return service.getCollectionSet();
+  }
+
+  /**
+   * Check if ORB knows of this collection.
+   * @param name the name of a collecion to be searched for.
+   * @return boolean <TT>true</TT> if collection is found, else <TT>false</TT>.
+   */
+  public boolean hasCollection( String _name ) {
+    return service.hasCollection(_name);
+  }
+
+
+  /**
+   * Check if ORB can communicate with of this collection.
+   * @param name the name of a collecion to be pinged.
+   * @return boolean <TT>true</TT> if collection returned ping, else
+   * <TT>false</TT>.
+   */
+  public boolean pingCollection( String _name ) {
+    return service.pingCollection(_name);
+  }
+
+  /**
+   * Extract information on this collection into a
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} object
+   * @param name the collection to be retrieved.
+   * @return an instance of
+   * {@link NzdlCollectionInfo NzdlCollectionInfo} containing data on a
+   * collection
+   */
+  public NzdlCollectionInfo getCollectionInfo( String _name ) {
+    return service.getCollectionInfo(_name);
+  }
+
+  /**
+   * Returns the set of filter options for a particular filter
+   * @param name the collection name
+   * @param filter the filter name
+   * @return an instance of
+   * {@link NzdlFilterOptions NzdlFilterOptions} containing the filter
+   * options for a filter
+   */
+    public NzdlFilterOptions getFilterOptionSet(String _name, String _filter){
+	return service.getFilterOptionSet(_name, _filter);
+    }
+
+  /**
+   * Returns the set of filters for the service object.
+   * @param name the collection name
+   * @return a set of strings that name the filters, for example
+   * BrowseFilter, QueryFilter and NullFilter.
+   */
+  public Set getFilterSet( String _name ) {
+    return service.getFilterSet(_name);
+  }
+
+  /**
+   * @param name the collection name
+   * @return the Set of (name, value) value pairs for all metadata 
+   * associated with a collection  
+   */
+  public Set getMetaTagSet( String _name ) {
+    return service.getMetaTagSet(_name);
+  }
+
+  /**
+   * Returns the Greenstone Markup Language (GML) text for a particular
+   * document from a collection.
+   * @param name the name of the collection.
+   * @param docID the document identity string
+   * @return the GML document in the form of a string.
+   */
+  public String getDocument( String _name, String _docID ) {
+    return service.getDocument(_name, _docID);
+  }
+
+  /**
+   * Returns the set of value(s) for a metatag from a particular document.
+   * @param name collection name
+   * @param docID the document identifier.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The set of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Set getMetaData( String _name, String _docID, String _metaTag ) {
+    return service.getMetaData( _name, _docID, _metaTag );
+  }
+
+  /**
+   * Returns a map of value(s) for a metatag from a list of documents.
+   * @param name collection name
+   * @param docIDs a list of document identifier strings.
+   * @param metaTag the metatag name such as: Title, Author, Date and Images.
+   * @return The map of value(s) for the requested metatag and document. In
+   * cases such as Title, Author, Date there will probably be only one value
+   * per document.
+   */
+  public Map getMetaData( String _name, List _docIDs, String _metaTag ) {
+    return service.getMetaData( _name, _docIDs, _metaTag );
+  }
+
+  /**
+   * Services a {@link NzdlRequest NzdlRequest} to a collection and places
+   * the results into a {@link NzdlResponse NzdlResponse} object. <br>
+   * Pre:   Created instances of NzdlRequest and NzdlResponse. <br>
+   * Post: Placed the result data into NzdlResponse object.
+   * @param name the collection name.
+   * @param request an instance of NzdlRequest with query data to be serviced
+   * @param response an instance of NzdlResponse. where the results of
+   * sevciving the query will be placed
+   */
+  public void service( String _name, NzdlRequest _request, 
+		       NzdlResponse _response ) {    
+    service.service(_name,_request,_response);
+  }
+  
+}
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/package.html
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/package.html	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/service/package.html	(revision 21017)
@@ -0,0 +1,156 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.16-22 i686) [Netscape]">
+   <title>: Package org.nzdl.gsdl.service</title>
+<!--NewPage-->
+<!-- Generated by javadoc on Thu Mar 08 23:01:13 GMT+13:00 2001 -->
+</head>
+<body bgcolor="#FFFFFF">
+Provides services for java client-side communication
+to a Greenstone Digital Library via CORBA.
+<br>&nbsp;
+<h2>
+Further Requirements</h2>
+
+<ul>
+<li>
+Sun Java 2 version 1.3 (or later)</li>
+
+<li>
+Corbaserver, a server-side application for communicating to a Greenstone
+Digital Library.</li>
+</ul>
+
+<h2>
+Java Interface Data Flows</h2>
+
+<center><img SRC="nzdl-service-package.png" ALT="NZDL Data Flow Diagram" height=280 width=637></center>
+
+<p><br>
+<h2>
+A Typical Query</h2>
+From a users perspective, a typical query may work&nbsp; as follows:
+<ul>
+<li>
+&nbsp;Create instances of the necessary NZDL Java-Client objects:</li>
+
+<ul>
+<li>
+&nbsp; a <b>NzdlQuery</b> object</li>
+
+<li>
+&nbsp; a <b>NzdlRequest </b>object using your <b>NzdlQuery</b> object</li>
+
+<li>
+&nbsp; a <b>NzdlResponse</b> object that will eventually hold response
+data</li>
+
+<li>
+&nbsp; a <b>NzdlService</b> object to service CORBA interface requests
+to a Greenstone collection</li>
+</ul>
+
+<li>
+Use the <b>NzdlService</b> object (with collection name and <b>NzdlRequest
+</b>object)
+to query the CORBA interface and place the reply into the <b>NzdlResponse</b>
+object.</li>
+
+<li>
+Create an instance of the <b>NzdlResultSet</b> object. Use <b>NzdlResponse.getResultSet()
+</b>to
+extract response data into the <b>NzdlResultSet</b> object.</li>
+
+<li>
+Use the <b>NzdlResultSet</b> methods to view data such as document IDs</li>
+
+<br>Get documents using <b>NzdlService.getDocument()</b></ul>
+
+<h1>
+Sample Code</h1>
+Below is a trivial example of a client application. For a more elaborate
+example, see <a href="../SimpleClient.html">SimpleClient</a>.
+<p>In order to function, this app needs Corbaserver running on the same
+machine.
+<br>&nbsp;
+<p><tt>/**</tt>
+<br><tt>* TrivialDemo.java.</tt>
+<br><tt>* A very simple client application that:</tt>
+<br><tt>* - Creates a service object using an Interoperable</tt>
+<br><tt>*&nbsp;&nbsp; Object Reference (IOR) from a file;</tt>
+<br><tt>* - lists all available collections;</tt>
+<br><tt>* - searches "demo" collection for "snail farming";</tt>
+<br><tt>* - prints the number of hits;</tt>
+<br><tt>* - lists first 10 titles found;</tt>
+<br><tt>* - displays the unformatted text of first document found.</tt>
+<br><tt>*/</tt>
+<br><tt>import java.io.*;</tt>
+<br><tt>import java.util.*;</tt>
+<br><tt>import java.lang.*;</tt>
+<br><tt>import org.nzdl.gsdl.service.*; //the java-client stuff</tt>
+<br><tt>import org.nzdl.gsdl.util.NzdlServiceFactory</tt>
+<p><tt>public class TrivialDemo {</tt>
+<br><tt>&nbsp; public static void main( String [] args )</tt>
+<br><tt>&nbsp; {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; String myQueryString = "snail farming";</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; String myCollection = "demo";</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // Create a Service Object</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; NzdlService myService = NzdlServiceFactory.CreateNzdlService(args,</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+System.getProperties(), null, null, null);</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // Use getCollectionSet to obtain List of Collections</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; Set myCollections = myService.getCollectionSet();</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; //Display List of Collections</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; System.out.println("\nThe available collections:");</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; for (Iterator i = myCollections.iterator(); i.hasNext();
+)</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String collName = (String)
+i.next();</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("&nbsp;
+"+ collName);</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // Create query object</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; NzdlQuery query = new NzdlQuery( myQueryString
+);</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // Create request object</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; NzdlRequest request = new NzdlRequest( query
+);</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // create response object</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; NzdlResponse response = new NzdlResponse( );</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // use service to get response from request to
+myCollection</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; myService.service( myCollection, request, response
+);</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // use getResultSet to get results from response</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; NzdlResultSet results = response.getResultSet();</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // getNumOfDocs</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; System.out.println("\nNumber of hits = "+results.getNumOfDocs());</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // Use getDocumentIDs to build list of titles
+(defaults: 1 - 10)</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; List docIDs = results.getDocumentIDs();</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; System.out.println("\nThe titles:");</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; for (ListIterator i = docIDs.listIterator();
+i.hasNext(); )</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; {</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set metaData</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = myService.getMetaData(
+myCollection,(String)i.next(),"Title");</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Iterator j = metaData.iterator();</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(j.next());
+//print title metadata</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; }</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; System.out.println("\nThe first document returned
+was:");</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; // Print first document returned</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; String myDoc</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = myService.getDocument(myCollection,(String)docIDs.get(0));</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; System.out.println(myDoc);</tt>
+<p><tt>&nbsp;&nbsp;&nbsp; } // end of main</tt>
+<br><tt>} // end of demo class</tt>
+<br>&nbsp;
+<br>&nbsp;
+</body>
+</html>
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/Makefile
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/Makefile	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/Makefile	(revision 21017)
@@ -0,0 +1,32 @@
+#name/location of java compiler
+JAVAC=javac
+
+#javac options
+#JAVACOPTIONS= -g:none -O
+#JAVACOPTIONS= -deprecation -g:lines
+
+#complete compilation
+JAVACOMPILE=$(JAVAC) $(JAVACOPTIONS)
+
+#make a .class file from a .java file
+%.class: %.java
+	$(JAVAC) $(JAVACOPTIONS)  $<
+
+CLASSFILES=NzdlPreferences.class\
+     NzdlConstants.class  \
+     NzdlCorbaFactory.class  \
+     NzdlHosts.class  \
+     NzdlServiceFactory.class
+
+all: $(CLASSFILES)
+
+clean:
+	rm -f *.class
+
+
+
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlConstants.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlConstants.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlConstants.java	(revision 21017)
@@ -0,0 +1,107 @@
+/*
+ *    NzdlConstants.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.util;
+
+/**
+ * Contains default values for: query and other stuff.
+ *
+ * @author Stuart Yeates   (say1@cs.waikato.ac.nz)
+ * @author Aziz Mahoui     (amahoui@yahoo.com)
+ * @author Gordon Paynter  (paynter@cs.waikato.ac.nz)
+ * @author Dave Nichols    (daven@cs.waikato.ac.nz)
+ * @author George Buchanan (g.buchanan@mdx.ac.uk)
+ * @version $Revision$
+ */
+public interface NzdlConstants {
+
+  String DEFAULT_QUERY_TERM   = "";
+  String DEFAULT_QUERY_TYPE   = "ranked";
+  boolean DEFAULT_CASE_FOLDING = true;
+  boolean DEFAULT_STEMMING     = false;
+  String DEFAULT_CASE_FOLDING_STRING = "true";
+  String DEFAULT_STEMMING_STRING     = "false";
+  boolean DEFAULT_QUERY_META  = false;
+  String BOOLEAN_STRING = "boolean";
+  String RANKED_STRING = "ranked";
+ 
+
+
+  /* Greenstone metadata names */
+
+
+  String LONG_COLLECTION_NAME = "collectionname";
+  String ICON = "iconcollection";
+  String SMALL_ICON = "iconcollectionsmall";
+  String COLLECTION_DESCRIPTION = "collectionextra";
+ 
+ 
+
+  int    DEFAULT_START_RESULTS = 1;
+  int    DEFAULT_END_RESULTS   = 10;
+  int    DEFAULT_MAX_DOCS      = 200;
+
+    /* preferences not under explicit dialog/user control */
+    
+
+    String STEMMING = "stemming";
+    String CASE_FOLDING = "casefolding";
+    String QUERYTYPE = "querytype";
+
+
+  /* Preference Strings */
+  
+  String DISPLAY_FIRST_DOC = "Automatically display the first document";
+  String RAW_TEXT = "Always display raw text (don't interpret HTML)";
+  String MULTIPLE_SERVERS =  "Connect to multiple servers";
+  String LOG_SERVICE = "Log at the NzdlService level";
+  String CACHE_CORBA = "Cache corba requests";
+  String SAVE_DOCS = "Save documents";
+  
+/* these appear to have been generated by 
+the idlj compiler but not any more - so 
+they are are being placed here */
+
+public static final int FRtermFreq = 1;
+public static final int FRmatchterms = 2;
+public static final int FROID = 4 ;
+public static final int FRsubcol = 8;
+public static final int FRranking = 16;
+public static final int FRdocFreq = 32;
+public static final int FRmetadata = 64;
+public static final int FRfullTextBrowse = 128;
+
+/* The constants above are based on these definitions from the C++ receptionist
+
+#define FRtermFreq   1
+#define FRmatchTerms 2
+#define FROID        4
+#define FRsubCol     8
+#define FRranking    16
+#define FRdocFreq    32
+#define FRmetadata   64
+// used to indicate a full text browse query for mgpp
+#define FRfullTextBrowse  128
+
+*/
+
+}
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlCorbaFactory.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlCorbaFactory.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlCorbaFactory.java	(revision 21017)
@@ -0,0 +1,318 @@
+/*
+ *    NzdlCorbaFactory.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.util;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.nzdl.gsdl.service.NzdlQuery;
+import org.nzdl.gsdl.service.NzdlBrowse;
+import org.nzdl.gsdl.corba.gsdlInterface.*;
+import org.nzdl.gsdl.util.NzdlConstants;
+
+/**
+ * Returns CORBA objects via it's operations.
+ */
+public final class NzdlCorbaFactory {
+
+
+  private NzdlCorbaFactory() {}
+
+  public static corbatext_t toCorbaText(String _text) {
+    int len = _text.length();
+    short[] shorts = new short[len];
+    for (int i=0; i<len; i++) {
+      shorts[i] = (short)_text.charAt(i);
+    }
+    short encoding = 0;
+    corbatext_t corba_t = new corbatext_t(shorts, encoding, len);
+    return corba_t;
+  }
+
+  public static String toString(corbatext_t _text) {
+    //    System.out.println("NzdlCorbaFactory.toString() called length = " + _text.text.length +
+    //		       " ecnoding = " + _text.encoding +
+    //		       " reported length = " + _text.length);
+    StringBuffer text = new StringBuffer(1000);
+    for (int j=0; j<_text.text.length; j++) {
+      text.append((char)_text.text[j]);
+    }
+    return text.toString();
+  }
+
+  public static corbaComErrorHolder createComErrorHolder() {
+    corbaComErrorHolder err
+      = new corbaComErrorHolder( corbaComError.from_int(0) );    
+    return err;
+  }
+
+  public static corbatext_tarrayHolder createCorbaTextArrayHolder() {
+    corbatext_t [] array = {};
+    corbatext_tarrayHolder arrayHolder = new corbatext_tarrayHolder( array );
+    return arrayHolder;
+  }
+
+  public static Set  toSet( corbatext_t [] _configLines ) {
+    HashSet set = new HashSet();
+      for (int i=0; i<_configLines.length; i++) {
+	set.add(NzdlCorbaFactory.toString(_configLines[i]));
+      }
+      return set;
+  }
+
+  public static corbatext_t []  toCorbaTextArray( Set _configLines ) {
+    Object [] lines = _configLines.toArray();
+    corbatext_t [] array = new corbatext_t[ lines.length ];
+    for (int i=0; i<lines.length; i++) {
+      array[i] = toCorbaText( (String)lines[i] );
+    }
+    return array;
+  }
+
+  public static corbaColInfoResponseHolder createColInfoResponseHolder() {
+    corbaShortColInfo shortInfo = new corbaShortColInfo();
+    shortInfo.name = toCorbaText("");
+    shortInfo.host = toCorbaText("");
+    corbaColInfoResponse response = new corbaColInfoResponse();
+    response.shoftInfo = shortInfo; // shoft !! typo in corba interface !!
+    response.isPublic  = false;
+    response.isBeta    = false;
+    response.buildDate = 0;
+    response.ccsCols   = new corbatext_t[0];
+    response.languages = new corbatext_t[0];
+    response.numDocs   = 0;
+    response.numWords  = 0;
+    response.numBytes  = 0;
+    response.collectionMeta = new corbatext_tmap(new corbatext_t[0],new corbatext_t[0]);
+    response.format         = new corbatext_tmap(new corbatext_t[0],new corbatext_t[0]);
+    response.building       = new corbatext_tmap(new corbatext_t[0],new corbatext_t[0]);
+    response.httpdomain   = toCorbaText("");
+    response.httpprefix   = toCorbaText("");
+    response.receptionist = toCorbaText("");
+    corbaColInfoResponseHolder responseHolder 
+      = new corbaColInfoResponseHolder(response);
+    return responseHolder;
+  }
+    
+  public static corbaFilterRequest 
+    createQueryFilterRequest( String _term, String _type, int _numOfHits ) {
+    return createQueryFilterRequest( _term,
+				     _type,
+				     String.valueOf(NzdlConstants.DEFAULT_CASE_FOLDING),
+				     String.valueOf(NzdlConstants.DEFAULT_STEMMING),
+				     String.valueOf(NzdlConstants.DEFAULT_START_RESULTS),
+				     String.valueOf(_numOfHits),
+				     String.valueOf(NzdlConstants.DEFAULT_MAX_DOCS),
+				     NzdlConstants.DEFAULT_QUERY_META,
+				     new String("")
+				     );
+  }
+
+  public static corbaFilterRequest 
+    createQueryFilterRequest( NzdlQuery _query ) {
+	return createQueryFilterRequest( _query.getQueryTerm(),
+				     _query.getQueryType(),
+				     _query.getCaseFolding(),
+				     _query.getStemming(),
+				     String.valueOf(_query.getStartResults()),
+				     String.valueOf(_query.getEndResults()),
+				     String.valueOf(_query.getMaxDocs()),
+					 _query.getMetadata(),
+					 _query.getIndex()
+				     );
+  }
+
+
+  public static corbaFilterRequest 
+    createQueryFilterRequest( String _term, String _type,     String _case, 
+			      String _stem, String _startHit, String _endHit, String _maxDocs) {
+		return createQueryFilterRequest(_term, _type, _case, _stem, _startHit, _endHit, _maxDocs,
+		                                NzdlConstants.DEFAULT_QUERY_META, new String("")
+						 );
+	}
+
+  public static corbaFilterRequest 
+    createQueryFilterRequest( String _term, String _type,     String _case, 
+			      String _stem, String _startHit, String _endHit, String _maxDocs, boolean _meta, String _index ) {
+
+    corbaFilterRequest queryFilter = new corbaFilterRequest();
+    queryFilter.filter        = toCorbaText("QueryFilter");
+
+    queryFilter.filterOptions = new corbaOptionValue[9];
+    queryFilter.filterOptions[0] 
+      = new corbaOptionValue(toCorbaText("Term"),
+			     toCorbaText(_term));
+    queryFilter.filterOptions[1] 
+      = new corbaOptionValue(toCorbaText("QueryType"),
+			     toCorbaText(_type));
+    queryFilter.filterOptions[2] 
+      = new corbaOptionValue(toCorbaText("Casefold"),
+			     toCorbaText(_case));
+    queryFilter.filterOptions[3] 
+      = new corbaOptionValue(toCorbaText("Stem"),
+			     toCorbaText(_stem));
+    queryFilter.filterOptions[4] 
+      = new corbaOptionValue(toCorbaText("StartResults"),
+			     toCorbaText(_startHit));
+    queryFilter.filterOptions[5] 
+      = new corbaOptionValue(toCorbaText("EndResults"),
+			     toCorbaText(_endHit));
+    queryFilter.filterOptions[6] 
+      = new corbaOptionValue(toCorbaText("Maxdocs"),
+			     toCorbaText(_maxDocs));
+
+      queryFilter.filterOptions[7] 
+        = new corbaOptionValue(toCorbaText("MatchMode"),
+  			     toCorbaText("all"));
+      queryFilter.filterOptions[8]
+	  = new corbaOptionValue(toCorbaText("Index"),
+				 toCorbaText(_index));
+
+    queryFilter.docSet        = new corbatext_t[0];
+    int resultOptions = NzdlConstants.FROID|NzdlConstants.FRtermFreq|NzdlConstants.FRranking;
+		if (_meta)
+		{	resultOptions |= NzdlConstants.FRmetadata;
+		}
+    queryFilter.filterResultOptions = resultOptions;
+    queryFilter.requestParams = toCorbaText("");
+    queryFilter.refParams     = toCorbaText("");
+    queryFilter.fields        = new corbatext_t[0];
+    queryFilter.getParents    = false;
+    return queryFilter;
+  }
+  
+  public static corbaFilterRequest 
+    createBrowseFilterRequest( NzdlBrowse _browse ) {
+    return createBrowseFilterRequest( _browse.getBrowseNode(), _browse.getMetadata());
+  }
+
+  public static corbaFilterRequest createBrowseFilterRequest(String _docID, String _metaTag) {
+
+    corbaFilterRequest browseFilter = new corbaFilterRequest();
+    browseFilter.filter        = toCorbaText("BrowseFilter");
+
+    browseFilter.filterOptions = new corbaOptionValue[1];
+    browseFilter.filterOptions[0] 
+      = new corbaOptionValue(toCorbaText("ParentNode"),
+			     toCorbaText(_docID));
+
+    browseFilter.docSet        = new corbatext_t[0];
+    int resultOptions = NzdlConstants.FROID|NzdlConstants.FRmetadata;
+    browseFilter.filterResultOptions = resultOptions;
+    browseFilter.requestParams = toCorbaText("");
+    browseFilter.refParams     = toCorbaText("");
+    browseFilter.fields        = new corbatext_t[1];
+    browseFilter.fields[0]     = toCorbaText(_metaTag);
+    browseFilter.getParents    = false;
+    return browseFilter;
+  }
+
+  public static corbaFilterRequest createBrowseFilterRequest( String _docID ) {
+    corbaFilterRequest browseFilter = new corbaFilterRequest();
+    browseFilter.filter        = toCorbaText("BrowseFilter");
+    browseFilter.filterOptions = new corbaOptionValue[1];
+    browseFilter.filterOptions[0] 
+      = new corbaOptionValue(toCorbaText("ParentNode"),
+			     toCorbaText(_docID));
+    browseFilter.docSet        = new corbatext_t[0];
+    int resultOptions = NzdlConstants.FROID;
+    browseFilter.filterResultOptions = resultOptions;
+    browseFilter.requestParams = toCorbaText("");
+    browseFilter.refParams     = toCorbaText("");
+    browseFilter.fields        = new corbatext_t[0];
+    browseFilter.getParents    = false;
+    return browseFilter;
+  }
+
+  public static corbaFilterRequest createMetaDataFilterRequest( String _docID, String _metaTag ) {
+    corbaFilterRequest nullFilter = new corbaFilterRequest();
+    nullFilter.filter        = toCorbaText("NullFilter");
+    nullFilter.filterOptions = new corbaOptionValue[0];
+    nullFilter.docSet        = new corbatext_t[1];
+    nullFilter.docSet[0]     = toCorbaText(_docID);
+    int resultOptions = NzdlConstants.FRmetadata;
+    nullFilter.filterResultOptions = resultOptions;
+    nullFilter.requestParams = toCorbaText("");
+    nullFilter.refParams     = toCorbaText("");
+    nullFilter.fields        = new corbatext_t[1];
+    nullFilter.fields[0]     = toCorbaText(_metaTag);
+    nullFilter.getParents    = false;
+    return nullFilter;
+  }
+
+  public static corbaFilterRequest createMetaDataFilterRequest( List _docIDs, String _metaTag ) {
+    corbaFilterRequest nullFilter = new corbaFilterRequest();
+    nullFilter.filter = toCorbaText("NullFilter");
+    nullFilter.filterOptions = new corbaOptionValue[0];
+    // we will request the meta data for all documents in _docIDs set
+    nullFilter.docSet = new corbatext_t[_docIDs.size()];
+    int i=0;
+    for (ListIterator itr = _docIDs.listIterator(); itr.hasNext(); ) {
+      nullFilter.docSet[i] = toCorbaText( (String)itr.next() );
+      i++;
+    }
+    int resultOptions = NzdlConstants.FRmetadata;
+    nullFilter.filterResultOptions = resultOptions;
+    nullFilter.requestParams = toCorbaText("");
+    nullFilter.refParams     = toCorbaText("");
+    nullFilter.fields        = new corbatext_t[1];
+    // this is the meta (_metaTag) data we need
+    nullFilter.fields[0]     = toCorbaText(_metaTag);
+    nullFilter.getParents    = false;
+    return nullFilter;
+  }
+
+  public static corbaFilterResponseHolder createFilterResponseHolder() {
+    corbaFilterResponse responseFilter = new corbaFilterResponse();
+    responseFilter.numDocs = 0;
+    responseFilter.isApprox = corbaIsApprox.from_int(0);
+    responseFilter.termInfo = new corbaTermInfo[0];
+    responseFilter.docInfo = new corbaResultDocInfo[0];
+    return new corbaFilterResponseHolder(responseFilter);
+  }
+
+    // created 25-4-02 kjdon
+    public static corbaFilterOptionsResponseHolder createFilterOptionsResponseHolder() {
+	corbaFilterOptionsResponse response = new corbaFilterOptionsResponse();
+	response.options = new corbaFilterOption[0];
+	response.names = new corbatext_t[0];
+	return new corbaFilterOptionsResponseHolder(response);
+    }
+
+  public static corbaDocRequestHolder createDocRequestHolder( String _docID ) {
+    corbaDocRequest docRequest 
+      = new corbaDocRequest( toCorbaText( _docID ), toCorbaText(""), toCorbaText("") );
+    return new corbaDocRequestHolder(docRequest);
+  }
+
+  public static corbaDocResponseHolder createDocResponseHolder( ) {
+    corbaDocResponse docResponse = new corbaDocResponse( toCorbaText("") );
+    return new corbaDocResponseHolder( docResponse );
+  }
+
+}
+
+
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlHosts.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlHosts.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlHosts.java	(revision 21017)
@@ -0,0 +1,231 @@
+/*
+ *    TODO.java
+ *    Copyright (C) 2000 Stuart Yeates
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl.util;
+
+// java standard library classes used
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.Cloneable;
+import java.util.Properties;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import org.omg.CORBA.Object;
+import org.omg.CORBA.ORB;
+import java.net.URL;
+
+import org.nzdl.gsdl.service.*;
+
+/**
+ * Used to get host information including: name, IOR and URL.
+ *
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @author  George Buchanan (g.buchanan@mdx.ac.uk)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.SimpleClient
+ * @see org.nzdl.gsdl.SimpleServer
+ *
+ */
+
+public class NzdlHosts implements Cloneable, Serializable {
+  
+  static String propertiesFileName = "NZDLServers.properties";
+
+  static String defaultHostName = "nzdl2.cs.waikato.ac.nz";
+
+  protected Properties table;
+
+  private static NzdlHosts singleton = new NzdlHosts();
+  
+  private NzdlHosts()
+  {
+    table = new Properties();
+    
+    try {
+      File file = new File(propertiesFileName);
+      if (file.exists() && file.canRead())
+	table.load(new FileInputStream(file));
+      else {
+	table.put("mdxlite", "ickenham.mdx.ac.uk");
+	table.put("nzdl2", "nzdl2.cs.waikato.ac.nz");
+	table.put("csdl1", "csdl1.mdx.ac.uk");
+      }
+    } catch (IOException exception) {
+      System.err.println("NzdlHosts::NzdlHosts() error reading properties file: " + 
+			 exception);
+    }
+  }
+
+  public void finalize() {
+    tidy();
+  }
+
+  static public void tidy() {
+    if (singleton == null)
+      singleton = new NzdlHosts();
+    try {
+      File file = new File(propertiesFileName);
+      if (file.canWrite() || !file.exists())
+	singleton.table.store(new FileOutputStream(file),"NZDL hosts we know about");
+      else {
+	System.err.println("NzdlHosts::tidy() unable ");
+      }
+    } catch (IOException exception) {
+      System.err.println("NzdlHosts::NzdlHosts() error reading properties file: " + 
+			 exception);
+    }
+  }
+  
+
+  static public void addHost(String code, String url)
+  {
+    if (singleton == null)
+      singleton = new NzdlHosts();
+    singleton.table.put(code, url);
+  }
+
+
+  static public String getFullName(String code)
+  {
+    if (singleton == null)
+      singleton = new NzdlHosts();
+    String reply;
+    reply = (String) singleton.table.get(code);
+    System.out.println("Read " + reply);
+    if (reply == null)
+      {       
+	return defaultHostName;
+      }
+    return reply;
+  }
+
+  static public String getUrlFromSite(String sitename)
+  {
+    return "http://" + sitename + "/cgi-bin/getior";
+  }
+
+  static public String getUrlFromCode(String code)
+  {
+    return "http://" + getFullName(code) + "/cgi-bin/getior";
+  }
+
+    static String getIOR(URL url)
+    {
+	try {
+	    InputStream his = url.openStream();
+	    DataInputStream dhis = new DataInputStream(his) ;
+	    String ior = dhis.readLine();
+	    System.out.println(ior);
+	    return ior;
+	}
+	catch (Throwable throwable) {
+	    System.err.println("NzdlHosts:getIOR() unable to communicate with URL \"" + url + "\"");
+	}
+	return "";
+    }
+
+  static public String getIOR(String code)
+  {
+    if (singleton == null)
+      singleton = new NzdlHosts();
+
+    String str = getUrlFromCode(code);
+    String ior = null;
+    URL    url;
+
+    try { 
+	url = new URL(str);
+    }
+    catch (Throwable malEx) {
+      System.err.println("NzdlHosts::getIOR() unable to construct or read URL \"" +
+			 str + "\", \"" + ior + "\": " + malEx);
+      return "";
+    }
+
+    return getIOR(url);
+  }
+
+  static public NzdlService getHost(String code) {
+    NzdlService nzdl = null;
+
+    try {
+      nzdl = new NzdlServiceClient(null,null,getIOR(code));
+    } catch (Throwable throwable) {
+      System.err.println("NzdlHosts::getHost() constructing NzdlServiceClient(" + 
+			   code + ") " + throwable);
+    }
+    return nzdl;
+  }
+
+  static public NzdlService getSite(String sitename) {
+    NzdlService nzdl = null;
+
+    try {
+	String siteUrl = getUrlFromSite(sitename);
+	URL url = new URL(siteUrl);
+      nzdl = new NzdlServiceClient(null,null,getIOR(url));
+    } catch (Throwable throwable) {
+      System.err.println("NzdlHosts::getHost() constructing NzdlServiceClient(" + 
+			   sitename + ") " + throwable);
+    }
+    return nzdl;
+  }
+
+  static public Vector getAllHosts() {
+    if (singleton == null)
+      singleton = new NzdlHosts();
+
+    Vector results = new Vector();
+
+    Enumeration e = singleton.table.keys();
+    while (e.hasMoreElements()) {
+      String code = (String) e.nextElement();
+      try {
+	NzdlService nzdl = new NzdlServiceClient(null,null,getIOR(code));
+	results.addElement(nzdl);
+      } catch (Throwable throwable) {
+	System.err.println("NzdlHosts::getHost() constructing NzdlServiceClient(" + 
+			   code + "): " + throwable);
+      }
+    }
+    return results;
+  }
+
+  static public NzdlService hostFromCommandlineArgs(String [] _args, Properties _props) {
+    NzdlService nzdl = null;
+
+    try {
+      nzdl = new NzdlServiceClient( _args, _props, null);
+    } catch (Throwable throwable) {
+      System.err.println("NzdlHosts::hostFromCommandlineArgs() constructing " +
+			 "NzdlServiceClient() " + throwable);
+      
+    }
+    return nzdl;
+  }
+}
+
+
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlPreferences.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlPreferences.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlPreferences.java	(revision 21017)
@@ -0,0 +1,145 @@
+/*
+ *    NzdlPreferences.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+//the package we're in
+package org.nzdl.gsdl.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Hashtable;
+import java.util.Properties;
+
+
+/**
+ * Stores our preferences...
+ */
+public final class NzdlPreferences {
+  /** The hashtable we write to disk ... */
+  protected Properties _preferences = null;
+  /** 
+   * Should we save the preferences? Should normally be true for
+   * GUI work and false for commandline and/or server work.
+   */
+  public static boolean saving = true;
+  /** The singleton instance */
+  static NzdlPreferences instance = null;
+  static String preferencesFileName = "preferences";
+
+  protected NzdlPreferences() {
+    try {
+      _preferences = new Properties();
+      String dir = System.getProperties().getProperty("user.home");
+      String sep = System.getProperties().getProperty("file.separator");
+
+      File file = new File(dir + sep + preferencesFileName);
+      InputStream stream = new FileInputStream(file);
+      _preferences.load(stream);
+    } catch (Exception exception) {
+      System.out.println("Unable to load file " + preferencesFileName+ "\n" + exception);
+    }
+  }
+
+  public void save() {
+    if (!saving)
+      return;
+    try {
+      String dir = System.getProperties().getProperty("user.home");
+      String sep = System.getProperties().getProperty("file.separator");
+
+      File file = new File(dir + sep + preferencesFileName);
+      OutputStream stream = new FileOutputStream(file);
+      _preferences.store(stream,"Preferences ...");
+    } catch (Exception exception) {
+      System.out.println("Unable to save file " + preferencesFileName + "\n" + exception);
+      System.out.println("preferences =" + _preferences);
+    }
+  }
+  
+  /**
+   * Get the static Preferences object
+   */
+  public static NzdlPreferences getInstance() {
+    if (instance == null)
+      instance = new NzdlPreferences();
+    return instance;
+  }
+  /**
+   * Get a boolean preference
+   */
+  public static boolean getBoolean(String key){
+    String value = (String) getInstance()._preferences.get(key);
+    if (value == null)
+      {
+	setBoolean(key,false);
+	return false;
+      }
+    return Boolean.valueOf(value).booleanValue();
+  }
+  /**
+   * Set a boolean preference
+   */
+  public static void setBoolean(String key,boolean value) {
+    getInstance()._preferences.put(key,"" + value);
+    getInstance().save();
+  }
+
+
+    public static boolean isBoolean(String key) {
+	String value = (String) getInstance()._preferences.get(key);
+	if (value == null)
+		return false;
+	return true;
+    }
+
+  /**
+   * Get a String preference
+   */
+  public static String getString(String key){
+    String value = (String) getInstance()._preferences.get(key);
+    if (value == null)
+      {
+	setString(key,"");
+	return "";
+      }
+    return value;
+  }
+
+    public static boolean isString(String key){
+	//String value = (String) getInstance()._preferences.get(key);
+	if (getInstance()._preferences.get(key) == null )
+	    return false;
+	else
+	    return true;
+    }
+
+
+
+  /**
+   * Set a String preference
+   */
+  public static void setString(String key, String value) {
+    getInstance()._preferences.put(key, value);
+    getInstance().save();
+  }
+}
+
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlServiceFactory.java
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlServiceFactory.java	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/NzdlServiceFactory.java	(revision 21017)
@@ -0,0 +1,594 @@
+/*
+ *    NzdlServiceFactory.java
+ *    Copyright (C) 2001 New Zealand Digital Library Project
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software
+ *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+// the package we're in
+package org.nzdl.gsdl.util;
+
+// java libraries we're using
+import java.io.BufferedWriter;
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.Serializable;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Vector;
+import java.util.Hashtable;
+
+// local libraries
+import org.nzdl.gsdl.service.NzdlCollectionInfo; 
+import org.nzdl.gsdl.service.NzdlQuery;
+import org.nzdl.gsdl.service.NzdlRequest;
+import org.nzdl.gsdl.service.NzdlResponse;
+import org.nzdl.gsdl.service.NzdlResultSet;
+import org.nzdl.gsdl.service.NzdlService;
+import org.nzdl.gsdl.service.NzdlServiceClient;
+import org.nzdl.gsdl.service.NzdlCacheWrapper;
+import org.nzdl.gsdl.service.NzdlLogWrapper;
+import org.nzdl.gsdl.service.NzdlDocSaveWrapper;
+import org.nzdl.gsdl.service.NzdlMultiWayWrapper;
+
+/**
+ * Class NzdlServiceFactory
+ *
+ * A repositry for IORs of various NZDL servers we've seen.
+ * Finds IORs from sources such as: URL, file, string, or server based
+ * list of known IORs.
+ *
+ * @author stuart yeates (say1@cs.waikato.ac.nz)
+ * @author Brett Sheeran (bsheeran@xtra.co.nz)
+ * @author Dave Nichols (daven@cs.waikato.ac.nz)
+ * @author Gordon Paynter (paynter@cs.waikato.ac.nz)
+ * @version $Revision$
+ * @see org.nzdl.gsdl.SimpleServer
+ * @see org.nzdl.gsdl.service.NzdlCollectionInfo
+ * @see org.nzdl.gsdl.service.NzdlQuery
+ * @see org.nzdl.gsdl.service.NzdlRequest
+ * @see org.nzdl.gsdl.service.NzdlResponse
+ * @see org.nzdl.gsdl.service.NzdlResultSet
+ * @see org.nzdl.gsdl.service.NzdlService
+ * @see org.nzdl.gsdl.service.NzdlServiceClient
+ * @see gnu.getopt.Getopt
+ * @see gnu.getopt.LongOpt
+ * @see <a href="http://www.nzdl.org/">The New Zealand Digital Library Project</a>
+ * @see <a href="http://www.nzdl.org/fast-cgi-bin/library?&a=p&p=gsdl">Greenstone Digital Library Software</a>
+ */
+
+
+public class NzdlServiceFactory implements Cloneable, Serializable {
+
+  /** The collection of CORBA IORs we know about */
+  protected static Properties knownIORs = null;
+  /** The name of the properties file */
+  static String propertiesFileName = "knownIORs.properties";
+  /** The name of the file we look for IOR's in */
+  public static String IORFileName = "/tmp/localcorba.objid";
+
+  /** default places wit look for IORs ... */
+  static String[] urlsCompiledIn = 
+  { 
+    "http://nikau.cs.waikato.ac.nz/~say1/gsdl/cgi-bin/getior", 
+    "http://www.nzdl.org/cgi-bin/getior"
+  };
+
+
+  /**
+   * Get the first known-good IOR
+   * @see java.lang.String
+   * @return the string containing the IOR
+   */
+  public static String getFirstValid()  {
+    validate(); // implies checkLoaded();
+    try {
+	synchronized (knownIORs) {
+	    
+	    Enumeration e = knownIORs.keys();
+	    while (e.hasMoreElements()) {
+		String IOR = (String) e.nextElement();
+		if (attemptToInitialise(null, null, IOR) != null) {
+		    return IOR;
+		}
+	    }
+	}
+    } catch (Throwable t) {
+	System.out.println("Throwable in NzdlServiceFactory::getFirstValid()");
+    }
+    return null;
+  }
+  /**
+   * Get the all known-good IOR
+   * @see java.lang.String
+   * @return the string[] containing the IORs
+   */
+  public static String[] getAllValid()  {
+    checkLoaded();
+    Vector vec = new Vector();
+			    
+    synchronized (knownIORs) {
+      
+      Enumeration e = knownIORs.keys();
+      while (e.hasMoreElements()) {
+	String IOR = (String) e.nextElement();
+	if (attemptToInitialise(null, null, IOR) != null) {
+	  vec.add(IOR);
+	}
+      }
+    }
+    String[] strings = new String[vec.size()];
+    Enumeration e = vec.elements();
+    int i = 0;
+    while (e.hasMoreElements()) {
+       strings[i++] = (String) e.nextElement();
+    }
+    return strings;
+    
+  }
+  
+  /**
+   * Check that the class has been correctly initialised
+   */
+  static protected void checkLoaded()  {
+    // if we're already initialised we can bail now and
+    // save synchronization overhead ...
+    if (knownIORs != null)
+      return;
+
+    Properties blarg = new Properties();
+    
+    // take a lock on blarg. currently it's local, but 
+    // won't be soon...
+    synchronized (blarg) {
+
+      try {
+	synchronized (Class.forName("org.nzdl.gsdl.util.NzdlServiceFactory")) {
+	  if (knownIORs != null)
+	    return;
+	  knownIORs = blarg;
+	}
+      } catch (ClassNotFoundException exception) {
+	System.err.println("Exception locking class:" + exception);
+      }
+          
+      try {
+	String dir = System.getProperties().getProperty("user.home");
+	String sep = System.getProperties().getProperty("file.separator");
+	
+	File file = new File(dir + sep + propertiesFileName);
+	if (file.exists()) {
+	  knownIORs.load(new FileInputStream(file));
+	} 
+      } catch (IOException exception) {
+	System.err.println("Exception reading properties file:" + exception);
+      }
+    }
+    getIORsfromFile(IORFileName);
+  }
+
+  /**
+   * Save the IORs back to the underlying file
+   * @see java.io.File
+   */
+  static protected void checkSave()  {
+    synchronized (knownIORs) {
+      if (knownIORs == null)
+	throw new Error("saving null property list");
+      
+      File file = new File(propertiesFileName);
+      try {
+      String dir = System.getProperties().getProperty("user.home");
+      String sep = System.getProperties().getProperty("file.separator");
+
+	knownIORs.store(new FileOutputStream(dir + sep + file),
+			"NZDL IOR's see: org.nzdl.gsdl.util.NzdlServiceFactory");
+      } catch (IOException i) {
+	System.err.println("Error reading properties file:" + i);
+      }
+    }
+  }
+
+  /**
+   * Find a valid IOR to initialise from.
+   * @param _args the command line arguments
+   * @param _URL a URL to look for an IOR in
+   * @param _filename a local filename to look for an IOR in
+   * @param _IOR a string to look for an IOR in
+   * @see org.omg.CORBA.ORB
+   */
+  public static NzdlService findIOR(String [] _args,
+				    Properties _props, 
+				    String _URL,
+				    String _filename,
+				    String _IOR)  {
+    
+    // read our prevously seed IORs ...
+    String IOR = null;
+    NzdlService client = null;
+      
+    // try a URL from the command line
+    if ( _URL != null) {
+      String[] IORs = NzdlServiceFactory.getIORsfromURL(_URL);
+      for (int i=0;( i<IORs.length && client == null );i++) {
+	client = attemptToInitialise(_args, _props,IORs[i]);
+      }
+    }
+
+    // try an IOR from the command line
+    if (_IOR != null && client == null) {
+      IOR = NzdlServiceFactory.registerIOR(_IOR);
+      client = attemptToInitialise(_args, _props, IOR);
+    }
+    
+    // try an IOR from a file (the filename may have been 
+    // given from the commandline
+    if (client == null) {
+      String[] IORs = NzdlServiceFactory.getIORsfromFile(_filename);
+      for (int i=0;(IORs != null && i<IORs.length && client == null );i++) {
+	client = attemptToInitialise(_args, _props,IORs[i]);
+      }
+    }
+    
+    // try the compiled-in URLs
+    if (client == null && urlsCompiledIn != null) {
+      for (int i=0;( i<urlsCompiledIn.length && client == null );i++) {
+	String[] IORs = NzdlServiceFactory.getIORsfromURL(urlsCompiledIn[i]);
+	for (int j=0;(IORs != null && j<IORs.length && client == null );j++) {
+	  client = attemptToInitialise(_args, _props,IORs[j]);
+	}
+      }
+    }
+    // the knownIORs is the last resort
+    if (client == null) {
+      IOR = NzdlServiceFactory.getFirstValid();
+      client = attemptToInitialise(_args, _props, IOR);
+    }
+    return client;
+    
+  }
+  /**
+   * Connect for as many servers as possible
+   * @param _args the command line arguments
+   * @param _URL a URL to look for an IOR in
+   * @param _filename a local filename to look for an IOR in
+   * @param _IOR a string to look for an IOR in
+   * @see org.omg.CORBA.ORB
+   */
+  public static Hashtable findIORs(String [] _args,
+				   Properties _props, 
+				   String _URL,
+				   String _filename,
+				   String _IOR)  {
+    // the object we're filling ...
+    Hashtable result = new Hashtable();
+
+    // read our prevously seed IORs ...
+    String IOR = null;
+    NzdlService client = null;
+      
+      
+    // try a URL from the command line
+    if ( _URL != null) {
+      String[] IORs = NzdlServiceFactory.getIORsfromURL(_URL);
+      for (int i=0;( i<IORs.length && client == null );i++) {
+	client = attemptToInitialise(_args, _props,IORs[i]);
+	if (client != null)
+	  result.put(IORs[i],client);
+      }
+    }
+
+    // try an IOR from the command line
+    if (_IOR != null) {
+      IOR = NzdlServiceFactory.registerIOR(_IOR);
+      client = attemptToInitialise(_args, _props, IOR);
+	if (client != null)
+	  result.put(IOR,client);
+    }
+    
+    // try an IOR from a file (the filename may have been 
+    // given from the commandline
+    {
+      String[] IORs = NzdlServiceFactory.getIORsfromFile(_filename);
+      for (int i=0;( i<IORs.length);i++) {
+	client = attemptToInitialise(_args, _props,IORs[i]);
+	if (client != null)
+	  result.put(IORs[i],client);
+      }
+    }
+    
+    // try the compiled-in URLs
+    for (int i=0;(urlsCompiledIn != null && i<urlsCompiledIn.length);i++) {
+      String[] IORs = NzdlServiceFactory.getIORsfromURL(urlsCompiledIn[i]);
+      for (int j=0;( IORs != null && j<IORs.length);j++) {
+	client = attemptToInitialise(_args, _props, IORs[j]);
+	if (client != null)
+	  result.put(IORs[j],client);
+      }
+    }
+
+    // the knownIORs is the last resort
+    IOR = NzdlServiceFactory.getFirstValid();
+    client = attemptToInitialise(_args, _props, IOR);
+    if (client != null)
+      result.put(IOR,client);
+    return result;    
+  }
+
+  /**
+   * Connect to each of the ORB's described by the IORs and throw away
+   * any that can't be connected to.
+   * @see org.omg.CORBA.ORB
+   */
+ public static void validate()  {
+    checkLoaded();
+    synchronized (knownIORs) {
+
+      Properties valid = new Properties();
+      
+      if (knownIORs == null)
+	throw new Error("saving null property list");
+	
+      Enumeration e = knownIORs.keys();
+      while (e.hasMoreElements()) {
+	String IOR = (String) e.nextElement();
+	if (attemptToInitialise(null, null, IOR) != null) {
+	  valid.put(IOR,"");
+	}
+      }
+      try {
+	synchronized (Class.forName("org.nzdl.gsdl.util.NzdlServiceFactory")) {
+	  knownIORs = valid;
+	}
+      } catch (ClassNotFoundException exception) {
+	System.err.println("Exception locking class:" + exception);
+      }
+      checkSave();
+    }    
+  }
+
+  /**
+   * Register a given IOR 
+   * @see java.lang.String
+   * @param str the IOR
+   * @return the str
+   */
+ public static String registerIOR(String str)
+  {
+    checkLoaded();    
+    if (str != null)
+      synchronized (knownIORs) {
+	knownIORs.put(str,"");
+      }
+    checkSave();
+    return str;
+  }
+
+ 
+  /**
+   * Retrieve an IOR from a URL
+   * @see java.net.URL
+   * @param str the url to retrieve
+   * @return the IOR
+   */
+  public static String[] getIORsfromURL(String str)
+  {
+    checkLoaded();
+    String ior = null;
+    
+    try { 
+      System.err.println("Requesting IORs from: " + str);
+      URL url = new URL(str);
+      InputStream his = url.openStream();
+      
+      BufferedReader rdr = new BufferedReader (new InputStreamReader(his)) ;
+      return readIORsfromReader(rdr);
+    } catch (Throwable throwable) {
+      System.err.println("NzdlHosts::getIOR() unable to construct or read URL \"" +
+			 str + "\", \"" + ior + "\": " + throwable);
+      return new String[0];
+    }
+  }
+
+  public static String[] readIORsfromReader(BufferedReader rdr) {
+    Vector vec = new Vector();
+    
+    try { 
+      String ior = rdr.readLine();
+      while (ior != null) {
+	vec.add(ior);
+	synchronized (knownIORs) {
+	  knownIORs.put(ior,"");
+	}
+	ior = rdr.readLine();
+      }
+    } catch (Throwable throwable) {
+      System.err.println("Throwable: " + throwable);
+    }
+    checkSave();
+    String[] strings = new String[vec.size()];
+    for (int i = 0; i < vec.size(); i++)
+      strings[i] = (String)vec.elementAt(i);
+    return strings;
+  }
+  
+  /**
+   * Retrieve an IOR from a file
+   * @see java.io.File
+   * @param str the file to open
+   * @return the IOR
+   */
+  public static String[] getIORsfromFile(String file) {
+    checkLoaded();
+    String ior = null;
+    if (file == null || file.equals(""))
+      file = IORFileName;
+    file = file.trim();
+    try  {
+      BufferedReader input
+	= new BufferedReader(new FileReader(file));
+      return readIORsfromReader(input);
+    } catch (java.io.FileNotFoundException e) {
+	// System.err.println("Error reading IOR file:\n" + e);
+    } catch (java.io.IOException e) {
+      System.err.println("Error reading IOR file:\n" + e);
+    }
+    return new String[0];
+  }  
+
+  /**
+   * Write all IORs to a flat file (for reading from c++ etc).
+   *
+   * Not used for the properties files.
+   *
+   * @see java.util.Properties
+   * @param file the file to write to
+   */
+  public static void  writeToFile(String file) {
+    checkLoaded();
+    if (file != null)
+      synchronized (knownIORs) {
+	String ior = null;
+	file = file.trim();
+	try  {
+	  BufferedWriter output
+	    = new BufferedWriter(new FileWriter(file));
+	  Enumeration e = knownIORs.keys();
+	  while (e.hasMoreElements()) {
+	    String IOR = (String) e.nextElement();
+	    output.write(IOR);
+	    output.newLine();
+	  } 
+	} catch (java.io.IOException e) {
+	  System.err.println("Error reading IOR file:\n" + e);
+	}
+      }
+  }   // end of getIorKey
+  
+
+  /**
+   * Attempt to connect to the object pointed to by an IOR
+   * @see org.omg.CORBA.ORB
+   * @param _args the command line arguments
+   * @param _props the system properties
+   * @param _IOR the IOR string
+   * @return the newly created NzdlServiceClient
+   */
+  static public NzdlService attemptToInitialise(String [] _args, 
+				      Properties _props, 
+				      String _IOR) {
+    checkLoaded();
+    NzdlService nzdl = null;
+    if (_props == null)
+      _props = System.getProperties();
+    try {
+      nzdl = new NzdlServiceClient( _args, _props, _IOR);
+    } catch (Throwable t) {
+      System.err.println ("failed to initialise using:");
+      System.err.println (_IOR);
+      return null;
+    }
+    return nzdl;
+  }
+  
+  static public NzdlService createNzdlService(String [] _args, 
+					      Properties _props, 
+					      String _URL,
+					      String _filename,
+					      String _IOR) {
+    if (_props == null)
+      _props = System.getProperties();
+
+    NzdlService nzdl = null;
+    
+    if (NzdlPreferences.getBoolean("Connect to multiple servers"))
+      nzdl = new NzdlMultiWayWrapper(_args,_props,_URL,_filename,_IOR);
+    else
+      nzdl = findIOR(_args,_props,_URL,_filename,_IOR);
+    
+    if (NzdlPreferences.getBoolean("Save documents"))
+      nzdl = new NzdlDocSaveWrapper(nzdl);
+    
+    if (NzdlPreferences.getBoolean("Log at the NzdlService level"))
+      nzdl = new NzdlLogWrapper(nzdl, "log.file.after.cache", "AFTER: ");
+    
+    if (NzdlPreferences.getBoolean("Cache corba requests"))
+      nzdl = new NzdlCacheWrapper(nzdl);
+
+    if (NzdlPreferences.getBoolean("Log at the NzdlService level"))
+      nzdl = new NzdlLogWrapper(nzdl, "log.file.before.cache", "BEFORE: ");
+    
+    return nzdl;
+  }
+  static public NzdlService createNzdlService(String _IOR) {
+    Properties _props =  System.getProperties();
+    
+    NzdlService nzdl = null;
+    String IOR = null;
+    
+    IOR = NzdlServiceFactory.registerIOR(_IOR);
+    nzdl = attemptToInitialise(null, _props, IOR);
+
+    if (nzdl == null) {
+      System.err.println("couldn't open the requested IOR: going for what we can ...");
+      nzdl = createNzdlService(null,null,null,null,null);
+    }
+
+    
+    if (NzdlPreferences.getBoolean("Save documents"))
+      nzdl = new NzdlDocSaveWrapper(nzdl);
+    
+    if (NzdlPreferences.getBoolean("Log at the NzdlService level"))
+      nzdl = new NzdlLogWrapper(nzdl, "log.file.after.cache", "AFTER: ");
+    
+    if (NzdlPreferences.getBoolean("Cache corba requests"))
+      nzdl = new NzdlCacheWrapper(nzdl);
+
+    if (NzdlPreferences.getBoolean("Log at the NzdlService level"))
+      nzdl = new NzdlLogWrapper(nzdl, "log.file.before.cache", "BEFORE: ");
+    
+    return nzdl;
+  }
+   
+  /**
+   * Write the System properties to a file called "System.properties" in
+   * the current directory.
+   */
+  public static final void main( String [] args ) {
+ 
+    try {
+      File file = new File("System.properties");
+      
+      System.getProperties().store(new FileOutputStream(file),"");
+    } catch (Exception exception) {
+      System.err.println("Error locking class:" + exception);
+    }
+  } //main
+} // class
Index: other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/package.html
===================================================================
--- other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/package.html	(revision 21017)
+++ other-projects/gs2-java-client/trunk/org/nzdl/gsdl/util/package.html	(revision 21017)
@@ -0,0 +1,12 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.16-22 i686) [Netscape]">
+   <title>Utils Package</title>
+</head>
+<body bgcolor="#FFFFFF">
+Contains utilities for working with hosts, IORs and the NzdlCorba
+factory.
+</body>
+</html>
Index: other-projects/gs2-java-client/trunk/overview.html
===================================================================
--- other-projects/gs2-java-client/trunk/overview.html	(revision 21017)
+++ other-projects/gs2-java-client/trunk/overview.html	(revision 21017)
@@ -0,0 +1,16 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.76 [en] (X11; U; Linux 2.2.16-22 i686) [Netscape]">
+</head>
+<body text="#000000" bgcolor="#FFFFFF" link="#0000EE" vlink="#551A8B" alink="#FF0000">
+The NZDL Java-Client interface is a package for writing java applications to communicate
+with the Greenstone Digital Library.
+<p>The interface is through Common Object Reference Broker Architecture
+(CORBA).
+<p>In order to communicate to Greenstone collections, this software requires that the
+server machine has Corbaserver installed and running.
+<br><tt></tt>&nbsp;
+</body>
+</html>
