[Xulu-commits] r2 - in trunk: . defaults defaults/plugin defaults/plugin/GTVisualisationColorMapPlugin defaults/plugin/GeoModelCodeGenerator defaults/plugin/LoggerPlugin defaults/plugin/RasterCalculator lib lib/JavaRInterface lib/jai-1_1_3 lib/jai-1_1_3/lib lib/jai-1_1_3/lib/native_win lib/jini lib/jini/lib lib/schmitzm lib/xulu resource resource/icons resource/locales resource/unused src src/META-INF src/appl src/appl/data src/appl/ext src/appl/parallel src/appl/parallel/client src/appl/parallel/data src/appl/parallel/data/splittable src/appl/parallel/data/xulugridfile src/appl/parallel/data/xulugridfile/factories src/appl/parallel/event src/appl/parallel/gui src/appl/parallel/model src/appl/parallel/plugin src/appl/parallel/plugin/event src/appl/parallel/server src/appl/parallel/services src/appl/parallel/spmd src/appl/parallel/spmd/split src/appl/parallel/starter src/appl/parallel/starter/client src/appl/parallel/starter/server src/appl/parallel/test src/appl/parallel/thread src/appl/parallel/util src/appl/plugin src/appl/plugin/multimodelcontrol src/appl/util src/appl/util/benchmark src/de src/de/skrueger src/de/skrueger/xulu src/de/skrueger/xulu/plugin src/de/skrueger/xulu/plugin/gnur src/de/skrueger/xulu/plugin/gnur/Rcode src/edu src/edu/bonn src/edu/bonn/xulu src/edu/bonn/xulu/appl src/edu/bonn/xulu/data src/edu/bonn/xulu/gui src/edu/bonn/xulu/io src/edu/bonn/xulu/model src/edu/bonn/xulu/model/event src/edu/bonn/xulu/plugin src/edu/bonn/xulu/plugin/appl src/edu/bonn/xulu/plugin/data src/edu/bonn/xulu/plugin/data/feature src/edu/bonn/xulu/plugin/data/grid src/edu/bonn/xulu/plugin/data/misc src/edu/bonn/xulu/plugin/gui src/edu/bonn/xulu/plugin/io src/edu/bonn/xulu/plugin/io/feature src/edu/bonn/xulu/plugin/io/feature/gt src/edu/bonn/xulu/plugin/io/grid src/edu/bonn/xulu/plugin/io/grid/array src/edu/bonn/xulu/plugin/io/grid/awt src/edu/bonn/xulu/plugin/io/grid/gt src/edu/bonn/xulu/plugin/io/grid/lateloading src/edu/bonn/xulu/plugin/io/misc src/edu/bonn/xulu/plugin/model src/edu/bonn/xulu/plugin/model/ca src/edu/bonn/xulu/plugin/model/ca/agric src/edu/bonn/xulu/plugin/model/ca/fire src/edu/bonn/xulu/plugin/model/ca/reservoir src/edu/bonn/xulu/plugin/model/clue src/edu/bonn/xulu/plugin/model/parallel src/edu/bonn/xulu/plugin/model/parallel/demo src/edu/bonn/xulu/plugin/model/test src/edu/bonn/xulu/plugin/vis src/skrueger src/skrueger/gol

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Wed Feb 25 12:57:17 CET 2009


Author: mojays
Date: 2009-02-25 12:54:01 +0100 (Wed, 25 Feb 2009)
New Revision: 2

Added:
   trunk/InitXulu.bat
   trunk/defaults/
   trunk/defaults/.classpath
   trunk/defaults/.project
   trunk/defaults/DefaultProperties
   trunk/defaults/XuluProperties
   trunk/defaults/plugin/
   trunk/defaults/plugin/GTVisualisationColorMapPlugin/
   trunk/defaults/plugin/GTVisualisationColorMapPlugin/gtcolormaps.xif
   trunk/defaults/plugin/GeoModelCodeGenerator/
   trunk/defaults/plugin/GeoModelCodeGenerator/ModelContentManager.tpl
   trunk/defaults/plugin/GeoModelCodeGenerator/StepModel.tpl
   trunk/defaults/plugin/GeoModelCodeGenerator/XuluModel.tpl
   trunk/defaults/plugin/LoggerPlugin/
   trunk/defaults/plugin/LoggerPlugin/log4j.cfg
   trunk/defaults/plugin/RasterCalculator/
   trunk/defaults/plugin/RasterCalculator/default_filter.inp
   trunk/defaults/registry.xif
   trunk/defaults/registry_ProxyGrid.xif
   trunk/defaults/registry_arrayGrid.xif
   trunk/defaults/startXULU.bat
   trunk/doc/
   trunk/lib/
   trunk/lib/JavaRInterface/
   trunk/lib/JavaRInterface/JRI.jar
   trunk/lib/jai-1_1_3/
   trunk/lib/jai-1_1_3/COPYRIGHT-jai.txt
   trunk/lib/jai-1_1_3/DISTRIBUTIONREADME-jai.txt
   trunk/lib/jai-1_1_3/LICENSE-jai.txt
   trunk/lib/jai-1_1_3/THIRDPARTYLICENSEREADME-jai.txt
   trunk/lib/jai-1_1_3/UNINSTALL-jai
   trunk/lib/jai-1_1_3/lib/
   trunk/lib/jai-1_1_3/lib/clibwrapper_jiio.jar
   trunk/lib/jai-1_1_3/lib/jai_codec.jar
   trunk/lib/jai-1_1_3/lib/jai_core.jar
   trunk/lib/jai-1_1_3/lib/jai_imageio.jar
   trunk/lib/jai-1_1_3/lib/mlibwrapper_jai.jar
   trunk/lib/jai-1_1_3/lib/native_linux/
   trunk/lib/jai-1_1_3/lib/native_win/
   trunk/lib/jai-1_1_3/lib/native_win/mlib_jai.dll
   trunk/lib/jai-1_1_3/lib/native_win/mlib_jai_mmx.dll
   trunk/lib/jai-1_1_3/lib/native_win/mlib_jai_util.dll
   trunk/lib/jini/
   trunk/lib/jini/lib/
   trunk/lib/jini/lib/tools.jar
   trunk/lib/schmitzm/
   trunk/lib/schmitzm/schmitzm.jar
   trunk/lib/xulu/
   trunk/lib/xulu/XuluModellingPlatform.jar
   trunk/readme.txt
   trunk/resource/
   trunk/resource/icons/
   trunk/resource/icons/xulu_icon.png
   trunk/resource/icons/xulu_info.png
   trunk/resource/icons/xulu_start.png
   trunk/resource/locales/
   trunk/resource/locales/StandardBundleExtension.properties
   trunk/resource/locales/XuluMainAppl.properties
   trunk/resource/locales/XuluMainAppl_de.properties
   trunk/resource/locales/XuluMainError.properties
   trunk/resource/locales/XuluMainError_de.properties
   trunk/resource/locales/XuluModel_Clue.properties
   trunk/resource/locales/XuluModel_Clue_de.properties
   trunk/resource/locales/XuluModel_ImpetusFireCA.properties
   trunk/resource/locales/XuluModel_ImpetusFireCA_de.properties
   trunk/resource/locales/XuluModel_SmallReservoirModel.properties
   trunk/resource/locales/XuluModel_SmallReservoirModel_de.properties
   trunk/resource/locales/XuluVisualisationTool.properties
   trunk/resource/locales/XuluVisualisationTool_de.properties
   trunk/resource/unused/
   trunk/resource/unused/edit_clear.gif
   trunk/resource/unused/edit_redo.gif
   trunk/resource/unused/edit_undo.gif
   trunk/resource/unused/layer_cancel3.png
   trunk/resource/unused/xulu_icon.gif
   trunk/resource/unused/xulu_icon_green.gif
   trunk/resource/unused/xulu_icon_red.gif
   trunk/resource/unused/xulu_icon_yellow.gif
   trunk/resource/unused/xuluv.png
   trunk/src/
   trunk/src/META-INF/
   trunk/src/META-INF/PREFERRED.LIST
   trunk/src/appl/
   trunk/src/appl/data/
   trunk/src/appl/data/DataLoader.java
   trunk/src/appl/data/DataProxy.java
   trunk/src/appl/data/DataUnloader.java
   trunk/src/appl/data/FactoryLoader.java
   trunk/src/appl/data/ImportFactoryLoader.java
   trunk/src/appl/data/LateLoadingProxy.java
   trunk/src/appl/data/SerializedDataLoader.java
   trunk/src/appl/data/WritableGridArrayLoader.java
   trunk/src/appl/data/WritableGridLLProxy.java
   trunk/src/appl/data/package.html
   trunk/src/appl/ext/
   trunk/src/appl/ext/ConfigurationEditor.java
   trunk/src/appl/ext/ConfigurationEditorEngine.java
   trunk/src/appl/ext/ConfigurationEditorGUI.java
   trunk/src/appl/ext/ConfigurationEditorPlugin.java
   trunk/src/appl/ext/XuluConfig.java
   trunk/src/appl/ext/package.html
   trunk/src/appl/package.html
   trunk/src/appl/parallel/
   trunk/src/appl/parallel/ComputingResource.java
   trunk/src/appl/parallel/ComputingResourceContainer.java
   trunk/src/appl/parallel/ComputingResourceProperties.java
   trunk/src/appl/parallel/SimpleResourceProperties.java
   trunk/src/appl/parallel/client/
   trunk/src/appl/parallel/client/ClientDataServer.java
   trunk/src/appl/parallel/client/DataServer.java
   trunk/src/appl/parallel/client/RemoteEventHandler.java
   trunk/src/appl/parallel/client/RemoteExecutionController.java
   trunk/src/appl/parallel/client/ResourceChangeListener.java
   trunk/src/appl/parallel/client/package.html
   trunk/src/appl/parallel/data/
   trunk/src/appl/parallel/data/AbstractDataHandler.java
   trunk/src/appl/parallel/data/DataLoadHandler.java
   trunk/src/appl/parallel/data/PartitionDataHandler.java
   trunk/src/appl/parallel/data/PartitionHandlerFactory.java
   trunk/src/appl/parallel/data/WritableGridArrayPartition.java
   trunk/src/appl/parallel/data/XuluClientLoader.java
   trunk/src/appl/parallel/data/package.html
   trunk/src/appl/parallel/data/splittable/
   trunk/src/appl/parallel/data/splittable/GridListFactory.java
   trunk/src/appl/parallel/data/splittable/GridListFactory_ArcInfoAsciiGrid.java
   trunk/src/appl/parallel/data/splittable/MultiGridFactory.java
   trunk/src/appl/parallel/data/splittable/MultiGridFactory_ArcInfoAsciiGrid.java
   trunk/src/appl/parallel/data/splittable/SingleGridFactory.java
   trunk/src/appl/parallel/data/splittable/SingleGridFactory_ArcInfoAsciiGrid.java
   trunk/src/appl/parallel/data/splittable/SingleGridFactory_GeoTiff.java
   trunk/src/appl/parallel/data/splittable/SplittableGridLLFactory.java
   trunk/src/appl/parallel/data/splittable/SplittableLLProxyGrid.java
   trunk/src/appl/parallel/data/splittable/package.html
   trunk/src/appl/parallel/data/xulugridfile/
   trunk/src/appl/parallel/data/xulugridfile/BufferedHelper.java
   trunk/src/appl/parallel/data/xulugridfile/BufferedRandomAccessFile.java
   trunk/src/appl/parallel/data/xulugridfile/GridFileDataLoader.java
   trunk/src/appl/parallel/data/xulugridfile/XuluGridFile.java
   trunk/src/appl/parallel/data/xulugridfile/XuluGridFileConverter.java
   trunk/src/appl/parallel/data/xulugridfile/XuluGridFileException.java
   trunk/src/appl/parallel/data/xulugridfile/XuluGridSharedFileSystemLoader.java
   trunk/src/appl/parallel/data/xulugridfile/XuluWritableGridFile.java
   trunk/src/appl/parallel/data/xulugridfile/factories/
   trunk/src/appl/parallel/data/xulugridfile/factories/GridListFactory.java
   trunk/src/appl/parallel/data/xulugridfile/factories/GridListFactory_ArcInfoAsciiGrid.java
   trunk/src/appl/parallel/data/xulugridfile/factories/MultiGridFactory.java
   trunk/src/appl/parallel/data/xulugridfile/factories/MultiGridFactory_ArcInfoAsciiGrid.java
   trunk/src/appl/parallel/data/xulugridfile/factories/SingleGridFactory.java
   trunk/src/appl/parallel/data/xulugridfile/factories/SingleGridFactory_ArcInfoAsciiGrid.java
   trunk/src/appl/parallel/data/xulugridfile/factories/XuluGridFactory.java
   trunk/src/appl/parallel/data/xulugridfile/factories/package.html
   trunk/src/appl/parallel/data/xulugridfile/package.html
   trunk/src/appl/parallel/event/
   trunk/src/appl/parallel/event/CommEvent.java
   trunk/src/appl/parallel/event/CommEventSink.java
   trunk/src/appl/parallel/event/RemoteEvent.java
   trunk/src/appl/parallel/event/RemoteEventSink.java
   trunk/src/appl/parallel/event/SimpleConsoleMonitor.java
   trunk/src/appl/parallel/event/TimeEvent.java
   trunk/src/appl/parallel/event/TimeMonitor.java
   trunk/src/appl/parallel/event/TransferEvent.java
   trunk/src/appl/parallel/event/TransferMonitor.java
   trunk/src/appl/parallel/event/package.html
   trunk/src/appl/parallel/gui/
   trunk/src/appl/parallel/gui/ModelControlContainer_parallel.java
   trunk/src/appl/parallel/gui/ModelControlFrame_Tabbed.java
   trunk/src/appl/parallel/gui/ModelControlFrame_parallel.java
   trunk/src/appl/parallel/gui/ParallelControlPanel.java
   trunk/src/appl/parallel/gui/ParallelControlPanelEngine.java
   trunk/src/appl/parallel/gui/SimplePropertyTable.java
   trunk/src/appl/parallel/gui/package.html
   trunk/src/appl/parallel/model/
   trunk/src/appl/parallel/model/AbstractParallelStepModel.java
   trunk/src/appl/parallel/model/ParallelStepModel.java
   trunk/src/appl/parallel/model/package.html
   trunk/src/appl/parallel/package.html
   trunk/src/appl/parallel/plugin/
   trunk/src/appl/parallel/plugin/event/
   trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitor.java
   trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitorEngine.java
   trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitorPlugin.java
   trunk/src/appl/parallel/plugin/event/package.html
   trunk/src/appl/parallel/server/
   trunk/src/appl/parallel/server/MasterSlaveResource.java
   trunk/src/appl/parallel/server/PartitionDataManager.java
   trunk/src/appl/parallel/server/PartitionDataServer.java
   trunk/src/appl/parallel/server/SPMDResource.java
   trunk/src/appl/parallel/server/ServerMulticastReceiver.java
   trunk/src/appl/parallel/server/XuluServer.java
   trunk/src/appl/parallel/server/XuluServerProperties.java
   trunk/src/appl/parallel/server/package.html
   trunk/src/appl/parallel/services/
   trunk/src/appl/parallel/services/DiscoveryService.java
   trunk/src/appl/parallel/services/GlobalDiscoveryService.java
   trunk/src/appl/parallel/services/HostnameDiscoveryService.java
   trunk/src/appl/parallel/services/MulticastDiscoveryService.java
   trunk/src/appl/parallel/services/RemoteEventProxy.java
   trunk/src/appl/parallel/services/Service.java
   trunk/src/appl/parallel/services/package.html
   trunk/src/appl/parallel/spmd/
   trunk/src/appl/parallel/spmd/AbstractSPMDTask.java
   trunk/src/appl/parallel/spmd/AdvancedSPMDClientController.java
   trunk/src/appl/parallel/spmd/AdvancedSPMDClientInterface.java
   trunk/src/appl/parallel/spmd/AdvancedSPMDServerController.java
   trunk/src/appl/parallel/spmd/AdvancedSPMDServerInterface.java
   trunk/src/appl/parallel/spmd/MultiDataInfo.java
   trunk/src/appl/parallel/spmd/MultiDataObject.java
   trunk/src/appl/parallel/spmd/MultiDataPartitionObject.java
   trunk/src/appl/parallel/spmd/SPMDClientController.java
   trunk/src/appl/parallel/spmd/SPMDClientInterface.java
   trunk/src/appl/parallel/spmd/SPMDServerController.java
   trunk/src/appl/parallel/spmd/SPMDServerInterface.java
   trunk/src/appl/parallel/spmd/SPMDTask.java
   trunk/src/appl/parallel/spmd/SyncPoint.java
   trunk/src/appl/parallel/spmd/package.html
   trunk/src/appl/parallel/spmd/split/
   trunk/src/appl/parallel/spmd/split/AbstractSplitMap.java
   trunk/src/appl/parallel/spmd/split/DataPartition.java
   trunk/src/appl/parallel/spmd/split/PartitionInfo.java
   trunk/src/appl/parallel/spmd/split/SinglePartitionInfo.java
   trunk/src/appl/parallel/spmd/split/SplitMap.java
   trunk/src/appl/parallel/spmd/split/SplitMap1DHorizontal.java
   trunk/src/appl/parallel/spmd/split/SplitMap1DVertical.java
   trunk/src/appl/parallel/spmd/split/SplitMap2D.java
   trunk/src/appl/parallel/spmd/split/SplittableGrid.java
   trunk/src/appl/parallel/spmd/split/SplittableResource.java
   trunk/src/appl/parallel/spmd/split/WritableGridPartition.java
   trunk/src/appl/parallel/spmd/split/package.html
   trunk/src/appl/parallel/starter/
   trunk/src/appl/parallel/starter/Starter.java
   trunk/src/appl/parallel/starter/client/
   trunk/src/appl/parallel/starter/client/StarterClientGUI.java
   trunk/src/appl/parallel/starter/client/StarterContainer.java
   trunk/src/appl/parallel/starter/client/XuluStarterClientPanel.java
   trunk/src/appl/parallel/starter/client/XuluStarterController.java
   trunk/src/appl/parallel/starter/client/XuluStarterControllerFrame.java
   trunk/src/appl/parallel/starter/client/XuluStarterControllerPlugin.java
   trunk/src/appl/parallel/starter/client/package.html
   trunk/src/appl/parallel/starter/package.html
   trunk/src/appl/parallel/starter/server/
   trunk/src/appl/parallel/starter/server/XuluServerStarter.java
   trunk/src/appl/parallel/starter/server/XuluStarterServerGUI.java
   trunk/src/appl/parallel/starter/server/package.html
   trunk/src/appl/parallel/test/
   trunk/src/appl/parallel/test/AverageNeighborhoodTestTask.java
   trunk/src/appl/parallel/test/AverageNeighborhoodTestTask_MultiGrid.java
   trunk/src/appl/parallel/test/MulticastSocketTest.java
   trunk/src/appl/parallel/test/PartitialGridTest.java
   trunk/src/appl/parallel/test/PingTestObject.java
   trunk/src/appl/parallel/test/SPMDTest.java
   trunk/src/appl/parallel/test/SPMDTest.testsuite
   trunk/src/appl/parallel/test/SPMDTest_MultiGrid.java
   trunk/src/appl/parallel/test/SplitMapTest.java
   trunk/src/appl/parallel/test/SplitMaps.testsuite
   trunk/src/appl/parallel/test/XuluGridTestCase.java
   trunk/src/appl/parallel/test/XuluGridTestCase.testsuite
   trunk/src/appl/parallel/test/XuluServerTest.java
   trunk/src/appl/parallel/test/XuluServerTest.testsuite
   trunk/src/appl/parallel/test/generalTestClass.java
   trunk/src/appl/parallel/test/package.html
   trunk/src/appl/parallel/thread/
   trunk/src/appl/parallel/thread/ComputingResourceThread.java
   trunk/src/appl/parallel/thread/DataServerThread.java
   trunk/src/appl/parallel/thread/ExecutionThread.java
   trunk/src/appl/parallel/thread/OneMethodThread.java
   trunk/src/appl/parallel/thread/package.html
   trunk/src/appl/parallel/util/
   trunk/src/appl/parallel/util/Helper.java
   trunk/src/appl/parallel/util/PartitionUtil.java
   trunk/src/appl/parallel/util/package.html
   trunk/src/appl/plugin/
   trunk/src/appl/plugin/multimodelcontrol/
   trunk/src/appl/plugin/multimodelcontrol/ModelListObject.java
   trunk/src/appl/plugin/multimodelcontrol/MultiModelControlFrame.java
   trunk/src/appl/plugin/multimodelcontrol/MultiModelControlHandler.java
   trunk/src/appl/plugin/multimodelcontrol/MultiModelControlPlugin.java
   trunk/src/appl/plugin/multimodelcontrol/package.html
   trunk/src/appl/util/
   trunk/src/appl/util/GeneralUtil.java
   trunk/src/appl/util/NonEditableTableModel.java
   trunk/src/appl/util/RasterUtil.java
   trunk/src/appl/util/XuluFrameAdapter.java
   trunk/src/appl/util/benchmark/
   trunk/src/appl/util/benchmark/Benchmark.java
   trunk/src/appl/util/benchmark/SimpleBenchmark.java
   trunk/src/appl/util/benchmark/package.html
   trunk/src/appl/util/package.html
   trunk/src/de/
   trunk/src/de/skrueger/
   trunk/src/de/skrueger/xulu/
   trunk/src/de/skrueger/xulu/plugin/
   trunk/src/de/skrueger/xulu/plugin/gnur/
   trunk/src/de/skrueger/xulu/plugin/gnur/GnuRGUI.java
   trunk/src/de/skrueger/xulu/plugin/gnur/GnuRPlugin.java
   trunk/src/de/skrueger/xulu/plugin/gnur/JRTextArea.java
   trunk/src/de/skrueger/xulu/plugin/gnur/PropertytypeNotConvertableToRVar.java
   trunk/src/de/skrueger/xulu/plugin/gnur/RConsolePanel.java
   trunk/src/de/skrueger/xulu/plugin/gnur/RVar.java
   trunk/src/de/skrueger/xulu/plugin/gnur/RVarAdapter.java
   trunk/src/de/skrueger/xulu/plugin/gnur/RVarMatrix.java
   trunk/src/de/skrueger/xulu/plugin/gnur/RVarScalar.java
   trunk/src/de/skrueger/xulu/plugin/gnur/RVarSingleGrid.java
   trunk/src/de/skrueger/xulu/plugin/gnur/RVarsTable.java
   trunk/src/de/skrueger/xulu/plugin/gnur/RVarsTableModel.java
   trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/
   trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/funGeneric.r
   trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/functions.R
   trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/logit_regression_all_v1.3.R
   trunk/src/de/skrueger/xulu/plugin/gnur/SwingIO.java
   trunk/src/de/skrueger/xulu/plugin/gnur/TextReader.java
   trunk/src/de/skrueger/xulu/plugin/gnur/testsomethong.java
   trunk/src/edu/
   trunk/src/edu/bonn/
   trunk/src/edu/bonn/xulu/
   trunk/src/edu/bonn/xulu/XuluModellingPlatform.java
   trunk/src/edu/bonn/xulu/appl/
   trunk/src/edu/bonn/xulu/appl/AbstractCommandInterpreter.java
   trunk/src/edu/bonn/xulu/appl/AbstractHandler.java
   trunk/src/edu/bonn/xulu/appl/AbstractManager.java
   trunk/src/edu/bonn/xulu/appl/AbstractScriptInterpreter.java
   trunk/src/edu/bonn/xulu/appl/AbstractXuluPlugin.java
   trunk/src/edu/bonn/xulu/appl/DataPool.java
   trunk/src/edu/bonn/xulu/appl/EventHandler.java
   trunk/src/edu/bonn/xulu/appl/EventManager.java
   trunk/src/edu/bonn/xulu/appl/Handler.java
   trunk/src/edu/bonn/xulu/appl/HandlerFactory.java
   trunk/src/edu/bonn/xulu/appl/ModelControlManager.java
   trunk/src/edu/bonn/xulu/appl/RecentImports.java
   trunk/src/edu/bonn/xulu/appl/RecentScripts.java
   trunk/src/edu/bonn/xulu/appl/ScriptInterpreter.java
   trunk/src/edu/bonn/xulu/appl/ScriptablePlugin.java
   trunk/src/edu/bonn/xulu/appl/VisualisationManager.java
   trunk/src/edu/bonn/xulu/appl/VisualisationTool.java
   trunk/src/edu/bonn/xulu/appl/VisualisationUpdateListener.java
   trunk/src/edu/bonn/xulu/appl/XuluComponent.java
   trunk/src/edu/bonn/xulu/appl/XuluComponentUtil.java
   trunk/src/edu/bonn/xulu/appl/XuluConstants.java
   trunk/src/edu/bonn/xulu/appl/XuluPlugin.java
   trunk/src/edu/bonn/xulu/appl/XuluRegistry.java
   trunk/src/edu/bonn/xulu/appl/XuluRegistryReader.java
   trunk/src/edu/bonn/xulu/appl/package.html
   trunk/src/edu/bonn/xulu/data/
   trunk/src/edu/bonn/xulu/data/AbstractXuluObject.java
   trunk/src/edu/bonn/xulu/data/DuplicateXuluObjectIDException.java
   trunk/src/edu/bonn/xulu/data/DuplicateXuluObjectNameException.java
   trunk/src/edu/bonn/xulu/data/DynamicXuluObject.java
   trunk/src/edu/bonn/xulu/data/XuluDataException.java
   trunk/src/edu/bonn/xulu/data/XuluObject.java
   trunk/src/edu/bonn/xulu/data/package.html
   trunk/src/edu/bonn/xulu/gui/
   trunk/src/edu/bonn/xulu/gui/AbstractManagerFrame.java
   trunk/src/edu/bonn/xulu/gui/DataPoolFrame.java
   trunk/src/edu/bonn/xulu/gui/DataPoolInputOption.java
   trunk/src/edu/bonn/xulu/gui/DataPoolMenu.java
   trunk/src/edu/bonn/xulu/gui/DataPoolMenu.sav
   trunk/src/edu/bonn/xulu/gui/DataPoolTreeModel.java
   trunk/src/edu/bonn/xulu/gui/ModelContentManagerContainer.java
   trunk/src/edu/bonn/xulu/gui/ModelControlFrame.java
   trunk/src/edu/bonn/xulu/gui/ModelManagerTreeModel.java
   trunk/src/edu/bonn/xulu/gui/ObjectOrModelInputOption.java
   trunk/src/edu/bonn/xulu/gui/RegistryFrame.java
   trunk/src/edu/bonn/xulu/gui/StatusFrame.java
   trunk/src/edu/bonn/xulu/gui/XuluErrorResource.20080424
   trunk/src/edu/bonn/xulu/gui/XuluErrorResource_en.20080424
   trunk/src/edu/bonn/xulu/gui/XuluGUIMessages.java
   trunk/src/edu/bonn/xulu/gui/XuluGUIResource.20080424
   trunk/src/edu/bonn/xulu/gui/XuluGUIResource_en.20080424
   trunk/src/edu/bonn/xulu/gui/XuluGUIUtil.java
   trunk/src/edu/bonn/xulu/gui/XuluInternalFrame.java
   trunk/src/edu/bonn/xulu/gui/XuluLanguageManagerFrame.java
   trunk/src/edu/bonn/xulu/gui/XuluMainFrame.java
   trunk/src/edu/bonn/xulu/gui/XuluMainFrameInfo.java
   trunk/src/edu/bonn/xulu/gui/XuluStartingFrame.java
   trunk/src/edu/bonn/xulu/gui/package.html
   trunk/src/edu/bonn/xulu/io/
   trunk/src/edu/bonn/xulu/io/AbstractFactory.java
   trunk/src/edu/bonn/xulu/io/ExportFactory.java
   trunk/src/edu/bonn/xulu/io/Factory.java
   trunk/src/edu/bonn/xulu/io/FactoryCanceledException.java
   trunk/src/edu/bonn/xulu/io/IODefinition.java
   trunk/src/edu/bonn/xulu/io/ImportFactory.java
   trunk/src/edu/bonn/xulu/io/InstantiationFactory.java
   trunk/src/edu/bonn/xulu/io/TypeMapping.java
   trunk/src/edu/bonn/xulu/io/TypeMappingException.java
   trunk/src/edu/bonn/xulu/io/package.html
   trunk/src/edu/bonn/xulu/model/
   trunk/src/edu/bonn/xulu/model/AbstractModelContentManager.java
   trunk/src/edu/bonn/xulu/model/AbstractModelResource.java
   trunk/src/edu/bonn/xulu/model/AbstractStepModel.java
   trunk/src/edu/bonn/xulu/model/AbstractXuluModel.java
   trunk/src/edu/bonn/xulu/model/DefaultModelResource.java
   trunk/src/edu/bonn/xulu/model/ModelCanceledException.java
   trunk/src/edu/bonn/xulu/model/ModelContentManager.java
   trunk/src/edu/bonn/xulu/model/ModelResource.java
   trunk/src/edu/bonn/xulu/model/PropertiesResource.java
   trunk/src/edu/bonn/xulu/model/StepModel.java
   trunk/src/edu/bonn/xulu/model/StepModelThread.java
   trunk/src/edu/bonn/xulu/model/ValuePropertyResource.java
   trunk/src/edu/bonn/xulu/model/XuluModel.java
   trunk/src/edu/bonn/xulu/model/XuluModelThread.java
   trunk/src/edu/bonn/xulu/model/event/
   trunk/src/edu/bonn/xulu/model/event/AbstractIterationStepEvent.java
   trunk/src/edu/bonn/xulu/model/event/AbstractModelEvent.java
   trunk/src/edu/bonn/xulu/model/event/AbstractStepModelEvent.java
   trunk/src/edu/bonn/xulu/model/event/ModelAdapter.java
   trunk/src/edu/bonn/xulu/model/event/ModelDisposedEvent.java
   trunk/src/edu/bonn/xulu/model/event/ModelEvent.java
   trunk/src/edu/bonn/xulu/model/event/ModelInitialisedEvent.java
   trunk/src/edu/bonn/xulu/model/event/ModelIterationStepFinishedEvent.java
   trunk/src/edu/bonn/xulu/model/event/ModelIterationStepStartedEvent.java
   trunk/src/edu/bonn/xulu/model/event/ModelListener.java
   trunk/src/edu/bonn/xulu/model/event/ModelStartedEvent.java
   trunk/src/edu/bonn/xulu/model/event/ModelStepFinishedEvent.java
   trunk/src/edu/bonn/xulu/model/event/ModelStepStartedEvent.java
   trunk/src/edu/bonn/xulu/model/event/ModelStoppedEvent.java
   trunk/src/edu/bonn/xulu/model/event/StepModelAdapter.java
   trunk/src/edu/bonn/xulu/model/package.html
   trunk/src/edu/bonn/xulu/package.html
   trunk/src/edu/bonn/xulu/plugin/
   trunk/src/edu/bonn/xulu/plugin/appl/
   trunk/src/edu/bonn/xulu/plugin/appl/AbstractMenuPlugin.java
   trunk/src/edu/bonn/xulu/plugin/appl/DataExportHandler.java
   trunk/src/edu/bonn/xulu/plugin/appl/DataExportHandlerFactory.java
   trunk/src/edu/bonn/xulu/plugin/appl/DataScriptInterpreter_Basic.java
   trunk/src/edu/bonn/xulu/plugin/appl/DateTimePlugin.java
   trunk/src/edu/bonn/xulu/plugin/appl/DateTimeWindowPlugin.java
   trunk/src/edu/bonn/xulu/plugin/appl/FileExportHandlerFactory.java
   trunk/src/edu/bonn/xulu/plugin/appl/GTVisualisationColorMapPlugin.java
   trunk/src/edu/bonn/xulu/plugin/appl/GeoModelCodeGenerator.java
   trunk/src/edu/bonn/xulu/plugin/appl/GeoModelCodeGeneratorGUI.java
   trunk/src/edu/bonn/xulu/plugin/appl/GeoModelCodeGeneratorPlugin.java
   trunk/src/edu/bonn/xulu/plugin/appl/LoggerPlugin.java
   trunk/src/edu/bonn/xulu/plugin/appl/ModelResourceMappingScriptInterpreter_Basic.java
   trunk/src/edu/bonn/xulu/plugin/appl/ModelTimeSnifferPlugin.java
   trunk/src/edu/bonn/xulu/plugin/appl/RasterCalculatorGUI.070821
   trunk/src/edu/bonn/xulu/plugin/appl/RasterCalculatorGUI.java
   trunk/src/edu/bonn/xulu/plugin/appl/RasterCalculatorPanel.java
   trunk/src/edu/bonn/xulu/plugin/appl/RasterCalculatorPlugin.java
   trunk/src/edu/bonn/xulu/plugin/appl/VisualisationHandler.java
   trunk/src/edu/bonn/xulu/plugin/appl/VisualisationHandlerFactory.java
   trunk/src/edu/bonn/xulu/plugin/appl/XuluRegistryReader_BasicAscii.java
   trunk/src/edu/bonn/xulu/plugin/appl/package.html
   trunk/src/edu/bonn/xulu/plugin/data/
   trunk/src/edu/bonn/xulu/plugin/data/feature/
   trunk/src/edu/bonn/xulu/plugin/data/feature/SingleFeatureCollection.java
   trunk/src/edu/bonn/xulu/plugin/data/grid/
   trunk/src/edu/bonn/xulu/plugin/data/grid/GridList.java
   trunk/src/edu/bonn/xulu/plugin/data/grid/MultiGrid.java
   trunk/src/edu/bonn/xulu/plugin/data/grid/SingleGrid.java
   trunk/src/edu/bonn/xulu/plugin/data/misc/
   trunk/src/edu/bonn/xulu/plugin/data/misc/CAArea.java
   trunk/src/edu/bonn/xulu/plugin/data/misc/CASettlementArea.java
   trunk/src/edu/bonn/xulu/plugin/data/package.html
   trunk/src/edu/bonn/xulu/plugin/gui/
   trunk/src/edu/bonn/xulu/plugin/gui/AbstractManagerFrame_BasicTable.java
   trunk/src/edu/bonn/xulu/plugin/gui/DataPoolFrame_BasicTable.java
   trunk/src/edu/bonn/xulu/plugin/gui/DataPoolFrame_Tree.java
   trunk/src/edu/bonn/xulu/plugin/gui/DisplayContainer_GeomAndGrid.java
   trunk/src/edu/bonn/xulu/plugin/gui/DisplayContainer_ListProperty.java
   trunk/src/edu/bonn/xulu/plugin/gui/DisplayContainer_MatrixProperty.java
   trunk/src/edu/bonn/xulu/plugin/gui/DisplayContainer_Properties.java
   trunk/src/edu/bonn/xulu/plugin/gui/DisplayContainer_Table.java
   trunk/src/edu/bonn/xulu/plugin/gui/EventManagerFrame_BasicTable.java
   trunk/src/edu/bonn/xulu/plugin/gui/ModelControlContainer.java
   trunk/src/edu/bonn/xulu/plugin/gui/ModelControlFrame_Basic.java
   trunk/src/edu/bonn/xulu/plugin/gui/PluginManagerFrame_BasicTable.java
   trunk/src/edu/bonn/xulu/plugin/gui/RegistryFrame_Tree.java
   trunk/src/edu/bonn/xulu/plugin/gui/StatusFrame_BasicTextArea.java
   trunk/src/edu/bonn/xulu/plugin/gui/package.html
   trunk/src/edu/bonn/xulu/plugin/io/
   trunk/src/edu/bonn/xulu/plugin/io/IOUtil.java
   trunk/src/edu/bonn/xulu/plugin/io/feature/
   trunk/src/edu/bonn/xulu/plugin/io/feature/gt/
   trunk/src/edu/bonn/xulu/plugin/io/feature/gt/SingleFeatureCollectionFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/feature/gt/SingleFeatureCollectionFactory_ShapeFile.java
   trunk/src/edu/bonn/xulu/plugin/io/feature/gt/package.html
   trunk/src/edu/bonn/xulu/plugin/io/feature/package.html
   trunk/src/edu/bonn/xulu/plugin/io/grid/
   trunk/src/edu/bonn/xulu/plugin/io/grid/WritableGridFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/GridListFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/GridListFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/MultiGridFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/MultiGridFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/SingleGridFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/SingleGridFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/SingleGridFactory_GeoTiff.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/WritableGridArrayFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/WritableGridArrayFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/array/WritableGridArrayFactory_GeoTiff.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/GridListFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/GridListFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/MultiGridFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/MultiGridFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/SingleGridFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/SingleGridFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/SingleGridFactory_GeoTiff.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/WritableGridRasterFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/WritableGridRasterFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/WritableGridRasterFactory_GeoTiff.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/awt/package.html
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/GridCoverageFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/GridCoverageFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/GridCoverageFactory_GeoTiff.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/GridListFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/GridListFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/MultiGridFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/MultiGridFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/SingleGridFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/SingleGridFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/SingleGridFactory_GeoTiff.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/gt/package.html
   trunk/src/edu/bonn/xulu/plugin/io/grid/lateloading/
   trunk/src/edu/bonn/xulu/plugin/io/grid/lateloading/GridListFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/lateloading/GridListFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/lateloading/MultiGridFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/lateloading/MultiGridFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/lateloading/SingleGridFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/lateloading/SingleGridFactory_ArcInfoAsciiGrid.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/lateloading/SingleGridFactory_GeoTiff.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/lateloading/WritableGridLLFactory.java
   trunk/src/edu/bonn/xulu/plugin/io/grid/package.html
   trunk/src/edu/bonn/xulu/plugin/io/misc/
   trunk/src/edu/bonn/xulu/plugin/io/misc/CAAreaListFactory_ShapeFile.java
   trunk/src/edu/bonn/xulu/plugin/io/misc/CASettlementAreaListFactory_ShapeFile.java
   trunk/src/edu/bonn/xulu/plugin/io/misc/DynamicXuluObjectFactory_BasicStructure.java
   trunk/src/edu/bonn/xulu/plugin/io/misc/package.html
   trunk/src/edu/bonn/xulu/plugin/io/package.html
   trunk/src/edu/bonn/xulu/plugin/model/
   trunk/src/edu/bonn/xulu/plugin/model/ca/
   trunk/src/edu/bonn/xulu/plugin/model/ca/MultiCellularAutomaton.java
   trunk/src/edu/bonn/xulu/plugin/model/ca/agric/
   trunk/src/edu/bonn/xulu/plugin/model/ca/agric/ImpetusCellularAutomaton.java
   trunk/src/edu/bonn/xulu/plugin/model/ca/fire/
   trunk/src/edu/bonn/xulu/plugin/model/ca/fire/ImpetusFireCA.java
   trunk/src/edu/bonn/xulu/plugin/model/ca/fire/ImpetusFireCAContentManager.java
   trunk/src/edu/bonn/xulu/plugin/model/ca/reservoir/
   trunk/src/edu/bonn/xulu/plugin/model/ca/reservoir/SmallReservoirModel.java
   trunk/src/edu/bonn/xulu/plugin/model/ca/reservoir/SmallReservoirModelContentManager.java
   trunk/src/edu/bonn/xulu/plugin/model/clue/
   trunk/src/edu/bonn/xulu/plugin/model/clue/ClueModel.java
   trunk/src/edu/bonn/xulu/plugin/model/clue/ClueModelContentManager.java
   trunk/src/edu/bonn/xulu/plugin/model/clue/ClueModel_Optimized.java
   trunk/src/edu/bonn/xulu/plugin/model/clue/ClueModel_Original.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/
   trunk/src/edu/bonn/xulu/plugin/model/parallel/ClueModelContentManager.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/ClueModelParallel.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/ClueModel_deterministic.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/ClueParallelTuned.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/ClueTask.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/ClueTaskDefinition.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/ClueTaskTuned.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/demo/
   trunk/src/edu/bonn/xulu/plugin/model/parallel/demo/AVNTask.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/demo/AVNTuned.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/demo/AVNTunedTask.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/demo/AverageNeighborhoodContentManager.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/demo/AverageNeighborhoodParallelDemoModel.java
   trunk/src/edu/bonn/xulu/plugin/model/parallel/demo/AverageNeighborhoodSerialDemoModel.java
   trunk/src/edu/bonn/xulu/plugin/model/test/
   trunk/src/edu/bonn/xulu/plugin/model/test/TestModel.java
   trunk/src/edu/bonn/xulu/plugin/package.html
   trunk/src/edu/bonn/xulu/plugin/vis/
   trunk/src/edu/bonn/xulu/plugin/vis/GTEditorTool.java
   trunk/src/edu/bonn/xulu/plugin/vis/GTVisualisationTool.java
   trunk/src/edu/bonn/xulu/plugin/vis/JFreeChartVisualisationTool.java
   trunk/src/edu/bonn/xulu/plugin/vis/package.html
   trunk/src/overview.html
   trunk/src/schmitzm/
   trunk/src/skrueger/
   trunk/src/skrueger/gol/
   trunk/src/skrueger/gol/GameOfLife.java
   trunk/src/skrueger/gol/GameOfLifeContentManager.java
   trunk/startXULU.bat
Modified:
   trunk/
Log:
First Commit, corresponds to Revision 1008 of Wikisquare-SVN 


Property changes on: trunk
___________________________________________________________________
Name: svn:ignore
   + classes
javadoc


Added: trunk/InitXulu.bat
===================================================================
--- trunk/InitXulu.bat	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/InitXulu.bat	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,134 @@
+ at echo off
+rem =====================================================================
+rem  Initializes the XULU folder structure after the first SVN checkout
+rem  by copying default configuration files from the "defaults" folder
+rem  to their expected location.
+rem 
+rem  The default behavior is only to copy not existing files. If you
+rem  want to completly reset you configuration (in case of a partially
+rem  deleted or damaged configuration) you can use the command parameter
+rem  "/reset" to overwrite all files with their default.
+rem
+rem  Summery:
+rem     - copy "DefaultProperties" to main folder
+rem     - copy Eclipse configuration to main folder
+rem              - .classpath
+rem              - .project
+rem     - copy "startXulu.bat" to main folder
+rem     - copy XULU registry files to main folder
+rem              - registry.xif
+rem              - registry_arrayGrid.xif
+rem              - registry_ProxyGrid.xif
+rem     - XULU plugin configurations
+rem              - plugin\GeoModelCodeGenerator\* to plugin folder
+rem              - plugin\GTVisualisationColorMapPlugin\* to plugin folder
+rem              - plugin\LoggerPlugin\* to plugin folder
+rem              - plugin\RasterCalculator\* to plugin folder
+rem =====================================================================
+
+setlocal
+
+set SOURCE_DIR=defaults
+
+rem *** Reset mode >> Overwrite without confirm ***
+if "%1"=="/init"  (set COPY_PARAM=/Y) else set COPY_PARAM=/-Y
+if "%1"=="/init" goto overwrite
+rem *** Update mode >> Overwrite with confirm ***
+if "%1"=="/reset" goto overwrite
+rem *** Default mode >> only copy not existing files ***
+goto no_overwrite
+
+rem ************************** Update routine **************************
+:no_overwrite
+echo.
+echo.The XULU configuration will be updated with new files...
+echo.*** DefaultProperties ***
+if not exist DefaultProperties (copy %SOURCE_DIR%\DefaultProperties .) else echo.        'DefaultProperties' skipped!
+if not exist XuluProperties    (copy %SOURCE_DIR%\XuluProperties .)    else echo.        'XuluProperties' skipped!
+echo.*** Eclipse configuration ***
+if not exist .classpath (copy %SOURCE_DIR%\.classpath .) else echo.        '.classpath' skipped!
+if not exist .project   (copy %SOURCE_DIR%\.project .)   else echo.        '.project' skipped!
+echo.*** startXulu.bat ***
+if not exist startXulu.bat (copy %SOURCE_DIR%\startXulu.bat .) else echo.        'startXulu.bat' skipped!
+echo.*** sample XULU registry files ***
+if not exist registry.xif           (copy %SOURCE_DIR%\registry.xif .)           else echo.        'registry.xif' skipped!
+if not exist registry_arrayGrid.xif (copy %SOURCE_DIR%\registry_arrayGrid.xif .) else echo.        'registry_arrayGrid.xif' skipped!
+if not exist registry_ProxyGrid.xif (copy %SOURCE_DIR%\registry_ProxyGrid.xif .) else echo.        'registry_ProxyGrid.xif' skipped!
+echo.*** Plugin folder ***
+if not exist plugin (mkdir plugin)  else echo.        'plugin' folder already exists!
+echo.*** Template files for GeoModelCodeGenerator plugin ***
+set DDIR=plugin\GeoModelCodeGenerator
+set SDIR=%SOURCE_DIR%\%DDIR%
+if not exist %DDIR%                         (mkdir %DDIR%)                                         else echo.        folder '%DDIR%' already exists!
+if not exist %DDIR%\ModelContentManager.tpl (copy %SDIR%\ModelContentManager.tpl %DDIR%)           else echo.        'ModelContentManager.tpl' skipped!
+if not exist %DDIR%\StepModel.tpl           (copy %SDIR%\StepModel.tpl           %DDIR%)           else echo.        'StepModel.tpl' skipped!
+if not exist %DDIR%\XuluModel.tpl           (copy %SDIR%\XuluModel.tpl           %DDIR%)           else echo.        'XuluModel.tpl' skipped!
+echo.*** Template files for GTVisualisationColorMapPlugin ***
+set DDIR=plugin\GTVisualisationColorMapPlugin
+set SDIR=%SOURCE_DIR%\%DDIR%
+if not exist %DDIR%                 (mkdir %DDIR%)                        else echo.        folder '%DDIR%' already exists!
+if not exist %DDIR%\gtcolormaps.xif (copy %SDIR%\gtcolormaps.xif %DDIR%)  else echo.        'gtcolormaps.xif' skipped!
+echo.*** Template files for LoggerPlugin ***
+set DDIR=plugin\LoggerPlugin
+set SDIR=%SOURCE_DIR%\%DDIR%
+if not exist %DDIR%           (mkdir %DDIR%)                  else echo.        folder '%DDIR%' already exists!
+if not exist %DDIR%\log4j.cfg (copy %SDIR%\log4j.cfg %DDIR%)  else echo.        'log4j.cfg' skipped!
+echo.*** Template files for LoggerPlugin ***
+set DDIR=plugin\RasterCalculator
+set SDIR=%SOURCE_DIR%\%DDIR%
+if not exist %DDIR%                    (mkdir %DDIR%)                           else echo.        folder '%DDIR%' already exists!
+if not exist %DDIR%\default_filter.inp (copy %SDIR%\default_filter.inp %DDIR%)  else echo.        'default_filter.inp' skipped!
+
+goto finish
+
+rem ************************ Overwrite routine *************************
+:overwrite
+echo.
+echo.The XULU configuration will be completly reset!!
+echo.*** DefaultProperties ***
+copy %SOURCE_DIR%\DefaultProperties . %COPY_PARAM%
+copy %SOURCE_DIR%\XuluProperties    . %COPY_PARAM%
+echo.*** Eclipse configuration ***
+copy %SOURCE_DIR%\.classpath . %COPY_PARAM%
+copy %SOURCE_DIR%\.project .   %COPY_PARAM%
+echo.*** startXulu.bat ***
+copy %SOURCE_DIR%\startXulu.bat .   %COPY_PARAM%
+echo.*** sample XULU registry files ***
+copy %SOURCE_DIR%\registry.xif           .   %COPY_PARAM%
+copy %SOURCE_DIR%\registry_arrayGrid.xif .   %COPY_PARAM%
+copy %SOURCE_DIR%\registry_ProxyGrid.xif .   %COPY_PARAM%
+echo.*** Plugin folder ***
+if not exist plugin (mkdir plugin) else echo.        'plugin' folder already exists!
+echo.*** Template files for GeoModelCodeGenerator plugin ***
+set DDIR=plugin\GeoModelCodeGenerator
+set SDIR=%SOURCE_DIR%\%DDIR%
+if not exist %DDIR% (mkdir %DDIR%) else echo.        folder '%DDIR%' already exists!
+copy %SDIR%\ModelContentManager.tpl %DDIR% %COPY_PARAM%
+copy %SDIR%\StepModel.tpl           %DDIR% %COPY_PARAM%
+copy %SDIR%\XuluModel.tpl           %DDIR% %COPY_PARAM%
+echo.*** Template files for GTVisualisationColorMapPlugin ***
+set DDIR=plugin\GTVisualisationColorMapPlugin
+set SDIR=%SOURCE_DIR%\%DDIR%
+if not exist %DDIR% (mkdir %DDIR%) else echo.        folder '%DDIR%' already exists!
+copy %SDIR%\gtcolormaps.xif %DDIR% %COPY_PARAM%
+echo.*** Template files for LoggerPlugin ***
+set DDIR=plugin\LoggerPlugin
+set SDIR=%SOURCE_DIR%\%DDIR%
+if not exist %DDIR% (mkdir %DDIR%) else echo.        folder '%DDIR%' already exists!
+copy %SDIR%\log4j.cfg %DDIR% %COPY_PARAM%
+echo.*** Template files for LoggerPlugin ***
+set DDIR=plugin\RasterCalculator
+set SDIR=%SOURCE_DIR%\%DDIR%
+if not exist %DDIR% (mkdir %DDIR%) else echo.        folder '%DDIR%' already exists!
+copy %SDIR%\default_filter.inp %DDIR% %COPY_PARAM%
+
+
+goto finish
+
+
+rem ************************** Finish routine **************************
+:finish
+echo.Finished.
+echo.
+
+endlocal

Added: trunk/defaults/.classpath
===================================================================
--- trunk/defaults/.classpath	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/.classpath	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry excluding="**/.svn/" kind="src" path="src"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/SCHMITZM"/>
+	<classpathentry kind="lib" path="lib/jai-1_1_3/lib/clibwrapper_jiio.jar"/>
+	<classpathentry kind="lib" path="lib/jai-1_1_3/lib/jai_codec.jar"/>
+	<classpathentry kind="lib" path="lib/jai-1_1_3/lib/jai_core.jar"/>
+	<classpathentry kind="lib" path="lib/jai-1_1_3/lib/jai_imageio.jar"/>
+	<classpathentry kind="lib" path="lib/jai-1_1_3/lib/mlibwrapper_jai.jar"/>
+	<classpathentry kind="lib" path="lib/JavaRInterface/JRI.jar"/>
+	<classpathentry kind="lib" path="lib/jini/lib/tools.jar"/>
+	<classpathentry kind="lib" path="lib/schmitzm/schmitzm.jar"/>
+	<classpathentry kind="output" path="classes"/>
+</classpath>

Added: trunk/defaults/.project
===================================================================
--- trunk/defaults/.project	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/.project	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>XULU</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: trunk/defaults/DefaultProperties
===================================================================
--- trunk/defaults/DefaultProperties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/DefaultProperties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,145 @@
+#Default Properties for the Xulu Modelling Plattform
+#Thu Jan 25 20:20:05 CET 2007
+
+
+#************************************************************
+#********************* CRS Preferences **********************
+#************************************************************
+# Supported are EPSG-Codes "EPSG:..." and WKT-specifications
+# Benin --> UTM (zone xx) = EPSG:326xx
+General.DefaultCRS = EPSG\:32631
+General.DefaultCRS.doc = Default Coordinate-Reference-System for prj-less data (here: UTM zone 31 for Benin; allowed: EPSG-Codes "EPSG:..." or WKT-specifications as used in prj-files)
+
+#************************************************************
+#**************** XULU General Preferences ******************
+#************************************************************
+General.useSystemLookAndFeel = true
+General.useSystemLookAndFeel.doc = set this entry to false, if you have problems (e.g. with gnome), when using the system look and feel (
+
+Datatypes.proxy.enableUnloading = true
+Datatypes.proxy.enableUnloading.doc = if true the Xulu-models have the ability to unload no longer used data into a temporaray folder
+Datatypes.proxy.unloadFolder = Temp
+Datatypes.proxy.unloadFolder.doc = The folder in which the models are unloaded (if unloading is enabled)
+Datatypes.xulugrid.alwaysconvert = true
+Datatypes.xulugrid.alwaysconvert.doc = if true, every time a arcgridraster is converted to xulugridfile (in a new file). If false, this is only done if no xulugridfile with the same name exists
+Datatypes.xulugrid.creationFolder = Temp
+Datatypes.xulugrid.creationFolder.doc  = The folder where new empty xulugridfiles are created
+
+#************************************************************
+#**************** XULU/V General Preferences ****************
+#************************************************************
+
+#General#
+Parallel.splitmapforclass.default = appl.parallel.spmd.split.SplitMap1DVertical
+Parallel.splitmapforclass.default.doc = The default splitmap used for partitioning
+Parallel.splitmapforclass.XuluWritableGridFile = appl.parallel.spmd.split.SplitMap1DVertical
+Parallel.splitmapforclass.XuluWritableGridFile.doc = The Splitmap used for partitioning SplittableProxyGrids
+Parallel.splitmapforclass.SplittableLLProxyGrid = appl.parallel.spmd.split.SplitMap1DVertical
+Parallel.splitmapforclass.SplittableLLProxyGrid.doc = The Splitmap used for partitioning SplittableProxyGrids
+
+Parallel.partitionhandlerfactory.classname = appl.parallel.data.XuluClientLoader
+Parallel.partitionhandlerfactory.classname.doc = the loader used for data loading.
+
+## Benchmark ##
+Benchmark.SimpleBench.gridwidth = 100
+Benchmark.SimpleBench.gridwidth.doc = The width and height of the grid used for benchmarking
+Benchmark.SimpleBench.runningtime = 1500
+Benchmark.SimpleBench.runningtime.doc = The time in ms the benchmark runs. The longer the bench runs, the higher the rating and the accuracy
+Benchmark.SimpleBench.neighborhood = 10
+Benchmark.SimpleBench.neighborhood.doc = The neighborhood range which is used in the bench. Higher values will decrease the rating
+Benchmark.SimpleBench.calibrator = 4.25
+Benchmark.SimpleBench.calibrator.doc = After calculation the rating is divided by this integer value
+
+#***********************************************************
+#*************** XULU/V Client Preferences *****************
+#***********************************************************
+
+XuluClient.registryport.doc = Port for the registry on clientside
+XuluClient.registryport = 1099
+
+##Initialize Options##
+RemoteExecutionController.startlocalxuluserver=true
+RemoteExecutionController.startlocalxuluserver.doc = if true a local instance of the xuluServer is started
+RemoteExecutionController.spmd.start=true
+RemoteExecutionController.spmd.start.doc = if true a SPMDClient is started
+RemoteExecutionController.http.start = true
+RemoteExecutionController.http.start.doc = starts the HTTP-Server each time the controller is started
+RemoteExecutionController.http.basedir = ./classes
+RemoteExecutionController.http.basedir.doc = Use slashes or double backslashes as seperator! The directory which will be the root directory of the http-server (should be the root of your classfiles)
+RemoteExecutionController.http.port = 80
+RemoteExecutionController.http.port.doc = The port of the httpserver (should be 80)
+RemoteExecutionController.http.verbose = true
+RemoteExecutionController.http.verbose.doc = if true the http-server gives output to the console
+
+## Discovery ##
+DiscoveryServices.activeServices.doc = All active Discovery Services. Separate multiple entries by ';'
+DiscoveryServices.activeServices = appl.parallel.services.HostnameDiscoveryService
+DiscoveryServices.timeout = 500
+DiscoveryServices.timeout.doc = The time the discovery service waits on a response from the server
+DiscoveryServices.hostname.hosts.doc = The hosts which should be checked for computing resources (only when HostnameDiscovery is enabled). Separate multiple entries by ';'
+DiscoveryServices.hostname.hosts = localhost
+DiscoveryServices.hostname.refresh.doc = if refresh is set to 0 resources are only discovered once. Only existing resources are refreshed.
+DiscoveryServices.hostname.refresh = 1
+DiscoveryServices.multicast.port.doc = The port for multicastMessages on client side
+DiscoveryServices.multicast.port = 10000
+DiscoveryServices.multicast.group.doc = The multicast group IP
+DiscoveryServices.multicast.group = 239.1.1.1
+#DiscoveryServices.multicast.renewal.doc = currently not used
+#DiscoveryServices.multicast.renewal = 500
+
+#************************************************************
+#**************** XULU/V Server Preferences *****************
+#************************************************************
+XuluServer.priority = 3
+XuluServer.priority.doc = The priority for task execution on serverside. Use values from 1 to 5 with 3=normal 
+
+XuluServer.useThreads = max
+XuluServer.useThreads.doc = The number of threads to be used by the server for tasks that support multi-threading. Per default one thread is created for every available Processors (value='max'). More threads than processors may be useful for testing tasks which support multihreading or for processors which support hyperthreading 
+XuluServer.benchmarkclass = appl.util.benchmark.SimpleBenchmark
+XuluServer.benchmarkclass.doc = The benchmark-class used for getting rating. Leave blank for disabling the bench.
+XuluServer.runbench = true
+XuluServer.runbench.doc = if true, the benchmark is automatically run
+
+XuluServer.multicastgroup.doc = The XuluServerMulticast group IP (should be the same as MulticastDiscoveryService.multicastgroup)
+XuluServer.multicastgroup = 239.1.1.1
+XuluServer.registryport.doc = The port which is used for the registry in XuluServer
+XuluServer.registryport = 1099
+XuluServer.multicastport.doc = The port which is used on serverside to receive and send multicast messages
+XuluServer.multicastport = 10000
+
+XuluServer.eventDelay = 100
+XuluServer.eventDelay.doc = Events are collected on serverside and submitted ever <DELAY> milliseconds
+
+XuluServer.log4j.logLevel = warn
+XuluServer.log4j.logLevel.doc = Possible Values: info,debug,warn,error,fatal,off
+XuluServer.log4j.mode = console
+XuluServer.log4j.mode.doc = Possible Values: chainsaw, console, file
+
+XuluServer.useCodeDownloading = false
+XuluServer.useCodeDownloading.doc = Set to true, if you want to use the code downloading functionality
+
+### Xulu/V starter
+XuluServerStarter.port = 1099
+XuluServerStarter.port.doc = The port where the starter creates the registry, if needed
+XuluServerStarter.javaprogram = java
+XuluServerStarter.javaprogram.doc The path to the java.exe which should be used for execution (or just java, if in the classpath)
+XuluServerStarter.codebasedir = ./classes
+XuluServerStarter.codebasedir.doc = The codebase path (the path to the binaries)
+XuluServerStarter.securitypolicy = security.policy
+XuluServerStarter.securitypolicy.doc = The security policy which should be used for Server starting
+XuluServerStarter.furtherjavaarguments =
+XuluServerStarter.furtherjavaarguments.doc = further arguments for the Java VM
+XuluServerStarter.classpath = .;classes
+XuluServerStarter.classpath.doc = libaries, which should be on the classpath
+XuluServerStarter.memorymax = 64
+XuluServerStarter.memorymin = 4
+
+## ********************** Documentation only ******************
+SimpleCommEventMonitor.timemonitoring.doc = if true, timeEvents are generated for parallel computation. This may cost some performance
+SimpleCommEventMonitor.transfermonitoring.doc = if true, transferEvents are generated for parallel computation. This WILL cost a lot of performance
+
+## *************** Filter (excluding key from editor view)***********
+Filter.prefixes = Filter;SimpleCommEventMonitor
+Filter.prefixes.doc =  all prefixes which show up here are not displayed in the Configuration editor. Divide by ;
+Filter.keys =
+Filter.keys.doc = all keys (=Prefix + "." + Suffix) which show up here are not displayed in the configuration editor. Divide by ;

Added: trunk/defaults/XuluProperties
===================================================================
--- trunk/defaults/XuluProperties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/XuluProperties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,7 @@
+#Stored properties of the Xulu modelling platform
+#Wed Feb 25 12:47:39 WAT 2009
+RecentImports.MAXLOAD=10
+RecentImports.SIZE=0
+RecentScripts.SIZE=0
+Console.Logging=false
+RecentScripts.MAXLOAD=10

Added: trunk/defaults/plugin/GTVisualisationColorMapPlugin/gtcolormaps.xif
===================================================================
--- trunk/defaults/plugin/GTVisualisationColorMapPlugin/gtcolormaps.xif	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/plugin/GTVisualisationColorMapPlugin/gtcolormaps.xif	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,96 @@
+//========================================================================
+//
+//   Bei dieser Datei handelt es sich um die Input-Datei des Xulu-Plugins
+//    >>> schmitzm.dipl.xulu.plugin.appl.GTVisualisationColorMapPlugin <<<
+//   Dieses laed vordefinierte Farbpaletten fuer Rasterdaten in die
+//   Xulu-Visualisierungstools der Klasse
+//    >>> schmitzm.dipl.xulu.plugin.vis.GTVisualisationTool <<<
+//
+//   Damit das Plugin diese Datei korrekt einlesen kann, muss die Datei den
+//   statischen Namen "gtcolormaps.xif" tragen!!
+//
+//   Die Datei kann mehrere Farbpaletten enthalten. Jede Farbpalette wird
+//   von einem [..]-Tag eingeleitet, wobei die Bezeichnung zwischen den
+//   Klammern als Name fuer die Farbpalette verwendet wird.
+//   Nach dem [..]-Tag folgen die Farbpaletten-Eintraege der Form
+//
+//                 <raster wert> <color> [<label>]
+//
+//   Die Farbe kann auf mehrere Arten spezifiziert werden:
+//     a) Als RGB-Werte der Form "RGB(<red>,<green>,<blue>)".
+//        Die RGB-Werte muessen durch Komma und OHNE Leerzeichen
+//        voneinander getrennt sein.
+//     b) Als dezimaler (1234) oder hexadezimaler Integer-Wert (0x123456),
+//        aus dem die 3 RGB-Komponenten extrahiert werden
+//     c) Als String, der die Farbe identifiziert. Hierfuer sind alle
+//        Farb-Bezeichnungen zulaessig, die in der Klasse java.awt.Color
+//        als (statische) Felder deklariert sind.
+//        z.B. Black, Blue, Cyan, Gray, Green, Magenta, Orange, Pink,
+//             Red, White, Yellow
+//
+//========================================================================
+
+
+//###### Black & White Color-Map #######
+[Black/White]
+0	0x000000 #RGB(0,0,0)
+9999	0xFFFFFF #RGB(255,255,255)
+
+//###### Red & Green Color-Map #######
+[Red/Green]
+0	0xFF0000 # Rot   = RGB(255,0,0)
+9999	0x00FF00 # Gruen = RGB(0,255,00)
+
+//###### Bunte Test-Farbpalette ######
+[Bunt-Test]
+0	RGB(0,0,255)      # Blau
+1	RGB(128,128,128)  # Grau
+2	RGB(255,255,0)    # Gelb
+3	RGB(255,0,0)      # Rot
+4	RGB(0,255,255)    # Cyan
+5	RGB(255,0,255)    # Magenta
+
+//###### Bunte Test-Farbpalette ######
+[Name-Test]
+0	BLUE
+1	Gray
+2	Yellow
+3	Red
+4	cyan
+5	magenta
+
+//###### Farbschema fuer Impetus Clue (1) ######
+[Impetus Clue 0-5]
+0	BLUE            # Blau = Siedlung
+1	RGB(51,51,0)    # Dunkel-Braun = intesive Landwirtschaft
+2	RGB(204,153,80) # Hell-Braun = weniger intensive Landwirtschaft
+3	RGB(0,160,0)    # Dunkel-Gruen = dichter Wald
+4	RGB(170,255,0)  # Gruen = dichte Savanne
+5	RGB(204,255,0)  # Hell-Gruen = restliche Savanne / Sonstiges
+
+//###### Farbschema fuer Impetus Clue (2) ######
+[Impetus Clue 0-3]
+0	RED            # Rot = Siedlung
+1	RGB(204,153,0) # Braun = Landwirtschaft
+2	RGB(0,160,0)   # Dunkel-Gruen = dichter Wald/Savanne
+3	RGB(204,255,0) # Hell-Gruen = restliche Savanne / Sonstiges
+
+//###### Farbschema fuer den Impetus CA ######
+[Impetus CA]
+DEFAULT
+0	WHITE            // Weiss = Unclassified
+1	RGB(0,160,0)     // Dunkel-Gruen = Forest dense
+2	RGB(204,255,0)   // Hell-Gruen = Foret claire
+3	RGB(102,102,0)   // Braun-Gruen = Savanne Boise
+4	RGB(153,153,0)   // Ocker = Savanne Arboree
+5	RGB(102,255,102) // Hell-Gruen = Inselberg with Vegetation
+6	RGB(51,51,0)     // Dunkel-Braun = Savanne Saxicole
+7	BLACK            // Schwarz = Bas Fond
+8	BLUE             // Blau = Fluss
+9	RGB(153,153,255) // Hell-Blau = Flussbett
+10	RGB(204,0,0)     // Dunkel-Rot = Dichte Siedlung (Stadt)
+11	RGB(255,102,102) // Hell-Rot = Lockere Siedlung (Dorf)
+12	RGB(204,153,80)  // Hell-Braun = Feld/Brache
+13	RGB(170,255,0)   // Gruen = Inselberg
+14	RGB(204,153,0)   // Braun = Brache
+15	CYAN             // Cyan = Siedlungsexpansion
\ No newline at end of file

Added: trunk/defaults/plugin/GeoModelCodeGenerator/ModelContentManager.tpl
===================================================================
--- trunk/defaults/plugin/GeoModelCodeGenerator/ModelContentManager.tpl	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/plugin/GeoModelCodeGenerator/ModelContentManager.tpl	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,29 @@
+package $FIELD(Package);
+
+$LOOP(ClassImport)
+import $FIELD(ClassImport);
+$ENDLOOP()
+
+/**
+ * Diese Klasse definiert und verwaltet die $FIELD(ResourceCount)
+ * Ressourcen fuer das Modell {@linkplain $FIELD(ModelName)}
+ * und prueft diese auf Korrektheit.<br>
+ * Die Art der benoetigten Ressourcen ist der {@linkplain $FIELD(ModelName)}-Doku
+ * zu entnehmen.
+ * @see ClueModelContentManager
+ * @author automatisch generiert durch {@link edu.bonn.xulu.plugin.appl.GeoModelCodeGenerator}
+ * @version 1.0
+ */
+public class $FIELD(ModelCMName) extends $FIELD(ModelCMSuperClass) {
+
+  /**
+   * Erzeugt einen neuen ContentManager fuer das Modell {@linkplain $FIELD(ModelName)}.
+   */
+  public $FIELD(ModelCMName)() {
+    super($FIELD(ResourceCount));
+    // ===== Ressourcen festlegen =====
+$LOOP(Resources)
+    // $FIELD(ResourceDesc)
+    resource[$FIELD(ResourceNo)] = $FIELD(ResourceDefinition);
+$ENDLOOP()  }
+}

Added: trunk/defaults/plugin/GeoModelCodeGenerator/StepModel.tpl
===================================================================
--- trunk/defaults/plugin/GeoModelCodeGenerator/StepModel.tpl	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/plugin/GeoModelCodeGenerator/StepModel.tpl	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,94 @@
+package $FIELD(Package);
+
+$LOOP(ClassImport)
+import $FIELD(ClassImport);
+$ENDLOOP()
+
+/**
+ * Diese Klasse stellt eine Implementierung des Modells {@linkplain $FIELD(ModelName)}
+ * dar. Dieses benoetigt $FIELD(ResourceCount) Ressourcen, welche durch den
+ * {@linkplain $FIELD(ModelCMName)} spezifiziert werden:
+ * <ol>
+$LOOP(Resources)
+ * <li><b>$FIELD(ResourceDesc) ({@code $FIELD(ResourceVar)}):</b>
+ *     @todo Detaillierte Ressoucen-Beschreibung einfuegen
+ *     </li>
+$ENDLOOP() * </ol>
+ * @see $FIELD(ModelCMName)
+ * @author automatisch generiert durch {@link edu.bonn.xulu.plugin.appl.GeoModelCodeGenerator}
+ * @version 1.0
+ */
+public class $FIELD(ModelName) extends $FIELD(ModelSuperClass) {
+  /** Speichert den ContentManager fuer das Modell.
+   *  @see $FIELD(ModelCMName) */
+  protected $FIELD(ModelCMName) contManager;
+
+  //********** Lese/Schreibrechte, die fuer den gesamten ***********
+  //********** Modellanlauf gehalten werden muessen      ***********
+$LOOP(PropertyResources)
+  private $FIELD(ResourceAccessType)  $FIELD(ResourceAccessVar) = null;  // $FIELD(PropertyResourceDesc)
+$ENDLOOP()
+  //**************** Variablen mit denen gearbeitet wird *******************
+$LOOP(Resources)
+  private  $FIELD(ResourceVarType)  $FIELD(ResourceVar) = null; // $FIELD(ResourceDesc)
+$ENDLOOP()
+  /**
+   * Erzeugt eine neue Instanz des Modells.
+   */
+  public $FIELD(ModelName)() {
+    super( new $FIELD(ModelCMName)() );
+    contManager = ($FIELD(ModelCMName))super.contManager;
+  }
+
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////   Implementierung von AbstractXuluModel   //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Initialisiert das Model, indem die Ressourcen aus dem ContentManager
+   * geladen werden und mit Lese/Schreib-Rechten versehen werden. Zudem
+   * werden Referenzen auf die Ressourcen in lokalen Variablen
+   * gespeichert, um waehrend des Modellablaufs effizienter darauf zugreifen
+   * zu koennen.
+   */
+  public void performModelInit() {
+    if ( contManager == null )
+      return;
+    // Zugriffsrechte aus Ressourcen/Propertys holen
+$LOOP(PropertyResources)
+    $FIELD(ResourceAccessVar) = null;
+    if ( contManager.getResource($FIELD(PropertyResourceNo)).getData() != null )
+      $FIELD(ResourceAccessVar) = (($FIELD(PropertyResourceType))contManager.getResource($FIELD(PropertyResourceNo)).getData())$FIELD(ResourceAccessAlloc);
+$ENDLOOP()
+    // Variablen belegen mit denen gearbeitet wird
+$LOOP(Resources)
+    $FIELD(ResourceVar) = $FIELD(ResourceVarAlloc);
+$ENDLOOP()
+     // WICHTIG:
+     // An dieser Stelle die Anzahl an Modellschritten (aus einer
+     // Ressource) zuweisen, die das Modell laufen soll!
+     // Sonst laeuft das Modell nicht an!!
+    this.stepCount = 0;
+  }
+
+  /**
+   * Gibt die Lese/Schreibrechte auf das Ein- und Ausgaberaster wieder frei.
+   * Interne Ressourcen brauchen keine aus dem Speicher entfernt werden.
+   */
+  public void performModelDispose() {
+    // Ressourcen wieder freigeben
+$LOOP(PropertyResources)
+    releaseAccess($FIELD(ResourceAccessVar));
+$ENDLOOP()  }
+
+  /**
+   * Fuehrt einen Schritt des Modellablaufs durch.
+   * @param stepNo zu modellierender Schritt (beginnend bei 1!)
+   */
+  public void performModelStep(int stepNo) {
+    // @todo An dieser Stelle den Ablauf eines Modellschritts implementieren
+    
+    // Ueber die Variable 'statusOut' koennen Status-Ausgaben im
+    // Modellfenster ausgegeben werden.
+  }
+}

Added: trunk/defaults/plugin/GeoModelCodeGenerator/XuluModel.tpl
===================================================================
--- trunk/defaults/plugin/GeoModelCodeGenerator/XuluModel.tpl	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/plugin/GeoModelCodeGenerator/XuluModel.tpl	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,87 @@
+package $FIELD(Package);
+
+$LOOP(ClassImport)
+import $FIELD(ClassImport);
+$ENDLOOP()
+
+/**
+ * Diese Klasse stellt eine Implementierung des Modells {@linkplain $FIELD(ModelName)}
+ * dar. Dieses benoetigt $FIELD(ResourceCount) Ressourcen, welche durch den
+ * {@linkplain $FIELD(ModelCMName)} spezifiziert werden:
+ * <ol>
+$LOOP(Resources)
+ * <li><b>$FIELD(ResourceDesc) ({@code $FIELD(ResourceVar)}):</b>
+ *     @todo Detaillierte Ressoucen-Beschreibung einfuegen
+ *     </li>
+$ENDLOOP() * </ol>
+ * @see $FIELD(ModelCMName)
+ * @author automatisch generiert durch {@link edu.bonn.xulu.plugin.appl.GeoModelCodeGenerator}
+ * @version 1.0
+ */
+public class $FIELD(ModelName) extends $FIELD(ModelSuperClass) {
+  /** Speichert den ContentManager fuer das Modell.
+   *  @see $FIELD(ModelCMName) */
+  protected $FIELD(ModelCMName) contManager;
+
+  //********** Lese/Schreibrechte, die fuer den gesamten ***********
+  //********** Modellanlauf gehalten werden muessen      ***********
+$LOOP(PropertyResources)
+  private $FIELD(ResourceAccessType)  $FIELD(ResourceAccessVar) = null;  // $FIELD(PropertyResourceDesc)
+$ENDLOOP()
+  //**************** Variablen mit denen gearbeitet wird *******************
+$LOOP(Resources)
+  private  $FIELD(ResourceVarType)  $FIELD(ResourceVar) = null; // $FIELD(ResourceDesc)
+$ENDLOOP()
+  /**
+   * Erzeugt eine neue Instanz des Modells.
+   */
+  public $FIELD(ModelName)() {
+    super( new $FIELD(ModelCMName)() );
+    contManager = ($FIELD(ModelCMName))super.contManager;
+  }
+
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////   Implementierung von AbstractXuluModel   //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Initialisiert das Model, indem die Ressourcen aus dem ContentManager
+   * geladen werden und mit Lese/Schreib-Rechten versehen werden. Zudem
+   * werden Referenzen auf die Ressourcen in lokalen Variablen
+   * gespeichert, um waehrend des Modellablaufs effizienter darauf zugreifen
+   * zu koennen.
+   */
+  public void performModelInit() {
+    if ( contManager == null )
+      return;
+    // Zugriffsrechte aus Ressourcen/Propertys holen
+$LOOP(PropertyResources)
+    $FIELD(ResourceAccessVar) = null;
+    if ( contManager.getResource($FIELD(PropertyResourceNo)).getData() != null )
+      $FIELD(ResourceAccessVar) = (($FIELD(PropertyResourceType))contManager.getResource($FIELD(PropertyResourceNo)).getData())$FIELD(ResourceAccessAlloc);
+$ENDLOOP()
+    // Variablen belegen mit denen gearbeitet wird
+$LOOP(Resources)
+    $FIELD(ResourceVar) = $FIELD(ResourceVarAlloc);
+$ENDLOOP()  }
+
+  /**
+   * Gibt die Lese/Schreibrechte auf das Ein- und Ausgaberaster wieder frei.
+   * Interne Ressourcen brauchen keine aus dem Speicher entfernt werden.
+   */
+  public void performModelDispose() {
+    // Ressourcen wieder freigeben
+$LOOP(PropertyResources)
+    releaseAccess($FIELD(ResourceAccessVar));
+$ENDLOOP()  }
+
+  /**
+   * Fuehrt den kompletten Modellablauf durch.
+   */
+  public void performModelStart() {
+    // @todo An dieser Stelle den Ablauf des Modells implementieren
+    
+    // Ueber die Variable 'statusOut' koennen Status-Ausgaben im
+    // Modellfenster ausgegeben werden.
+  }
+}

Added: trunk/defaults/plugin/LoggerPlugin/log4j.cfg
===================================================================
--- trunk/defaults/plugin/LoggerPlugin/log4j.cfg	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/plugin/LoggerPlugin/log4j.cfg	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,42 @@
+# Consolen-Appender mit TTCC-Layout definieren
+log4j.appender.CONSOLE        = org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern =%d{yyyy-MM-dd\thh:mm:ss}\t%r\t%p\t%c\t%m%n
+
+
+
+# File-Appender "xulu.log" mit TTCC-Layout definieren
+log4j.appender.XULULOG             = org.apache.log4j.RollingFileAppender
+log4j.appender.XULULOG.File        = log\\xulu.log
+log4j.appender.XULULOG.MaxFileSize = 10MB
+log4j.appender.XULULOG.layout = org.apache.log4j.PatternLayout
+log4j.appender.XULULOG.layout.ConversionPattern =%d{yyyy-MM-dd\thh:mm:ss}\t%r\t%p\t%c\t%m%n
+
+
+# File-Appender "clue_log.csv" mit TTCC-Layout definieren
+log4j.appender.CLUELOG             = org.apache.log4j.RollingFileAppender
+log4j.appender.CLUELOG.File        = log\\clue_log.csv
+log4j.appender.CLUELOG.MaxFileSize = 10MB
+#log4j.appender.CLUELOG.append      = false
+log4j.appender.CLUELOG.layout = org.apache.log4j.PatternLayout
+#log4j.appender.CLUELOG.layout.ConversionPattern =%d{yyyy-MM-dd;hh:mm:ss};%r;%p;%c;%C:%L;%m%n
+log4j.appender.CLUELOG.layout.ConversionPattern =%d{yyyy-MM-dd|hh:mm:ss}|%r|%p|%c|%C:%L|%m%n
+
+
+# Root-Logger definieren
+log4j.rootLogger = ERROR, CONSOLE
+
+# Applikations-Logger definieren
+log4j.logger.edu.bonn.xulu = ERROR, XULULOG
+
+# Modell-Logger
+# --> alle Log-Ausgaben von Modellen sollen nicht auch noch in die Xulu-Log
+#     geschrieben oder auf der Console ausgegeben werden (edu.bonn.xulu.model.XXX
+#     erbt Appender von edu.bonn.xulu)
+# --> Dummy-Logger erzeugen ohne Additivitaet (und ohne Appender)
+log4j.logger.edu.bonn.xulu.plugin.model = OFF
+log4j.additivity.edu.bonn.xulu.plugin.model = FALSE
+
+log4j.logger.edu.bonn.xulu.plugin.model.ClueModel = OFF, CLUELOG
+log4j.logger.edu.bonn.xulu.plugin.model.ClueModel_Optimized = OFF, CLUELOG
+

Added: trunk/defaults/plugin/RasterCalculator/default_filter.inp
===================================================================
--- trunk/defaults/plugin/RasterCalculator/default_filter.inp	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/plugin/RasterCalculator/default_filter.inp	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,10 @@
+#===================================
+# Name des Xulu-Objekts
+XuluObjectName = DEFAULT-FILTER
+#===================================
+
+[Test]
+Type  = schmitzm.data.property.MatrixProperty; 3; 3
+Value =	0;	1;	0;
+Value =	1;	1;	1;
+Value =	0;	1;	0;

Added: trunk/defaults/registry.xif
===================================================================
--- trunk/defaults/registry.xif	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/registry.xif	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,74 @@
+//########### Klassen werden "fuer alles" registriert ###########
+[Global]
+
+//########### Klassen werden als Datentyp registriert ###########
+[DataType]
+edu.bonn.xulu.data.DynamicXuluObject
+edu.bonn.xulu.plugin.data.grid.SingleGrid
+ 
+ 
+//########### Klassen als Default-Factory registriert ###########
+[DefaultFactory]
+edu.bonn.xulu.data.DynamicXuluObject$DefaultFactory
+edu.bonn.xulu.plugin.io.grid.awt.SingleGridFactory
+ 
+//########### Klassen als Import-Factory registriert ###########
+[ImportFactory]
+edu.bonn.xulu.plugin.io.grid.awt.SingleGridFactory_ArcInfoAsciiGrid		SingleGrid aus ArcInfoASCII
+edu.bonn.xulu.plugin.io.grid.awt.SingleGridFactory_GeoTiff			SingleGrid aus GeoTiff
+edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory_ShapeFile	FeatureCollection aus ShapeFile
+edu.bonn.xulu.plugin.io.misc.DynamicXuluObjectFactory_BasicStructure		Dynamisches Xulu-Objekt aus ASCII-File
+edu.bonn.xulu.plugin.io.grid.awt.GridListFactory_ArcInfoAsciiGrid		GridList aus ArcausfoASCII 
+edu.bonn.xulu.plugin.io.grid.awt.MultiGridFactory_ArcInfoAsciiGrid		MultiGrid aus ArcInfoASCII
+edu.bonn.xulu.plugin.io.misc.CAAreaListFactory_ShapeFile			CA-Areas aus ShapeFile
+ 
+//########### Klassen als Export-Factory registriert ###########
+[ExportFactory]
+edu.bonn.xulu.plugin.io.grid.awt.SingleGridFactory_ArcInfoAsciiGrid		SingleGrid in ArcInfoASCII
+edu.bonn.xulu.plugin.io.grid.awt.SingleGridFactory_GeoTiff			SingleGrid in GeoTiff
+edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory_ShapeFile	FeatureCollection in ShapeFile
+edu.bonn.xulu.plugin.io.misc.DynamicXuluObjectFactory_BasicStructure		Dynamisches Xulu-Objekt in ASCII-File
+edu.bonn.xulu.plugin.io.grid.awt.GridListFactory_ArcInfoAsciiGrid		GridList in ArcInfoASCII 
+edu.bonn.xulu.plugin.io.grid.awt.MultiGridFactory_ArcInfoAsciiGrid		MultiGrid in ArcInfoASCII
+
+//########### TypeMapping ###########
+[TypeMapping]
+// Format:
+// DatenTyp-Klasse                                              Default-Factory-Klasse                                                  [Im/Export-Klassen ...] 
+//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+edu.bonn.xulu.data.DynamicXuluObject                       edu.bonn.xulu.data.DynamicXuluObject$DefaultFactory                edu.bonn.xulu.plugin.io.misc.DynamicXuluObjectFactory_BasicStructure
+edu.bonn.xulu.plugin.data.grid.SingleGrid                  edu.bonn.xulu.plugin.io.grid.awt.SingleGridFactory                 edu.bonn.xulu.plugin.io.grid.awt.SingleGridFactory_ArcInfoAsciiGrid
+edu.bonn.xulu.plugin.data.grid.GridList                    edu.bonn.xulu.plugin.io.grid.awt.GridListFactory                   edu.bonn.xulu.plugin.io.grid.awt.GridListFactory_ArcInfoAsciiGrid
+edu.bonn.xulu.plugin.data.grid.MultiGrid                   edu.bonn.xulu.plugin.io.grid.awt.MultiGridFactory                  edu.bonn.xulu.plugin.io.grid.awt.MultiGridFactory_ArcInfoAsciiGrid
+edu.bonn.xulu.plugin.data.feature.SingleFeatureCollection  edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory  edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory_ShapeFile
+
+//########### Visualisierungstools ###########
+[Visualisation]
+edu.bonn.xulu.plugin.vis.GTVisualisationTool
+edu.bonn.xulu.plugin.vis.GTEditorTool
+edu.bonn.xulu.plugin.vis.JFreeChartVisualisationTool
+
+//########### Modellklassen ###########
+[Model]
+edu.bonn.xulu.plugin.model.clue.ClueModel
+edu.bonn.xulu.plugin.model.test.TestModel
+edu.bonn.xulu.plugin.model.ca.agric.ImpetusCellularAutomaton
+edu.bonn.xulu.plugin.model.ca.fire.ImpetusFireCA
+edu.bonn.xulu.plugin.model.ca.reservoir.SmallReservoirModel
+skrueger.gol.GameOfLife
+
+//########### Skript-Interpreter ###########
+[Script]
+edu.bonn.xulu.plugin.appl.DataScriptInterpreter_Basic Datenpool-Skript
+edu.bonn.xulu.plugin.appl.ModelResourceMappingScriptInterpreter_Basic Modell-Daten-Zuordnung
+
+//########### Plugins ###########
+[Plugin]
+edu.bonn.xulu.plugin.appl.LoggerPlugin                  AUTOSTART Anzeige und Kontrolle von Log4j-Loggern
+edu.bonn.xulu.plugin.appl.DateTimePlugin                          Aktuelle Zeit in der Titelleiste
+edu.bonn.xulu.plugin.appl.DateTimeWindowPlugin                    Aktuelle Zeit in einem Fenster
+edu.bonn.xulu.plugin.appl.GTVisualisationColorMapPlugin AUTOSTART Farbpaletten fuer GTVisualisationTool
+edu.bonn.xulu.plugin.appl.ModelTimeSnifferPlugin                  Modell-Laufzeiten messen und ausgeben
+edu.bonn.xulu.plugin.appl.GeoModelCodeGeneratorPlugin   AUTOSTART SourceCode-Generator fuer Geo-Modelle
+edu.bonn.xulu.plugin.appl.RasterCalculatorPlugin        AUTOSTART Taschenrechner fuer Raster
+appl.ext.ConfigurationEditorPlugin                      AUTOSTART Konfigurationsfenster

Added: trunk/defaults/registry_ProxyGrid.xif
===================================================================
--- trunk/defaults/registry_ProxyGrid.xif	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/registry_ProxyGrid.xif	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,74 @@
+//########### Klassen werden "fuer alles" registriert ###########
+[Global]
+
+//########### Klassen werden als Datentyp registriert ###########
+[DataType]
+edu.bonn.xulu.data.DynamicXuluObject
+edu.bonn.xulu.plugin.data.grid.SingleGrid
+ 
+ 
+//########### Klassen als Default-Factory registriert ###########
+[DefaultFactory]
+edu.bonn.xulu.data.DynamicXuluObject$DefaultFactory
+edu.bonn.xulu.plugin.io.grid.lateloading.SingleGridFactory
+ 
+//########### Klassen als Import-Factory registriert ###########
+[ImportFactory]
+edu.bonn.xulu.plugin.io.grid.lateloading.SingleGridFactory_ArcInfoAsciiGrid		SingleGrid aus ArcInfoASCII
+edu.bonn.xulu.plugin.io.grid.lateloading.SingleGridFactory_GeoTiff			SingleGrid aus GeoTiff
+edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory_ShapeFile	FeatureCollection aus ShapeFile
+edu.bonn.xulu.plugin.io.misc.DynamicXuluObjectFactory_BasicStructure		Dynamisches Xulu-Objekt aus ASCII-File
+edu.bonn.xulu.plugin.io.grid.lateloading.GridListFactory_ArcInfoAsciiGrid		GridList aus ArcausfoASCII 
+edu.bonn.xulu.plugin.io.grid.lateloading.MultiGridFactory_ArcInfoAsciiGrid		MultiGrid aus ArcInfoASCII
+edu.bonn.xulu.plugin.io.misc.CAAreaListFactory_ShapeFile			CA-Areas aus ShapeFile
+ 
+//########### Klassen als Export-Factory registriert ###########
+[ExportFactory]
+edu.bonn.xulu.plugin.io.grid.array.SingleGridFactory_ArcInfoAsciiGrid		SingleGrid in ArcInfoASCII
+edu.bonn.xulu.plugin.io.grid.array.SingleGridFactory_GeoTiff			SingleGrid in GeoTiff
+edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory_ShapeFile	FeatureCollection in ShapeFile
+edu.bonn.xulu.plugin.io.misc.DynamicXuluObjectFactory_BasicStructure		Dynamisches Xulu-Objekt in ASCII-File
+edu.bonn.xulu.plugin.io.grid.array.GridListFactory_ArcInfoAsciiGrid		GridList in ArcInfoASCII 
+edu.bonn.xulu.plugin.io.grid.array.MultiGridFactory_ArcInfoAsciiGrid		MultiGrid in ArcInfoASCII
+
+//########### TypeMapping ###########
+[TypeMapping]
+// Format:
+// DatenTyp-Klasse                                              Default-Factory-Klasse                                        [Im/Export-Klassen ...] 
+//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+edu.bonn.xulu.data.DynamicXuluObject                       edu.bonn.xulu.data.DynamicXuluObject$DefaultFactory                edu.bonn.xulu.plugin.io.misc.DynamicXuluObjectFactory_BasicStructure
+edu.bonn.xulu.plugin.data.grid.SingleGrid                  edu.bonn.xulu.plugin.io.grid.lateloading.SingleGridFactory               edu.bonn.xulu.plugin.io.grid.lateloading.SingleGridFactory_ArcInfoAsciiGrid
+edu.bonn.xulu.plugin.data.grid.GridList                    edu.bonn.xulu.plugin.io.grid.lateloading.GridListFactory                 edu.bonn.xulu.plugin.io.grid.lateloading.GridListFactory_ArcInfoAsciiGrid
+edu.bonn.xulu.plugin.data.grid.MultiGrid                   edu.bonn.xulu.plugin.io.grid.lateloading.MultiGridFactory                edu.bonn.xulu.plugin.io.grid.lateloading.MultiGridFactory_ArcInfoAsciiGrid
+edu.bonn.xulu.plugin.data.feature.SingleFeatureCollection  edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory  edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory_ShapeFile
+
+//########### Visualisierungstools ###########
+[Visualisation]
+edu.bonn.xulu.plugin.vis.GTVisualisationTool
+edu.bonn.xulu.plugin.vis.GTEditorTool
+edu.bonn.xulu.plugin.vis.JFreeChartVisualisationTool
+
+//########### Modellklassen ###########
+[Model]
+edu.bonn.xulu.plugin.model.clue.ClueModel
+//edu.bonn.xulu.plugin.model.test.TestModel
+//edu.bonn.xulu.plugin.model.ca.agric.ImpetusCellularAutomaton
+//edu.bonn.xulu.plugin.model.ca.fire.ImpetusFireCA
+//edu.bonn.xulu.plugin.model.ca.reservoir.SmallReservoirModel
+
+//########### Skript-Interpreter ###########
+[Script]
+edu.bonn.xulu.plugin.appl.DataScriptInterpreter_Basic Datenpool-Skript
+edu.bonn.xulu.plugin.appl.ModelResourceMappingScriptInterpreter_Basic Modell-Daten-Zuordnung
+
+//########### Plugins ###########
+[Plugin]
+edu.bonn.xulu.plugin.appl.DateTimePlugin                          Aktuelle Zeit in der Titelleiste
+edu.bonn.xulu.plugin.appl.DateTimeWindowPlugin                    Aktuelle Zeit in einem Fenster
+edu.bonn.xulu.plugin.appl.GTVisualisationColorMapPlugin AUTOSTART Farbpaletten fuer GTVisualisationTool
+edu.bonn.xulu.plugin.appl.ModelTimeSnifferPlugin        AUTOSTART Modell-Laufzeiten messen und ausgeben
+edu.bonn.xulu.plugin.appl.LoggerPlugin                  AUTOSTART Logging
+edu.bonn.xulu.plugin.appl.GeoModelCodeGeneratorPlugin   AUTOSTART Code Generator
+de.skrueger.xulu.plugin.gnur.GnuRPlugin							  Gnu R Plugin
+edu.bonn.xulu.plugin.appl.RasterCalculatorPlugin        AUTOSTART Taschenrechner fuer Raster
+appl.ext.ConfigurationEditorPlugin                      AUTOSTART Konfigurationsfenster

Added: trunk/defaults/registry_arrayGrid.xif
===================================================================
--- trunk/defaults/registry_arrayGrid.xif	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/registry_arrayGrid.xif	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,74 @@
+//########### Klassen werden "fuer alles" registriert ###########
+[Global]
+
+//########### Klassen werden als Datentyp registriert ###########
+[DataType]
+edu.bonn.xulu.data.DynamicXuluObject
+edu.bonn.xulu.plugin.data.grid.SingleGrid
+ 
+ 
+//########### Klassen als Default-Factory registriert ###########
+[DefaultFactory]
+edu.bonn.xulu.data.DynamicXuluObject$DefaultFactory
+edu.bonn.xulu.plugin.io.grid.array.SingleGridFactory
+ 
+//########### Klassen als Import-Factory registriert ###########
+[ImportFactory]
+edu.bonn.xulu.plugin.io.grid.array.SingleGridFactory_ArcInfoAsciiGrid		SingleGrid aus ArcInfoASCII
+edu.bonn.xulu.plugin.io.grid.array.SingleGridFactory_GeoTiff			SingleGrid aus GeoTiff
+edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory_ShapeFile	FeatureCollection aus ShapeFile
+edu.bonn.xulu.plugin.io.misc.DynamicXuluObjectFactory_BasicStructure		Dynamisches Xulu-Objekt aus ASCII-File
+edu.bonn.xulu.plugin.io.grid.array.GridListFactory_ArcInfoAsciiGrid		GridList aus ArcausfoASCII 
+edu.bonn.xulu.plugin.io.grid.array.MultiGridFactory_ArcInfoAsciiGrid		MultiGrid aus ArcInfoASCII
+edu.bonn.xulu.plugin.io.misc.CAAreaListFactory_ShapeFile			CA-Areas aus ShapeFile
+ 
+//########### Klassen als Export-Factory registriert ###########
+[ExportFactory]
+edu.bonn.xulu.plugin.io.grid.array.SingleGridFactory_ArcInfoAsciiGrid		SingleGrid in ArcInfoASCII
+edu.bonn.xulu.plugin.io.grid.array.SingleGridFactory_GeoTiff			SingleGrid in GeoTiff
+edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory_ShapeFile	FeatureCollection in ShapeFile
+edu.bonn.xulu.plugin.io.misc.DynamicXuluObjectFactory_BasicStructure		Dynamisches Xulu-Objekt in ASCII-File
+edu.bonn.xulu.plugin.io.grid.array.GridListFactory_ArcInfoAsciiGrid		GridList in ArcInfoASCII 
+edu.bonn.xulu.plugin.io.grid.array.MultiGridFactory_ArcInfoAsciiGrid		MultiGrid in ArcInfoASCII
+
+//########### TypeMapping ###########
+[TypeMapping]
+// Format:
+// DatenTyp-Klasse                                              Default-Factory-Klasse                                        [Im/Export-Klassen ...] 
+//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+edu.bonn.xulu.data.DynamicXuluObject                       edu.bonn.xulu.data.DynamicXuluObject$DefaultFactory                edu.bonn.xulu.plugin.io.misc.DynamicXuluObjectFactory_BasicStructure
+edu.bonn.xulu.plugin.data.grid.SingleGrid                  edu.bonn.xulu.plugin.io.grid.array.SingleGridFactory               edu.bonn.xulu.plugin.io.grid.array.SingleGridFactory_ArcInfoAsciiGrid
+edu.bonn.xulu.plugin.data.grid.GridList                    edu.bonn.xulu.plugin.io.grid.array.GridListFactory                 edu.bonn.xulu.plugin.io.grid.array.GridListFactory_ArcInfoAsciiGrid
+edu.bonn.xulu.plugin.data.grid.MultiGrid                   edu.bonn.xulu.plugin.io.grid.array.MultiGridFactory                edu.bonn.xulu.plugin.io.grid.array.MultiGridFactory_ArcInfoAsciiGrid
+edu.bonn.xulu.plugin.data.feature.SingleFeatureCollection  edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory  edu.bonn.xulu.plugin.io.feature.gt.SingleFeatureCollectionFactory_ShapeFile
+
+//########### Visualisierungstools ###########
+[Visualisation]
+edu.bonn.xulu.plugin.vis.GTVisualisationTool
+edu.bonn.xulu.plugin.vis.GTEditorTool
+edu.bonn.xulu.plugin.vis.JFreeChartVisualisationTool
+
+//########### Modellklassen ###########
+[Model]
+edu.bonn.xulu.plugin.model.clue.ClueModel
+edu.bonn.xulu.plugin.model.test.TestModel
+edu.bonn.xulu.plugin.model.ca.agric.ImpetusCellularAutomaton
+edu.bonn.xulu.plugin.model.ca.fire.ImpetusFireCA
+edu.bonn.xulu.plugin.model.ca.reservoir.SmallReservoirModel
+
+//########### Skript-Interpreter ###########
+[Script]
+edu.bonn.xulu.plugin.appl.DataScriptInterpreter_Basic Datenpool-Skript
+edu.bonn.xulu.plugin.appl.ModelResourceMappingScriptInterpreter_Basic Modell-Daten-Zuordnung
+
+//########### Plugins ###########
+[Plugin]
+edu.bonn.xulu.plugin.appl.LoggerPlugin                  AUTOSTART Anzeige und Kontrolle von Log4j-Loggern
+edu.bonn.xulu.plugin.appl.DateTimePlugin                          Aktuelle Zeit in der Titelleiste
+edu.bonn.xulu.plugin.appl.DateTimeWindowPlugin                    Aktuelle Zeit in einem Fenster
+edu.bonn.xulu.plugin.appl.GTVisualisationColorMapPlugin AUTOSTART Farbpaletten fuer GTVisualisationTool
+edu.bonn.xulu.plugin.appl.ModelTimeSnifferPlugin                  Modell-Laufzeiten messen und ausgeben
+edu.bonn.xulu.plugin.appl.GeoModelCodeGeneratorPlugin   AUTOSTART SourceCode-Generator fuer Geo-Modelle
+edu.bonn.xulu.plugin.appl.RasterCalculatorPlugin        AUTOSTART Taschenrechner fuer Raster
+appl.ext.ConfigurationEditorPlugin                      AUTOSTART Konfigurationsfenster
+

Added: trunk/defaults/startXULU.bat
===================================================================
--- trunk/defaults/startXULU.bat	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/defaults/startXULU.bat	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,93 @@
+ at echo off
+setlocal
+
+set LIB_ROOT="..\xululib"
+
+rem ###################################################################
+rem #############   Xulu library paths and parameters   ###############
+rem ###################################################################
+set XULU_LIB=classes
+set XULU_MODELS_LIB=classes_models
+if "%1"=="/useXuluJar"     set XULU_LIB=%LIB_ROOT%\xulu\XuluModellingPlatform.jar
+if "%1"=="/useXuluJar"     set XULU_MODELS_LIB=%LIB_ROOT%\xulu\XuluModellingPlatformModels.jar
+if "%1"=="/useXuluClasses" set XULU_LIB=classes
+if "%1"=="/useXuluClasses" set XULU_MODELS_LIB=classes_models
+
+set XULU_REGISTRY=registry_arrayGrid.xif
+set XULU_LANGUAGE=de
+set XULU_WORK_DIR=C:\
+set XULU_START_SCRIPTS=
+set XULU_RESOURCE=resource
+
+rem ####################################################
+rem #############   External libraries   ###############
+rem ####################################################
+
+rem ##### Where to find "Java Advanced Imaging" (and ImageIO) #####
+set JAI_ROOT=%LIB_ROOT%\jai-1_1_3\lib
+
+rem ##### Where to find "GeoTools" #####
+set GT_ROOT=%LIB_ROOT%\gt2-2.4.4
+
+rem ##### Where to find gt2-arcgrid-2.1.x.jar (from SpearfishDemo) #####
+set GT_ARCGRID_ROOT=%LIB_ROOT%\geotoolsArcGrid
+
+rem ##### Where to find "Adagios" #####
+set ADAGIOS_ROOT=%LIB_ROOT%\ADaGIoS
+
+rem ##### Where to find "Log4j" #####
+set LOG4J_ROOT=%LIB_ROOT%\log4j-1.2.14
+
+rem ##### Where to find "JINI" #####
+set JINI_ROOT=%LIB_ROOT%\jini
+
+rem ##### Where to find "R" #####
+set R_ROOT=%LIB_ROOT%\JavaRInterface
+
+rem ##### Where to find "jFreeChart" #####
+set JFREECHART_ROOT=%LIB_ROOT%\jFreeChart
+
+rem ##### combine the external libs #####
+set JAI_LIB=%JAI_ROOT%\*
+set GT_LIB=%GT_ROOT%\*
+set GT_LIB=%GT_LIB%;%GT_ARCGRID_ROOT%\gt2-arcgrid-2.3.0-M0.jar;%GT_ARCGRID_ROOT%\junit-4.4.jar
+set ADAGIOS_LIB=%ADAGIOS_ROOT%\AdagiosJavaLib.jar
+set JINI_LIB=%JINI_ROOT%\lib\*;%JINI_ROOT%\lib-dl\*;%JINI_ROOT%\lib-ext\*
+rem set JINI_LIB=%JINI_ROOT%\lib\jsk-platform.jar;%JINI_ROOT%\lib\tools.jar
+set LOG4J_LIB=%LOG4J_ROOT%\log4j-1.2.14.jar
+set R_LIB=%R_ROOT%\JRI.jar;%R_ROOT%\libjri.so;%R_ROOT%\libR.so
+set JFREECHART_LIB=%JFREECHART_ROOT%\jfreechart-1.0.6.jar;%JFREECHART_ROOT%\jcommon-1.0.10.jar
+
+set LIB_ALL=%XULU_LIB%;%JAI_LIB%;%GT_LIB%;%ADAGIOS_LIB%;%LOG4J_LIB%;%JINI_LIB%;%R_LIB%;%JFREECHART_LIB%
+
+rem ##### combine the native libs #####
+rem set JAI_NATIVE=%JAI_ROOT%\native_win\mlib_jai.dll;%JAI_ROOT%\native_win\mlib_jai_mmx.dll;%JAI_ROOT%\native_win\mlib_jai_util.dll
+set JAI_NATIVE=%JAI_ROOT%\native_win
+
+set LIB_NATIVE=%JAI_NATIVE%
+
+
+rem ##### combine Xulu starting parameters #####
+set XULU_PARAMS=
+if not "%XULU_LANGUAGE%"==""        set XULU_PARAMS=%XULU_PARAMS% -l %XULU_LANGUAGE%
+if not "%XULU_REGISTRY%"==""        set XULU_PARAMS=%XULU_PARAMS% -rf %XULU_REGISTRY%
+if not "%XULU_MODELS_LIB%"==""      set XULU_PARAMS=%XULU_PARAMS% -d %XULU_MODELS_LIB%
+if not "%XULU_WORK_DIR%"==""        set XULU_PARAMS=%XULU_PARAMS% -w "%XULU_WORK_DIR%"
+if not "%XULU_START_SCRIPTS%"==""   set XULU_PARAMS=%XULU_PARAMS% -s "%XULU_START_SCRIPTS%"
+
+
+rem ##### determine java interpreter #####
+set JAVA_PRG=start /B javaw
+rem set JAVA_PRG=java
+rem ##### for command line help, use java instead of javaw #####
+if "%1"=="/?"     set JAVA_PRG=java
+if "%1"=="?"      set JAVA_PRG=java
+if "%1"=="-?"     set JAVA_PRG=java
+if "%1"=="--help" set JAVA_PRG=java
+if "%1"=="-h"     set JAVA_PRG=java
+
+
+rem ##### start Xulu #####
+%JAVA_PRG% -Xms300M -Xmx1000M -version:1.6 -cp %XULU_RESOURCE%;%LIB_ALL% -Djava.library.path=%LIB_NATIVE% -splash:resource\icons\xulu_start.png edu.bonn.xulu.XuluModellingPlatform %XULU_PARAMS% %*
+
+endlocal

Added: trunk/lib/JavaRInterface/JRI.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/JavaRInterface/JRI.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/jai-1_1_3/COPYRIGHT-jai.txt
===================================================================
--- trunk/lib/jai-1_1_3/COPYRIGHT-jai.txt	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/lib/jai-1_1_3/COPYRIGHT-jai.txt	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,34 @@
+Copyright © 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+California 95054, U.S.A. All rights reserved. U.S. Government Rights -
+Commercial software. Government users are subject to the Sun Microsystems,
+Inc. standard license agreement and applicable provisions of the FAR and its 
+supplements. Use is subject to license terms. This distribution may include
+materials developed by third parties. Sun, Sun Microsystems, the Sun logo
+and Java are trademarks or registered trademarks of Sun Microsystems, Inc.
+in the U.S. and other countries. This product is covered and controlled by
+U.S.Export Control laws and may be subject to the export or import laws in
+other countries. Nuclear, missile, chemical biological weapons or nuclear
+maritime end uses or end users, whether direct or indirect, are strictly
+prohibited. Export or reexport to countries subject to U.S. embargo or to
+entities identified on U.S. export exclusion lists, including, but not
+limited to, the denied persons and specially designated nationals lists is
+strictly prohibited.
+
+Copyright © 2006 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+California 95054, Etats-Unis. Tous droits réservés.L'utilisation est soumise
+aux termes de la Licence.Cette distribution peut comprendre des composants
+développés par des tierces parties.Sun, Sun Microsystems, le logo Sun et
+Java sont des marques de fabrique ou des marques déposées de Sun Microsystems,
+Inc. aux Etats-Unis et dans d'autres pays.Ce produit est soumis à la
+législation américaine en matière de contrôle des exportations et peut être
+soumis à la règlementation en vigueur dans d'autres pays dans le domaine des
+exportations et importations. Les utilisations, ou utilisateurs finaux, pour
+des armes nucléaires,des missiles, des armes biologiques et chimiques ou du
+nucléaire maritime, directement ou indirectement, sont strictement interdites.
+Les exportations ou réexportations vers les pays sous embargo américain, ou
+vers des entités figurant sur les listes d'exclusion d'exportation 
+américaines, y compris, mais de manière non exhaustive, la liste de personnes
+qui font objet d'un ordre de ne pas participer, d'une façon directe ou
+indirecte, aux exportations des produits ou des services qui sont régis  par
+la législation américaine en matière de contrôle des exportations et la liste
+de ressortissants spécifiquement désignés, sont rigoureusement interdites.

Added: trunk/lib/jai-1_1_3/DISTRIBUTIONREADME-jai.txt
===================================================================
--- trunk/lib/jai-1_1_3/DISTRIBUTIONREADME-jai.txt	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/lib/jai-1_1_3/DISTRIBUTIONREADME-jai.txt	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,27 @@
+DistributionREADME
+
+DISTRIBUTION BY DEVELOPERS.  Subject to the terms and conditions of the Software License Agreement and the obligations, restrictions, and exceptions set forth below, You may reproduce and distribute the portions of Software identified below ("each a Redistributable"), provided that you comply with the following (note that You may be entitled to reproduce and distribute other portions of the Software not defined here as a Redistributable under certain other licenses as described in the THIRDPARTYLICENSEREADME):
+
+(a) You distribute the Redistributable complete and unmodified and only bundled as part of Your applets and applications ("Programs"), 
+
+(b) You do not distribute additional software intended to replace any
+component(s) of the Redistributable,
+
+(c) You do not remove or alter any proprietary legends or notices contained in or on the Redistributable.
+ 
+(d) You only distribute the Redistributable subject to a license agreement that protects Sun's interests consistent with the terms contained in the Software License Agreement, and
+
+(e) You agree to defend and indemnify Sun and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses  (including attorneys' fees) incurred in connection with any claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Redistributable.  
+
+The following files are each a Redistributable:
+
+The following Redistributables may be redistributed only as a whole
+
+JAVA Advanced Imaging API, Version 1.1.3
+
+
+The following Redistributables may be redistributed separately
+
+JAI Codecs - jai_codec.jar
+
+JAI Java Implementation - jai_core.jar and jai_codec.jar (required to be redistributed together)

Added: trunk/lib/jai-1_1_3/LICENSE-jai.txt
===================================================================
--- trunk/lib/jai-1_1_3/LICENSE-jai.txt	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/lib/jai-1_1_3/LICENSE-jai.txt	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,55 @@
+Sun Microsystems, Inc.
+Binary Code License Agreement
+
+JAVA ADVANCED IMAGING API, VERSION 1.1.3
+
+READ THE TERMS OF THIS AGREEMENT AND ANY PROVIDED SUPPLEMENTAL LICENSE TERMS (COLLECTIVELY "AGREEMENT") CAREFULLY BEFORE OPENING THE SOFTWARE MEDIA PACKAGE.  BY OPENING THE SOFTWARE MEDIA PACKAGE, YOU AGREE TO THE TERMS OF THIS AGREEMENT.  IF YOU ARE ACCESSING THE SOFTWARE ELECTRONICALLY, INDICATE YOUR ACCEPTANCE OF THESE TERMS BY SELECTING THE "ACCEPT" BUTTON AT THE END OF THIS AGREEMENT.  IF YOU DO NOT AGREE TO ALL THESE TERMS, PROMPTLY RETURN THE UNUSED SOFTWARE TO YOUR PLACE OF PURCHASE FOR A REFUND OR, IF THE SOFTWARE IS ACCESSED ELECTRONICALLY, SELECT THE "DECLINE" BUTTON AT THE END OF THIS AGREEMENT. 
+
+1.  LICENSE TO USE.  Sun grants you a non-exclusive and non-transferable license for the internal use only of the accompanying software and documentation and any error corrections provided by Sun (collectively "Software"), by the number of users and the class of computer hardware for which the corresponding fee has been paid. 
+
+2.  RESTRICTIONS.  Software is confidential and copyrighted. Title to Software and all associated intellectual property rights is retained by Sun and/or its licensors.  Except as specifically authorized in any Supplemental License Terms, you may not make copies of Software, other than a single copy of Software for archival purposes.  Unless enforcement is prohibited by applicable law, you may not modify, decompile, or reverse engineer Software.  Licensee acknowledges that Software is not designed or intended for use in the design, construction, operation or maintenance of any nuclear facility. Sun Microsystems, Inc. disclaims any express or implied warranty of fitness for such uses.   No right, title or interest in or to any trademark, service mark, logo or trade name of Sun or its licensors is granted under this Agreement. 
+
+3.  LIMITED WARRANTY.  Sun warrants to you that for a period of ninety (90) days from the date of purchase, as evidenced by a copy of the receipt, the media on which Software is furnished (if any) will be free of defects in materials and workmanship under normal use.  Except for the foregoing, Software is provided "AS IS".  Your exclusive remedy and Sun's entire liability under this limited warranty will be at Sun's option to replace Software media or refund the fee paid for Software. 
+
+4.  DISCLAIMER OF WARRANTY.  UNLESS SPECIFIED IN THIS AGREEMENT, ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT THESE DISCLAIMERS ARE HELD TO BE LEGALLY INVALID. 
+
+5.  LIMITATION OF LIABILITY.  TO THE EXTENT NOT PROHIBITED BY LAW, IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF OR RELATED TO THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.  In no event will Sun's liability to you, whether in contract, tort (including negligence), or otherwise, exceed the amount paid by you for Software under this Agreement.  The foregoing limitations will apply even if the above stated warranty fails of its essential purpose. 
+
+6.  Termination.  This Agreement is effective until terminated.  You may terminate this Agreement at any time by destroying all copies of Software.  This Agreement will terminate immediately without notice from Sun if you fail to comply with any provision of this Agreement.  Upon Termination, you must destroy all copies of Software. 
+
+7.  Export Regulations. All Software and technical data delivered under this Agreement are subject to US export control laws and may be subject to export or import regulations in other countries.  You agree to comply strictly with all such laws and regulations and acknowledge that you have the responsibility to obtain such licenses to export, re-export, or import as may be required after delivery to you. 
+
+8.  U.S. Government Restricted Rights.  If Software is being acquired by or on behalf of the U.S. Government or by a U.S. Government prime contractor or subcontractor (at any tier), then the Government's rights in Software and accompanying documentation will be only as set forth in this Agreement; this is in accordance with 48 CFR 227.7201 through 227.7202-4 (for Department of Defense (DOD) acquisitions) and with 48 CFR 2.101 and 12.212 (for non-DOD acquisitions). 
+
+9.  Governing Law.  Any action related to this Agreement will be governed by California law and controlling U.S. federal law.  No choice of law rules of any jurisdiction will apply. 
+
+10. Severability. If any provision of this Agreement is held to be unenforceable, this Agreement will remain in effect with the provision omitted, unless omission would frustrate the intent of the parties, in which case this Agreement will immediately terminate. 
+
+11. Integration.  This Agreement is the entire agreement between you and Sun relating to its subject matter.  It supersedes all prior or contemporaneous oral or written communications, proposals, representations and warranties and prevails over any conflicting or additional terms of any quote, order, acknowledgment, or other communication between the parties relating to its subject matter during the term of this Agreement.  No modification of this Agreement will be binding, unless in writing and signed by an authorized representative of each party. 
+
+ 
+                    JAVA ADVANCED IMAGING, VERSION 1.1.3
+                         
+                         SUPPLEMENTAL LICENSE TERMS
+
+These supplemental license terms ("Supplemental Terms") add to or modify the terms of the Binary Code License Agreement (collectively, the "Agreement"). Capitalized terms not defined in these Supplemental Terms shall have the same meanings ascribed to them in the Agreement. These Supplemental Terms shall supersede any inconsistent or conflicting terms in the Agreement, or in any license contained within the Software. 
+
+1. Software Internal Use and Development License Grant.  Subject to the terms and conditions of this Agreement, including, but not limited to Section 3 (Java Technology Restrictions) of these Supplemental Terms, Sun grants you a non-exclusive, non-transferable, limited license to reproduce internally and use internally the binary form of the Software, complete and unmodified, for the sole purpose of designing, developing and testing your Java applets and applications ("Programs"). 
+
+2. License to Distribute Software.  In addition to the license granted in Section 1 (Software Internal Use and Development License Grant) of these Supplemental Terms, subject to the terms and conditions of this Agreement, including but not limited to, Section 3 (Java Technology Restrictions) of these Supplemental Terms, Sun grants you a non-exclusive, non-transferable, limited license to reproduce and distribute the Software in binary code form only, provided that you (i) distribute the Software complete and unmodified and only bundled as part of your Programs, (ii) do not distribute additional software intended to replace any component(s) of the Software, (iii) do not remove or alter any proprietary legends or notices contained in the Software, (iv) only distribute the Software subject to a license agreement that protects Sun's interests consistent with the terms contained in this Agreement, and (v) agree to defend and indemnify Sun and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection with any claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Software. 
+
+3. Java Technology Restrictions. You may not modify the Java Platform Interface ("JPI", identified as classes contained within the "java" package or any subpackages of the "java" package), by creating additional classes within the JPI or otherwise causing the addition to or modification of the classes in the JPI.  In the event that you create an additional class and associated API(s) which (i) extends the functionality of the Java platform, and (ii) is exposed to third party software developers for the purpose of developing additional software which invokes such additional API, you must promptly publish broadly an accurate specification for such API for free use by all developers.  You may not create, or authorize your licensees to create additional classes, interfaces, or subpackages that are in any way identified as "java", "javax", "sun" or similar convention as specified by Sun in any naming convention designation. 
+
+4.  Java Runtime Availability.  Refer to the appropriate version of the Java Runtime Environment binary code license (currently located at http://www.java.sun.com/jdk/index.html) for the availability of runtime code which may be distributed with Java applets and applications.
+
+5. Trademarks and Logos. You acknowledge and agree as between you and Sun that Sun owns the SUN, SOLARIS, JAVA, JINI, FORTE, and iPLANET trademarks and all SUN, SOLARIS, JAVA, JINI, FORTE, and iPLANET-related trademarks, service marks, logos and other brand designations ("Sun Marks"), and you agree to comply with the Sun Trademark and Logo Usage Requirements currently located at http://www.sun.com/policies/trademarks. Any use you make of the Sun Marks inures to Sun's benefit. 
+
+6. Source Code. Software may contain source code that is provided solely for reference purposes pursuant to the terms of this Agreement.  Source code may not be redistributed unless expressly provided for in this Agreement. 
+
+7. Termination for Infringement.  Either party may terminate this Agreement immediately should any Software become, or in either party's opinion be likely to become, the subject of a claim of infringement of any intellectual property right.
+
+8. Third Party Code. Additional copyright notices and license terms applicable to portions of the Software are set forth in the THIRDPARTYLICENSEREADME. In addition to any terms and conditions of any third party open source/freeware license identified in the THIRDPARTYLICENSEREADME, the disclaimer of warranty and limitation of liability provisions in paragraphs 5 and 6 of the Binary Code License Agreement shall apply to all Software in this distribution.
+
+For inquiries please contact: Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, California 95054, U.S.A
+
+(LFI#143342/Form ID#011801)

Added: trunk/lib/jai-1_1_3/THIRDPARTYLICENSEREADME-jai.txt
===================================================================
--- trunk/lib/jai-1_1_3/THIRDPARTYLICENSEREADME-jai.txt	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/lib/jai-1_1_3/THIRDPARTYLICENSEREADME-jai.txt	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,54 @@
+DO NOT TRANSLATE OR LOCALIZE.
+
+%% The following software may be included in this product:  NeuQuant Color Quantization.  Use of any of this software is governed by the terms of the license below: 
+
+* NeuQuant Neural-Net Quantization Algorithm
+ * ------------------------------------------
+ *
+ * Copyright (c) 1994 Anthony Dekker
+ *
+ * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.
+ * See "Kohonen neural networks for optimal colour quantization"
+ * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367.
+ * for a discussion of the algorithm.
+ * See also  http://www.acm.org/~dekker/NEUQUANT.HTML
+ *
+ * Any party obtaining a copy of these files from the author, directly or
+ * indirectly, is granted, free of charge, a full and unrestricted irrevocable,
+ * world-wide, paid up, royalty-free, nonexclusive right and license to deal
+ * in this software and documentation files (the "Software"), including without
+ * limitation the rights to use, copy, modify, merge, publish, distribute,
+sublicense,
+ * and/or sell copies of the Software, and to permit persons who receive
+ * copies from any such party to do so, with the only requirement being
+ * that this copyright notice remain intact.
+ */
+
+%% The following software may be included in this product: Oct-Tree Color Quantization.  Use of any of this software is governed by the terms of the license below: 
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%  Permission is hereby granted, free of charge, to any person obtaining a    %
+%  copy of this software and associated documentation files ("ImageMagick"),  %
+%  to deal in ImageMagick without restriction, including without limitation   %
+%  the rights to use, copy, modify, merge, publish, distribute, sublicense,   %
+%  and/or sell copies of ImageMagick, and to permit persons to whom the       %
+%  ImageMagick is furnished to do so, subject to the following conditions:    %
+%                                                                             %
+%  The above copyright notice and this permission notice shall be included in %
+%  all copies or substantial portions of ImageMagick.                         %
+%                                                                             %
+%  The software is provided "as is", without warranty of any kind, express or %
+%  implied, including but not limited to the warranties of merchantability,   %
+%  fitness for a particular purpose and noninfringement.  In no event shall   %
+%  E. I. du Pont de Nemours and Company be liable for any claim, damages or   %
+%  other liability, whether in an action of contract, tort or otherwise,      %
+%  arising from, out of or in connection with ImageMagick or the use or other %
+%  dealings in ImageMagick.                                                   %
+%                                                                             %
+%  Except as contained in this notice, the name of the E. I. du Pont de       %
+%  Nemours and Company shall not be used in advertising or otherwise to       %
+%  promote the sale, use or other dealings in ImageMagick without prior       %
+%  written authorization from the E. I. du Pont de Nemours and Company.       %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+

Added: trunk/lib/jai-1_1_3/UNINSTALL-jai
===================================================================
--- trunk/lib/jai-1_1_3/UNINSTALL-jai	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/lib/jai-1_1_3/UNINSTALL-jai	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,19 @@
+#!/bin/sh
+# @(#)UNINSTALL-jai	3.1 06/05/25 18:35:35
+# usage: UNINSTALL-jai
+
+echo "Uninstalling Java Advanced Imaging"
+
+rm -f *jai.txt
+rm -f lib/jai_core.jar
+rm -f lib/jai_codec.jar
+rm -f lib/mlibwrapper_jai.jar
+rm -f lib/libmlib_jai.so
+if [ \( "`uname`" = "SunOS" \) -a \( "`uname -p`" = "sparc" \) ]; then
+    rm -f lib/libmlib_jai_vis.so
+    rm -f lib/libmlib_jai_vis2.so
+fi
+rmdir lib
+rm -f UNINSTALL-jai
+
+echo "Done"

Added: trunk/lib/jai-1_1_3/lib/clibwrapper_jiio.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jai-1_1_3/lib/clibwrapper_jiio.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/jai-1_1_3/lib/jai_codec.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jai-1_1_3/lib/jai_codec.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/jai-1_1_3/lib/jai_core.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jai-1_1_3/lib/jai_core.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/jai-1_1_3/lib/jai_imageio.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jai-1_1_3/lib/jai_imageio.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/jai-1_1_3/lib/mlibwrapper_jai.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jai-1_1_3/lib/mlibwrapper_jai.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/jai-1_1_3/lib/native_win/mlib_jai.dll
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jai-1_1_3/lib/native_win/mlib_jai.dll
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/jai-1_1_3/lib/native_win/mlib_jai_mmx.dll
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jai-1_1_3/lib/native_win/mlib_jai_mmx.dll
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/jai-1_1_3/lib/native_win/mlib_jai_util.dll
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jai-1_1_3/lib/native_win/mlib_jai_util.dll
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/jini/lib/tools.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jini/lib/tools.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/schmitzm/schmitzm.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/schmitzm/schmitzm.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/lib/xulu/XuluModellingPlatform.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/xulu/XuluModellingPlatform.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/readme.txt
===================================================================
--- trunk/readme.txt	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/readme.txt	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,166 @@
+TODO:
+- startXulu.bat erweitern:
+   - /useXuluClasses auf SCHMITZM erweitern
+- SCHMITZM in Xulu\lib aufnehmen
+- How to start XULU from Eclipse
+- How to develop XULU
+
+==============================================================
+=== XULU README (2009-02-24, Martin Schmitz)               ===
+===                                                        ===
+=== http://wald.intevation.org/projects/xulu/              ===
+=== http://wald.intevation.org/projects/schmitzm/          ===
+==============================================================
+This file contains some informations ...
+
+(1) about the XULU modelling platform
+(2) how to proceed after the first SVN checkout
+(3) about the folder structur of XULU
+(4) how to start XULU
+    a) Requirements
+    b) Start XULU from command line
+    c) Start XULU from Eclipse
+(5) how to develop XULU
+
+
+
+-----------------------------------------------------------
+(1) General informations about XULU
+-----------------------------------------------------------
+XULU (eXtendable Unified Land Use Modelling Platform) is a stand-alone
+Java software which was designed as a part of my diploma thesis (Martin Schmitz,
+2005, Institite of computer science, University of Bonn/Germany).
+The goal was the create a generic framework, which provides general functionalities
+needed for (simulation) modelling, without any relationship to a concrete
+model context:
+- data maintenance
+- data types
+- data import/export
+- data visualisation
+- GUI
+
+With these components implemented once (--> XULU) there is no further need to
+take into account during implementation of any model. The model designer and
+programmer can concentrate on implementing themodel algorithm.
+The interfaces to the upper mentioned components are realised as plugins,
+so the field of application is not static.
+Because the of the close cooperation with the ZFL (Zentrum für Fernerkundung der
+Landoberfläche) and IMPETUS (http://www.impetus.de) the most plugins which
+are currently implemented are for land use modelling:
+- maintain raster and vector data (based on the Geotools Java library)
+- layer based geo visualisation (based on the Geotools Java library)
+- raster based models
+
+But generally - with implementing appropriate plugins - XULU can also be used for
+complete other application fields
+
+
+-----------------------------------------------------------
+(2) Initialize XULU after the first SVN checkout
+-----------------------------------------------------------
+The XULU folders contain multiple files to configure defaults for
+the XULU main application as well as for XULU plugins.
+Because the "normal" user defined changes on these files should not be
+updated in SVN, these configuration files are initially located in the
+"defaults" folder, instead of their "correct" position.
+
+Therefore after the first SVN checkout you have to call the
+
+                            InitXulu.bat
+
+once to copy the configuration files from the "defaults" folder to their
+expected locations. After that you can make changes on all config files
+without any unintended effect on the whole XULU community.
+
+The default behavior of "InitXulu.bat" is not to overwrite files if they
+already exist. In case of trouble (e.g. deleted or damaged config files)
+you can call
+                        InitXulu.bat /reset
+                    or  InitXulu.bat /init   (no overwrite confirmation!)
+
+to overwrite all configuration files with their defaults.
+
+NOTE: PLEASE DO NOT UPDATE (AND COMMIT) CHANGES ON FILES IN THE
+      "DEFAULT" FOLDER!!
+
+
+-----------------------------------------------------------
+(3) The folder structure of XULU
+-----------------------------------------------------------
+main folder: The main folder contains some configuration files for
+             the XULU main application as well as the startXulu.bat
+             which can be used to start XULU from out of an
+             development environment (like Eclipse):
+             - InitXulu.bat: initializes the folder structure after
+                             the first SVN checkout (see (2))
+             - DefaultProperties: Defaults for XULU properties; after
+                                  the first XULU start a new file
+                                  "XuluProperties" is created with the
+                                  user defined properties
+             - registry.xif: contains the plugins used in XULU
+             - readme.txt: this file :-)
+
+defaults: Contains default configuration files for the XULU main
+          application and plugins. By calling "InitXulu.bat" (see (2))
+          these files are copied to the expected locations.
+          NOTE: PLEASE DO NOT UPDATE (AND COMMIT) CHANGES ON FILES IN
+	        THIS FOLDER!!
+
+classes: Contains the compliled java classes of the XULU application
+         and plugins.
+
+doc:     Contains the JavaDoc for Xulu. Also the target folder of
+         "makeDoc.bat"
+
+lib:     Contains all the external libraries required to run/compile XULU.
+         All JARs in this folder must be integrated in the Java classpath.
+
+plugin:  Contains configuration files for XULU plugins.
+
+src:     Contains the java source code of the XULU application and plugins.
+
+Temp:    Usually empty. Needed for temporary files.
+
+
+-----------------------------------------------------------
+(4) How to start XULU
+-----------------------------------------------------------
+
+a) Requirements
+---------------
+Besides the external libraries in "lib" folder, it is required that
+the following components are installed on system:
+- JRE 1.6
+- JAI 1.1.3
+
+b) Start XULU from command line
+-------------------------------
+To start XULU from command line there are 2 main variants:
+
+ 1) "startXulu.bat /useXuluJar"     (Default)
+    uses the XuluModellingPlatform.jar and SCHMITZM.jar from the
+    "lib" folder to run XULU. This option is recommended, if you
+    only want to "use" XULU and not to develop.
+
+ 2) "startXulu.bat /useXuluClasses"
+    uses the "classes" folder to run XULU. Use this option, if you
+    want to take your own changes (or plugin extension) take effekt.
+    This option requires that
+      - XULU is previously compiled to "classes" folder
+      - SCHMITZM is previously compiled to
+
+c) Start XULU from Eclipse
+--------------------------
+t.b.c.
+
+
+-----------------------------------------------------------
+(4) How to develop XULU
+-----------------------------------------------------------
+t.b.c.
+
+
+===========================================================
+http://wald.intevation.org/projects/xulu/
+http://wald.intevation.org/projects/schmitzm/
+===========================================================
\ No newline at end of file

Added: trunk/resource/icons/xulu_icon.png
===================================================================
(Binary files differ)


Property changes on: trunk/resource/icons/xulu_icon.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/icons/xulu_info.png
===================================================================
(Binary files differ)


Property changes on: trunk/resource/icons/xulu_info.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/icons/xulu_start.png
===================================================================
(Binary files differ)


Property changes on: trunk/resource/icons/xulu_start.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/locales/StandardBundleExtension.properties
===================================================================
--- trunk/resource/locales/StandardBundleExtension.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/StandardBundleExtension.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,53 @@
+# ----------------------------------------------------------------------------------
+#  LANGUAGE: English                               
+#
+#  Xulu extention of standard the bundles
+#
+#      schmitzm-swing
+#           bundle: schmitzm.swing.resource.locales.SwingResourceBundle
+#           prefix: schmitzm.swing
+#
+#      schmitzm-jFreeChart
+#           bundle: schmitzm.jfree.resource.locales.JFreeResourceBundle
+#           prefix: schmitzm.jfree
+#
+#      schmitzm-geotools:  
+#           bundle: schmitzm.geotools.gui.resource.locales.GTResourceBundle
+#           prefix: schmitzm.gt
+# 
+#  Besides extending a resource bundle <bundle> in this file, it is also necessary
+#  to programm the extention of the standard bundle in XuluModellingPlatform:
+#
+#    static {
+#        <extendedResourceBundle>.resetResourceBundle(
+#                                     "locales.StandardBundleExtention",
+#                                     <bundle prefix>
+#        )
+#        ...
+#    }
+#
+# ----------------------------------------------------------------------------------
+
+
+# -------------------------------------------------------------------------
+# Extention of bundle schmitzm.swing.resource.locales.SwingResourceBundle
+# Prefix: schmitzm.swing
+# -------------------------------------------------------------------------
+
+
+
+# ------------------------------------------------------------------------
+# Extention of bundle schmitzm.jfree.resource.locales.JFreeResourceBundle
+# Prefix: schmitzm.jfree
+# ------------------------------------------------------------------------
+
+
+
+
+# ----------------------------------------------------------------------------
+# Extention of bundle schmitzm.geotools.gui.resource.locales.GTResourceBundle
+# Prefix: schmitzm.gt
+# ----------------------------------------------------------------------------
+
+
+

Added: trunk/resource/locales/XuluMainAppl.properties
===================================================================
--- trunk/resource/locales/XuluMainAppl.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluMainAppl.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,88 @@
+# ----------------------------------------------------------------------
+# ------ Default Translations (english) for Xulu main application ------
+# ----------------------------------------------------------------------
+
+XuluTitle=XULU - eXtendable Unified Land Use Modelling Platform
+Menu_File=File
+Menu_File_Exit=Exit
+Menu_Model=Model
+Menu_Model_New=New
+Menu_Model_Reload=Reload model class
+Menu_View=View
+Menu_View_Arrange=Arrange Windows
+Menu_View_AutoArrange=Auto-Arrange
+Menu_Scripts=Scripts
+Menu_RecentScripts=Recent scripts
+Menu_Help=Help
+Menu_Help_Info=About...
+Menu_Advanced_Preferences=Xulu Preferences
+Menu_Advanced_Languages=Xulu Language-Packs
+Menu_Advanced=Advanced
+Menu_DataPool=Datapool
+Menu_DataPool_Del=Delete
+Menu_DataPool_New=New
+Menu_DataPool_New_CopyStr=Copy structure
+Menu_DataPool_Import=Import
+Menu_DataPool_RecentImport=Recent imports
+Menu_DataPool_Export=Export
+Menu_DataPool_RecentExport=Recent exports
+Menu_DataPool_Display=Display
+Menu_DataPool_Display_Actualise=Actualise
+Menu_DataPool_Display_New=New
+Comp_DataPool=Xulu Datapool
+Comp_Registry=Xulu Registry
+Comp_Models=Loaded Models
+Comp_EventManager=Event Manager
+Comp_PluginManager=Plugins
+Comp_Log=Status Messages
+Comp_Visualisation=Visualisation Tools
+Model=Model
+DynModel=Dynamic model
+Access=access
+ReadAccess=read access
+WriteAccess=write access
+ScriptProgressMess=Script is working...
+ImportProgressMess=Import in progress...
+ExportProgressMess=Export in progress...
+ModelChoiceMess=Please choose a model...
+DefaultModelName=New model
+ModelClassChoiceMess=Please choose a model class...
+DynModelChoiceMess=Please choose a dynamic model from datapool...
+ModelReloadSuccessMess=Model class reloaded successfully...
+Name=Name
+Type=Type
+Object=Object
+Event=Event
+Handler=Handler
+EventObject=Object to listen for
+VisualisationUpdate=Update visualisation
+UpdateObject=Object to visualise
+VisTool=Visualisationtool
+FileExport=Export to file
+ExportSource=Export object
+ExportFactory=Export method
+ExportDest=Export destination
+new=neu
+StartMess=Starting Xulu
+LangFrame.Title=Xulu language packs
+LangFrame.Bundle=Language bundle
+LangFrame.ExtentionOf=Extention of...
+LangFrame.RootLang=Root language
+LangFrame.AdditionalLang=Additional languages
+LangFrame.NewLang=Create new language...
+LangFrame.OtherLang=<other language>
+LangFrame.Language=Language
+LangFrame.LanguageCode=Language code
+LangFrame.FinishMess=Property files successfully created...
+LangFrame.InfoText=To change the program language it is necessary to restart XULU and use the "-l <ISO-639>" command line parameter (e.g. "-l de" or "-l en"). You can also specifiy the language code in the variable XULU_LANGUAGE of the startXulu.bat. The translations are handled by property files located in /resource/locales. When creating a new language by the button below, files for the new language (with dummy translations) are created automatically. They can be modified with a common text editor.
+Model.ErrorOccured=AN ERROR OCCURED!!!
+Model.Init=Model initialised
+Model.Start=Model started
+Model.Stop=Model stopped
+Model.Dispose=Model disposed
+Model.Step.Started=Model step ${0} started
+Model.Step.Finished=Model step ${0} finished
+ModelResource.Type.Null=Resource-Type can not be NULL!
+ModelResource.Data.Null=Resource-Data can not be NULL!
+ModelResource.Cat.Unknown=Unknown resource category (${0})
+ModelResource.Data.Error=Resource '${0}': ${1} expected
\ No newline at end of file

Added: trunk/resource/locales/XuluMainAppl_de.properties
===================================================================
--- trunk/resource/locales/XuluMainAppl_de.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluMainAppl_de.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,88 @@
+# -----------------------------------------------------------
+# ------ German Translations for Xulu main application ------
+# -----------------------------------------------------------
+
+XuluTitle=XULU - eXtendable Unified Land Use Modelling Platform
+Menu_File=Datei
+Menu_File_Exit=Beenden
+Menu_Model=Modell
+Menu_Model_New=Neu
+Menu_Model_Reload=Modell-Klasse neu laden
+Menu_View=Ansicht
+Menu_View_Arrange=Fenster anordnen
+Menu_View_AutoArrange=Autom. Fenster-Anordnung
+Menu_Scripts=Skripte
+Menu_RecentScripts=Skript erneut ausführen
+Menu_Help=Hilfe
+Menu_Help_Info=Über...
+Menu_Advanced_Preferences=Xulu Einstellungen
+Menu_Advanced_Languages=Xulu Sprach-Pakete
+Menu_Advanced=Erweitert
+Menu_DataPool=Daten-Pool
+Menu_DataPool_Del=Löschen
+Menu_DataPool_New=Neu
+Menu_DataPool_New_CopyStr=Struktur kopieren
+Menu_DataPool_Import=Import
+Menu_DataPool_RecentImport=Erneut importieren
+Menu_DataPool_Export=Export
+Menu_DataPool_RecentExport=Erneut exportieren
+Menu_DataPool_Display=Visualisieren
+Menu_DataPool_Display_Actualise=Aktualisieren
+Menu_DataPool_Display_New=Neu
+Comp_DataPool=Xulu-Datenpool
+Comp_Registry=Xulu-Registry
+Comp_Models=Geladene Modelle
+Comp_EventManager=Ereignis-Manager
+Comp_PluginManager=Plugins
+Comp_Log=Status-Ausgaben
+Comp_Visualisation=Visualisierungstools
+Model=Modell
+DynModel=Dynamisches Modell
+Access=Zugriffsrecht
+ReadAccess=Leserecht
+WriteAccess=Schreibrecht
+ScriptProgressMess=Skript wird verarbeitet...
+ImportProgressMess=Import wird durchgeführt...
+ExportProgressMess=Export wird durchgeführt...
+ModelChoiceMess=Modell auswählen...
+DefaultModelName=Neues Modell
+ModelClassChoiceMess=Modell-Klasse auswählen...
+DynModelChoiceMess=Dynamisches Modell aus Datenpool auswählen...
+ModelReloadSuccessMess=Modell-Klasse erfolgreich aktualisiert...
+Name=Name
+Type=Typ
+Object=Objekt
+Event=Ereignis
+Handler=Handler
+EventObject=Zu beobachtendes Objekt
+VisualisationUpdate=Visualisierung aktualisieren
+UpdateObject=Darzustellendes Objekt
+VisTool=Visualisierungstool
+FileExport=Datei-Export
+ExportSource=Zu exportierendes Objekt
+ExportFactory=Export-Methode
+ExportDest=Export-Ziel
+new=neu
+StartMess=Starte Xulu
+LangFrame.Title=Xulu Sprach-Pakete
+LangFrame.Bundle=Sprach Paket
+LangFrame.ExtentionOf=Erweiterung von...
+LangFrame.RootLang=Standard Sprache
+LangFrame.AdditionalLang=Weitere Sprachen
+LangFrame.NewLang=Neue Sprache anlegen...
+LangFrame.OtherLang=<andere Sprache>
+LangFrame.Language=Sprache
+LangFrame.LanguageCode=Sprachcode
+LangFrame.FinishMess=Property-Dateien erfolgreich erstellt...
+LangFrame.InfoText=Um die Sprache zu wechseln muss XULU neu gestartet werden und der Kommandozeilen-Parameter "-l <ISO-639 code>" entsprechend gesetzt werden (z.B. "-l de" oder "-l en"). Alternativ kann die Sprache auch über die Variable XULU_LANGUAGE in der startXulu.bat gesteuert werden.  Die Übersetzungen werden über Property-Dateien im Ordner /resource/locales verwaltet. Beim Anlegen einer neuen Sprache (über den Button unten), werden die entsprechenden Dateien (mit Dummy-Übersetzungen) automatisch erzeugt und können mit einem einfachen Text-Editor bearbeitet werden.
+Model.ErrorOccured=ES IST EIN FEHLER AUFGETRETEN!!!
+Model.Init=Modell initialisiert
+Model.Start=Modell gestartet
+Model.Stop=Modell gestoppt
+Model.Dispose=Modell disposed
+Model.Step.Started=Modell-Schritt ${0} gestarted
+Model.Step.Finished=Modell-Schritt ${0} beendet
+ModelResource.Type.Null=Typ der Ressource darf nicht NULL sein!
+ModelResource.Data.Null=Datenobjekt der Ressource darf nicht NULL sein!
+ModelResource.Cat.Unknown=Unbekannte Ressourcen-Kategorie (${0})
+ModelResource.Data.Error=Ressource '${0}': ${1} erwartet

Added: trunk/resource/locales/XuluMainError.properties
===================================================================
--- trunk/resource/locales/XuluMainError.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluMainError.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,24 @@
+# --------------------------------------------------------------------
+# ------ Default Translations (english) for Xulu error messages ------
+# --------------------------------------------------------------------
+
+Access=access
+ReadAccess=read access
+WriteAccess=write access
+AccessError=Access violation
+AccessErrMess_1=You don't have
+AccessErrMess_2=to this object at the time
+DataTypeError=Data type error
+TypeCastErrMess=Typ cast not possible
+InstantiationError=Instantiation error
+InstantiationErrMess=Class must be instantiable! Abstact classes or interfaces are not allowed!
+ClassCastError=Class cast error
+InstExpMess_1=Instance of
+InstExpMess_2=expected!
+DataError=Data error
+DuplXuluObjectNameMessIntro=Datapool already contains an object with name
+DuplModelNameMessIntro=Xulu already contains a model with name
+ClassError=Class error
+ClassNotFoundErrMess=The indicated class could not be found
+NoEvents=No events available for this object!
+NoHandler=No handler available for this object!

Added: trunk/resource/locales/XuluMainError_de.properties
===================================================================
--- trunk/resource/locales/XuluMainError_de.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluMainError_de.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,24 @@
+# ---------------------------------------------------------
+# ------ German Translations for Xulu error messages ------
+# ---------------------------------------------------------
+
+Access=Zugriffsrecht
+ReadAccess=Leserecht
+WriteAccess=Schreibrecht
+AccessError=Zugriffsfehler
+AccessErrMess_1=Sie haben (zur Zeit) kein
+AccessErrMess_2=auf dieses Objekt
+DataTypeError=Datentyp-Fehler
+TypeConvErrMess=Typumwandunlung kann nicht vorgenommen werden
+InstantiationError=Instanziierungs-Fehler
+InstantiationErrMess=Klasse muss instanziierbar sein! Abstrakte Klassen oder Interfaces sind nicht zulaessig!
+ClassCastError=Cast-Fehler
+InstExpMess_1=Instanz von
+InstExpMess_2=erwartet!
+DataError=Daten-Fehler
+DuplXuluObjectNameMessIntro=Es gibt bereits ein Datenpool-Objekt
+DuplModelNameMessIntro=Es gibt bereits ein Modell
+ClassError=Klassen-Fehler
+ClassNotFoundErrMess=Die angegebene Klasse konnte nicht gefunden werden
+NoEvents=Keine Ereignisse für dieses Objekt verfügbar!
+NoHandler=Keine Handler für dieses Objekt verfügbar!

Added: trunk/resource/locales/XuluModel_Clue.properties
===================================================================
--- trunk/resource/locales/XuluModel_Clue.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluModel_Clue.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,93 @@
+# ---------------------------------------------------------------
+# ------ English Translations for the xulu model ClueModel ------
+# ---------------------------------------------------------------
+
+# Descriptions of model resources
+MRDesc.ModelSteps=Number of time steps (${0}-${1})
+MRDesc.Tol.Type=Type of tolerance expressions [${0} = perc.; ${1} = abs.] (integer)
+MRDesc.Tol.Single=Demand tolerance for each single land use type (double)
+MRDesc.Tol.Avg=Average tolerance for land use demand (double)
+MRDesc.qmConvFactor=Conversion factor: demand unit to qm (double)
+MRDesc.LUC.Scenario=Base LUC scenatio (float-Grid)
+MRDesc.LUC.History=Land use history (float-Grid)
+MRDesc.LUC.ConvMatrix=Land use conversion matrix (integer-Matrix)
+MRDesc.LUC.ConvDev=Deviation of Land use conversion matrix (integer-Matrix)
+MRDesc.LUC.ConvElas=Conversion elasticity (double-List)
+MRDesc.AreaRestr=Area restrictions (float-Grid)
+MRDesc.Demand.Scenario=Demand scenario (integer-Matrix)
+MRDesc.DF.Static.Grids=Static driving forces (float-MultiGrid)
+MRDesc.DF.Dynamic.Grids=Dynamic driving forces (float-MultiGrid)
+MRDesc.DF.Dynamic.Types=Dynamic driving force types (int-List)
+MRDesc.Regression=Regression results (double-Matrix)
+MRDesc.Nbh.Weight=Weight of neighborhood (double-List)
+MRDesc.Nbh.Setting=Neighborhood settings (double-Matrix)
+MRDesc.Nbh.Regr=Regression results for neighborhood (double-Matrix)
+MRDesc.LSPA.Prob=Location specific preference addition (float-MultiGrid)
+MRDesc.LSPA.Fact=Factors for location specific pref. add. (double-List)
+MRDesc.Temp.LucHist=Temp-Raster for current land use history (float-Grid)
+MRDesc.Temp.LucProb=Temp-Raster for land use probabilities (float-MultiGrid)
+MRDesc.Temp.NbhProb=Temp-Raster for neighborhood probabilities (float-MultiGrid)
+MRDesc.Temp.IterVar=Temp-List for iteration variables (float-List)
+MRDesc.Temp.Luc=Temp-Raster for current land use (float-Grid)
+MRDesc.Temp.TotalProb=Temp-Raster for total probabilities (float-MultiGrid)
+MRDesc.Out.StepRes=Out-Rasters time step results (float-MultiGrid)
+
+# Model messages
+Model.InitCover=Initial coverage
+Model.TotalCover=Total coverage
+Model.LucTypes=List of all LUCC-Types in BaseScenario
+Model.Step.Started=Started step ${0}
+Model.Step.Started=Finished step ${0}
+Model.Step.Calc.done= done.
+Model.Step.Calc.LUCProb=Calculate LU-Probabilities for step ${0}...
+Model.Step.Calc.NbhProb=Calculate Neighborhood-Probabilities for step ${0}...
+Model.Step.Calc.Iter=Calculate Iterations for ${0}...
+Model.Step.Calc.Iter.done= done (${0} Iterations).
+Model.GUI.Single.Dev.Allowed=Allowed demand deviation per LUC type:
+Model.GUI.Avg.Dev.Allowed=Allowed average demand deviation:
+Model.GUI.AutoUpdate=Deviation update automatically
+Model.GUI.Total=Total
+Model.GUI.Avg=Average
+Model.GUI.LucType=LUC type
+Model.GUI.CurrDemandDev=Currend demand deviation
+Model.GUI.Iteration=Iteration
+Model.GUI.Type=Type
+Model.GUI.Divergence=Divergence
+Model.GUI.IterVar=Iter-Var.
+
+# Error messages
+Error.ModelSteps.Type=Long- or Integer-Property
+Error.LUC.ConvDev.Col=Matrix for LUC conversion deviation must have at least ${0} columns (one for each land use types)...
+Error.LUC.ConvDev.Row=Matrix for LUC conversion deviation must have at least ${0} rows (one for each land use types)...
+Error.LUC.ConvElas.Size=List for conversion elasticity must have at least ${0} entries (one for each land use types)...
+Error.LUC.ConvElas.Value=ListProperty with values between 0 and 1
+Error.Demand.Scenario.Col=Matrix for demand scenario must have ${0} column (one for each land use type)...
+Error.Demand.Scenario.Row=Matrix for demand scenario must have ${0} rows (one for each time step)...
+Error.DF.Static.Grids=MultiGrid for static driving forces must contain at least ${0} entries (one for each driving force)...
+Error.DF.Dynamic.Types.Size=List of dynamic driving forces must not have more than ${0} entries...
+Error.DF.Dynamic.Types.Value=Only values between ${0} and ${1} are allowed in list of dynamic driving forces...
+Error.DF.Dynamic.Grids.Null=Dynamic Driving Forces are uses! Resource '${0}' is not allowed to be null...
+Error.DF.Dynamic.Grids.Size1=MultiGrid for dynamic driving forces must contain at least ${0} entries (one for each driving force at every time step)...
+Error.DF.Dynamic.Grids.Size2=MultiGrid for dynamic driving forces must contain the same number of grids for all driving forces...
+Error.Regression.Col=Matrix for regression results must have ${0} columns (one for the constant and one for each driving force)...
+Error.Regression.Row=Matrix for regression results must have ${0} rows (one for each land use type)...
+Error.Nbh.Weight.Size=List of neighborhood weights must have at least ${0} entries (one for each land use type)...
+Error.Nbh.Setting.Null=Neighborhood settings must be specified...
+Error.Nbh.Setting.Size1=Neighborhood settings must be specified in matrix of uneven size in dimension 1 and 2 (the center is the considered cell)...
+Error.Nbh.Setting.Size2=${0} neighborhood settings must be specified in matrix (one for each land use type)...
+Error.Nbh.Regr.Null=Neighborhood regression must be specified...
+Error.Nbh.Regr.Col=Matrix for neighborhood regression results must have ${0} columns (one for the constant and one for each land use type)...
+Error.Nbh.Regr.Row=Matrix for neighborhood regression results must have ${0} rows (one for each land use type)...
+Error.Temp.LucProb.Size=MultiGrid for land use probabilities must contain at least ${0} grids (one for each land use type)...
+Error.Temp.NbhProb.Null=Temp. raster for neighborhood probabilities must be specified...
+Error.LSPA.Prob.Size=MultiGrid for location specific preference addition must contain at least ${0} entries (one for land use type)...
+Error.LSPA.Fact.Size=Factor-List for location specific preference addition must contain at least ${0} entries (one for land use type)...
+Error.RasterDim.GridWidth=Grid width
+Error.RasterDim.GridHeight=Grid height
+Error.RasterDim.CellWidth=Cell width
+Error.RasterDim.CellHeight=Cell height
+Error.RasterDim.SampleType=Grid sample type
+Error.RasterDim=${0} of '${1}' is incompatible to '${2}'...
+Error.Resource.Not.Allowed='${0}': value ${1} not allowed!
+Error.Expected.Matrix2=At least 2-dimensional Matrix
+Error.Expected.Matrix3=At least 3-dimensional Matrix

Added: trunk/resource/locales/XuluModel_Clue_de.properties
===================================================================
--- trunk/resource/locales/XuluModel_Clue_de.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluModel_Clue_de.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,91 @@
+# ---------------------------------------------------------------
+# ------ German Translations for the xulu model ClueModel ------
+# ---------------------------------------------------------------
+
+# Descriptions of model resources
+MRDesc.ModelSteps=Modellierte Zeitschritte (${0}-${1})
+MRDesc.Tol.Type=Art der Toleranz-Angabe [${0} = Prozent; ${1} = Abs.] (integer)
+MRDesc.Tol.Single=Erlaubte Bedarfsabweichung pro LUC-Typ (double)
+MRDesc.Tol.Avg=Erlaubte durchschn. Bedarfsabweichung (double)
+MRDesc.qmConvFactor=Umrechnungsfaktor: Nachfrage-Eh. zu qm (double)
+MRDesc.LUC.Scenario=Ausgangsszenario LUC (float-Grid)
+MRDesc.LUC.History=LUC History (float-Grid)
+MRDesc.LUC.ConvMatrix=LUC-Conversion-Matrix (integer-Matrix)
+MRDesc.LUC.ConvDev=Abweichung der LUC-Conversion-Matrix (integer-Matrix)
+MRDesc.LUC.ConvElas=Conversion Elasticity (double-List)
+MRDesc.AreaRestr=Area Restrictions (float-Grid)
+MRDesc.Demand.Scenario=Nachfrage-Szenarion (integer-Matrix)
+MRDesc.DF.Static.Grids=Statische Driving Forces (float-MultiGrid)
+MRDesc.DF.Dynamic.Grids=Dynamische Driving Forces (float-MultiGrid)
+MRDesc.DF.Dynamic.Types=Dynamische LUC-Typen (int-List)
+MRDesc.Regression=Regression (double-Matrix)
+MRDesc.Nbh.Weight=Nachbarschafts-Gewichte (double-List)
+MRDesc.Nbh.Setting=Nachbarschafts-Einstellung (double-Matrix)
+MRDesc.Nbh.Regr=Nachbarschafts-Regression (double-Matrix)
+MRDesc.LSPA.Prob=Location specific preference addition (float-MultiGrid)
+MRDesc.LSPA.Fact=Faktoren der location specific pref. add. (double-List)
+MRDesc.Temp.LucHist=Temp-Raster fuer LUC-History (float-Grid)
+MRDesc.Temp.LucProb=Temp-Raster fuer LUC-W'keiten (float-MultiGrid)
+MRDesc.Temp.NbhProb=Temp-Raster fuer Nachbarschafts-W'keiten (float-MultiGrid)
+MRDesc.Temp.IterVar=Temp-List fuer Iterations-Variablen (float-List)
+MRDesc.Temp.Luc=Temp-Raster fuer aktuelle LUC (float-Grid)
+MRDesc.Temp.TotalProb=Temp-Raster fuer Gesamt-W'keiten (float-MultiGrid)
+MRDesc.Out.StepRes=Ausgabe-Raster fuer Schritt-Ergebnisse (float-MultiGrid)
+
+# Model messages
+Model.InitCover=Initiale LUC
+Model.TotalCover=Gesamt-Flaeche
+Model.LucTypes=Liste der LUC-Typen im Szenario
+Model.Step.Calc.done= erledigt.
+Model.Step.Calc.LUCProb=Berechne LUC-W'keiten fuer Schritt ${0}...
+Model.Step.Calc.NbhProb=Berechne Nachbarschafts-W'keiten fuer Schritt ${0}...
+Model.Step.Calc.Iter=Berechne Iterationen fuer Schritt ${0}...
+Model.Step.Calc.Iter.done= erledigt (${0} Iterationen).
+Model.GUI.Single.Dev.Allowed=Erlaubte Bedarfsabweichung pro LUC-Typ:
+Model.GUI.Avg.Dev.Allowed=Erlaubte durchschn. Bedarfsabweichung:
+Model.GUI.AutoUpdate=Abweichungen autom. aktualisieren
+Model.GUI.Total=Gesamt
+Model.GUI.Avg=Durchschn.
+Model.GUI.LucType=LUC-Typ
+Model.GUI.CurrDemandDev=Aktuelle Bedarfsabweichung
+Model.GUI.Iteration=Iteration
+Model.GUI.Type=Typ
+Model.GUI.Divergence=Abweichung
+Model.GUI.IterVar=Iter-Var.
+
+# Error messages
+Error.ModelSteps.Type=Long- oder Integer-Property
+Error.LUC.ConvDev.Col=Matrix fuer Abweichung der LUC-Conversion-Matrix muss mind. ${0} Spalten haben (eine pro LUC-Typ)...
+Error.LUC.ConvDev.Row=Matrix fuer Abweichung der LUC-Conversion-Matrix muss mind. ${0} Zeilen haben (eine pro LUC-Typ)...
+Error.LUC.ConvElas.Size=Liste fuer Conversion-Elasticity muss mind. ${0} Eintraege haben (einen pro LUC-Typ)...
+Error.LUC.ConvElas.Value=ListProperty mit Werten zwischen 0 und 1
+Error.Demand.Scenario.Col=Matrix fuer Nachfrage-Szenario muss mind. ${0} Spalten haben (eine pro LUC-Typ)...
+Error.Demand.Scenario.Row=Matrix fuer Nachfrage-Szenario muss mind. ${0} Zeilen haben (eine pro Zeitschritt)...
+Error.DF.Static.Grids=MultiGrid fuer statische DF muss mind. ${0} Eintraege haben (einen pro DF)...
+Error.DF.Dynamic.Types.Size=Liste der dyn. DF darf maximal ${0} Eintraege haben...
+Error.DF.Dynamic.Types.Value=Nur Werte zwischen ${0} und ${1} erlaubt in Liste der dynamischen DF...
+Error.DF.Dynamic.Grids.Null=Dynamische Driving Forces werden verwendet! Ressource '${0}' muss belegt werden...
+Error.DF.Dynamic.Grids.Size1=MultiGrid fuer dynamische DF muss mind. ${0} Eintraege haben (einen pro DF und Zeitschritt)...
+Error.DF.Dynamic.Grids.Size2=MultiGrid fuer dynamische DF muss die gleiche Anzahl an Rastern fuer jeden DF beinhalten...
+Error.Regression.Col=Matrix fuer Regression muss ${0} Spalten haben (eine fuer die Konstante und eine pro DF)...
+Error.Regression.Row=Matrix fuer Regression muss ${0} Zeilen haben (eine pro LUC-Typ)...
+Error.Nbh.Weight.Size=Liste der Nachbarschafts-Gewichte muss mind. ${0} Eintraege haben (eine pro LUC-Typ)...
+Error.Nbh.Setting.Null=Nachbarschafts-Einstellungen muessen angegeben werden...
+Error.Nbh.Setting.Size1=Nachbarschafts-Matrix muss von ungerader Groesse in jeder Dimension sein (das Zentrum ist die betr. Zelle)...
+Error.Nbh.Setting.Size2=${0} Nachbarschafts-Einst. muessen in der Matrix eingetragen sein (je eine pro LUC-Typ)...
+Error.Nbh.Regr.Null=Nachbarschafts-Regression muss angegeben werden...
+Error.Nbh.Regr.Col=Matrix fuer Nachbarschafts-Regression muss ${0} Spalten haben (eine fuer die Konstante und eine pro LUC-Typ)...
+Error.Nbh.Regr.Row=Matrix for Nachbarschafts-Regression muss ${0} Zeilen haben (eine pro LUC-Typ)...
+Error.Temp.LucProb.Size=MultiGrid LUC-W'keiten muss mind. ${0} Raster enthalten (eines pro LUC-Typ)...
+Error.Temp.NbhProb.Null=Temp-Raster fuer Nachbarschafts-W'keiten muss angegeben werden...
+Error.LSPA.Prob.Size=MultiGrid fuer Location Specific Preference Addition muss mind. ${0} Eintraege haben (einen pro LUC-Typ)...
+Error.LSPA.Fact.Size=Faktor-Liste fuer Location Specific Preference Addition muss mind ${0} Eintraege (einen pro LUC-Typ)...
+Error.RasterDim.GridWidth=Raster-Breite
+Error.RasterDim.GridHeight=Raster-Hoehe
+Error.RasterDim.CellWidth=Zellen-Breite
+Error.RasterDim.CellHeight=Zellen-Hoehe
+Error.RasterDim.SampleType=Raster-Datentyp
+Error.RasterDim=${0} von '${1}' ist nicht kompatibel zu '${2}'...
+Error.Resource.Not.Allowed='${0}': Wert ${1} nicht zulaessig!
+Error.Expected.Matrix2=Mindestens 2-dimensionale Matrix
+Error.Expected.Matrix3=Mindestens 3-dimensionale Matrix

Added: trunk/resource/locales/XuluModel_ImpetusFireCA.properties
===================================================================
--- trunk/resource/locales/XuluModel_ImpetusFireCA.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluModel_ImpetusFireCA.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,45 @@
+# ---------------------------------------------------------------
+# ------ Default translations (english) for the xulu model ------
+# ------ ImpetusFireCA (iMABFIRE)                          ------
+# ---------------------------------------------------------------
+
+# Descriptions of model resources
+MRDesc.In.ModelParams=Common model parameters
+MRDesc.In.BurnSource=Fire source points [Point-FeatureCollection]
+MRDesc.In.BaseLUC=LUC classification [float-Raster]
+MRDesc.In.BurnSuit=Burn suitability (optional) [float-Raster]
+MRDesc.Out.LUC=Output raster for modelled LUC
+MRDesc.Out.BioMass=Output raster for burned biomass
+MRDesc.Temp.BurnTime=Temp raster for burn time
+
+# Model messages
+Model.ModelTime.Step=1 model step = 1 hour
+Model.ModelTime.Iter=1 iteration = ${0} seconds
+Model.GUI.WindDir.Dev=Deviation of wind direction [°]:
+Model.GUI.WindPower=Wind power [m/s]:
+Model.GUI.WindPower.Dev=Deviation of wind power [m/s]:
+Model.GUI.WindMatrix=Wind matrix:
+
+
+# Error messages
+Error.Global.Mess=Resource '${0}': ${1}
+Warn.In.ModelParams.Missing=Property '${0}' missing. Value ${0} used.
+Error.In.ModelParams.ModelTime=Must contain a property '${0}' with an greater zero int!
+Error.In.ModelParams.BurnLuc=Must contain a property '${0}' with an greater zero int!
+Error.In.ModelParams.BurnOutLuc=Must contain a property '${0}' with an greater zero int!
+Error.In.ModelParams.BurnSuit=Must contain a list-property '${0}' of number values!
+Error.In.ModelParams.BurnTime=Must contain a list-property '${0}' of positive number values!
+Error.In.ModelParams.WindDir=Must contain a property '${0}' with a not-negative value!
+Error.In.ModelParams.WindPower=Must contain a property '${0}' with a positive value!
+Error.In.ModelParams.WindDirDev=Must contain a property '${0}' with a not-negative value!
+Error.In.ModelParams.WindPowerDev=Must contain a property '${0}' with a not-negative value!
+Error.In.ModelParams.WindPowerMaxBW=Must contain a property '${0}' with a positive value!
+Error.In.ModelParams.WindMatrix=Must contain a 3x3-matrix-property '${0}' of number values!
+Error.In.ModelParams.WindMatrix_PowerConst=Property '${0}' must be scalar!
+Error.In.ModelParams.WindMatrix_PowerFact=Property '${0}' must be scalar with value not 0!
+Error.In.BurnSource.Data=Must contain at least one point feature!
+Error.In.BaseLUC.Grid=LUC-Classification-Raster
+Error.In.BurnSuit.Grid=Burn-Suitability-Raster
+Error.Out.LUC.Grid=LUC-Output-Raster
+Error.Out.BioMass.Grid=Biomass-Output-Raster
+Error.Temp.BurnTime.Grid=Burntime-Output-Raster
\ No newline at end of file

Added: trunk/resource/locales/XuluModel_ImpetusFireCA_de.properties
===================================================================
--- trunk/resource/locales/XuluModel_ImpetusFireCA_de.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluModel_ImpetusFireCA_de.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,45 @@
+# ----------------------------------------------------
+# ------ German Translations for the xulu model ------
+# ------ ImpetusFireCA (iMABFIRE)               ------
+# ----------------------------------------------------
+
+# Descriptions of model resources
+MRDesc.In.ModelParams=Allgemeine Modell-Parameter
+MRDesc.In.BurnSource=Brandherde [Point-FeatureCollection]
+MRDesc.In.BaseLUC=LUC Klassifikation [float-Raster]
+MRDesc.In.BurnSuit=Brenn-Eignung (optional) [float-Raster]
+MRDesc.Out.LUC=Ausgabe-Raster für modellierte LUC
+MRDesc.Out.BioMass=Ausgabe-Raster für verbrannte Biomasse
+MRDesc.Temp.BurnTime=Temp-Raster für Brenn-Zeit
+
+# Model messages
+Model.ModelTime.Step=1 Modellschritt = 1 Stunde
+Model.ModelTime.Iter=1 Iteration = ${0} Sekunden
+Model.GUI.WindDir.Dev=Abweichung Windrichtung [°]:
+Model.GUI.WindPower=Windstaerke [m/s]:
+Model.GUI.WindPower.Dev=Abweichung Windstaerke [m/s]:
+Model.GUI.WindMatrix=Wind-Matrix:
+
+
+# Error messages
+Error.Global.Mess=Ressource '${0}': ${1}
+Warn.In.ModelParams.Missing=Property '${0}' nicht vorhanden. Wert ${0} angenommen.
+Error.In.ModelParams.ModelTime=Muss eine Property '${0}' mit int-Wert > 0 besitzen!
+Error.In.ModelParams.BurnLuc=Muss eine Property '${0}' mit int-Wert > 0 besitzen!
+Error.In.ModelParams.BurnOutLuc=Muss eine Property '${0}' mit int-Wert > 0 besitzen!
+Error.In.ModelParams.BurnSuit=Muss eine Listen-Property '${0}' mit numerischen Werten besitzen!
+Error.In.ModelParams.BurnTime=Muss eine Listen-Property '${0}' mit positiven numerischen Werten besitzen!
+Error.In.ModelParams.WindDir=Muss eine Property '${0}' mit Wert >= 0 besitzen!
+Error.In.ModelParams.WindPower=Muss eine Property '${0}' mit Wert > 0 besitzen!
+Error.In.ModelParams.WindDirDev=Muss eine Property '${0}' mit Wert >= 0 besitzen!
+Error.In.ModelParams.WindPowerDev=Must contain a property '${0}' with a not-negative value!
+Error.In.ModelParams.WindPowerMaxBW=Muss eine Property '${0}' mit Wert > 0 besitzen!
+Error.In.ModelParams.WindMatrix=Muss eine 3x3-Matrix-Property '${0}' mit numerischen Werten besitzen!
+Error.In.ModelParams.WindMatrix_PowerConst=Property '${0}' muss skalar sein!
+Error.In.ModelParams.WindMatrix_PowerFact=Property '${0}' muss skalar sein mit Wert <> 0!
+Error.In.BurnSource.Data=Muss mind. ein Punkt-Feature besitzen!
+Error.In.BaseLUC.Grid=LUC-Klassifikation-Raster
+Error.In.BurnSuit.Grid=Brenn-Eignungs-Raster
+Error.Out.LUC.Grid=LUC-Ausgabe-Raster
+Error.Out.BioMass.Grid=BioMasse-Ausgabe-Raster
+Error.Temp.BurnTime.Grid=Brennzeit-Ausgabe-Raster
\ No newline at end of file

Added: trunk/resource/locales/XuluModel_SmallReservoirModel.properties
===================================================================
--- trunk/resource/locales/XuluModel_SmallReservoirModel.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluModel_SmallReservoirModel.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,37 @@
+# ---------------------------------------------------------------
+# ------ Default translations (english) for the xulu model ------
+# ------ SmallReservoirModel (SYMBA)                       ------
+# ---------------------------------------------------------------
+
+# Descriptions of model resources
+MRDesc.In.DHM=DHM (raster)
+MRDesc.In.Dam.Loc=Dam wall location (feature collection)
+MRDesc.In.Dam.Height=Dam wall height (double)
+MRDesc.In.Infilt=Infiltration in mm/day (double)
+MRDesc.In.Evapo=Evaporation in mm/day (double)
+MRDesc.In.StepSize=Model step size in days (int)
+MRDesc.Out.Area.Size=Calculated: size of flooded area in qm (double-List)
+MRDesc.Out.Area.Vol=Calculated: volume of flooded area in qqm (double-List)
+MRDesc.Out.Area.Grid=Calculated: flooded area (float-MultiGrid)
+MRDesc.Temp.DHM=Temp: dhm for wall (raster)
+
+# Model messages
+Model.Calc.Done= done.
+Model.Calc.Fill=Calculate filled reservoir...
+Model.Calc.Empty=Calculate reservoir after day ${0}...
+Model.Calc.Dam.DHM=Determining dam wall DHM and starting cells...
+Model.GUI.DamHeight=Dam height [m]
+Model.GUI.ModelSteps=Modelled step size [days]
+Model.GUI.Infilt=Infiltration [mm/day]
+Model.GUI.Evapo=Evaporation [mm/day]
+Model.GUI.Store.StepResults=Store step result raster
+Model.GUI.Calc.Area=Calculated area [m²]:
+Model.GUI.Calc.Vol=Calculated volume [m³]:
+
+# Error messages
+Error.Global.Mess=Resource '${0}': ${1}
+Error.In.Dam.Loc=Must contain at least one line string feature!
+Error.In.Dam.Loc.Type=Dam wall resource does not contain any (Multi)LineString!
+Error.In.DHM.Grid=DHM
+Error.Out.Area.Grid=Raster for flooded area
+Error.Temp.DHM.Grid=Temp-DHM for dam wall

Added: trunk/resource/locales/XuluModel_SmallReservoirModel_de.properties
===================================================================
--- trunk/resource/locales/XuluModel_SmallReservoirModel_de.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluModel_SmallReservoirModel_de.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,37 @@
+# ----------------------------------------------------
+# ------ German translations for the xulu model ------
+# ------ SmallReservoirModel (SYMBA)            ------
+# ----------------------------------------------------
+
+# Descriptions of model resources
+MRDesc.In.DHM=DHM (raster)
+MRDesc.In.Dam.Loc=Staudamm-Lage (feature collection)
+MRDesc.In.Dam.Height=Staudamm-Hoehe ueber NN (double)
+MRDesc.In.Infilt=Versickerung in mm/tag (double)
+MRDesc.In.Evapo=Verdunstung in mm/tag (double)
+MRDesc.In.StepSize=Modellierte Schrittweite in Tagen (int)
+MRDesc.Out.Area.Size=Ausgabe: Groesse der ueberfluteten Flaeche in qm (double-List)
+MRDesc.Out.Area.Vol=Ausgabe: Volumen der ueberfluteten Flaeche in qqm (double-List)
+MRDesc.Out.Area.Grid=Ausgabe: Ueberflutete Flaeche (float-MultiGrid)
+MRDesc.Temp.DHM=Temp: DHM fuer Staumauer (raster)
+
+# Model messages
+Model.Calc.Done= fertig.
+Model.Calc.Fill=Berechne Befuellung des Stausees...
+Model.Calc.Empty=Berechne Inhalt des Stausees nach Tag ${0}...
+Model.Calc.Dam.DHM=Ermittle das Staumauer-DHM und die Start-Zellen...
+Model.GUI.DamHeight=Staumauer Hoehe [m]
+Model.GUI.ModelSteps=Modellierte Schrittweite [Tage]
+Model.GUI.Infilt=Versickerung [mm/Tag]
+Model.GUI.Evapo=Verdunstung [mm/Tag]
+Model.GUI.Store.StepResults=Speichere Raster fuer jeden Modellschritt
+Model.GUI.Calc.Area=Berechnete Stausee-Groesse [m²]:
+Model.GUI.Calc.Vol=Berechnetes Stausee-Volumen [m³]:
+
+# Error messages
+Error.Global.Mess=Resource '${0}': ${1}
+Error.In.Dam.Loc=Muss mindestens ein LineString-Feature enthalten!
+Error.In.Dam.Loc.Type=Staudamm-Ressource enthaelt keinen (Multi)LineString!
+Error.In.DHM.Grid=DHM
+Error.Out.Area.Grid=Raster fuer ueberflutete Flaeche
+Error.Temp.DHM.Grid=Temp-DHM fuer Staumauer

Added: trunk/resource/locales/XuluVisualisationTool.properties
===================================================================
--- trunk/resource/locales/XuluVisualisationTool.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluVisualisationTool.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,15 @@
+# -------------------------------------------------------------------
+# ------ Default Translations (english) for Xulu Visualisation ------
+# ------ Plugins                                               ------
+# ------------------------------------------------------------------
+
+# ======== GTVisualisationTool ========
+GTVisualisationTool.FrameTitle=Geotools Visualisation
+
+# ======== GTEditorTool ========
+GTEditorTool.FrameTitle=Geotools Editor
+
+# ======== JFreeChartVisualisationTool ========
+JFreeChartVisualiationTool.FrameTitle=JFreeChart Visualisation
+JFreeChartVisualiationTool.RotateData=Rotate data
+JFreeChartVisualiationTool.ChartObjects=Chart objects

Added: trunk/resource/locales/XuluVisualisationTool_de.properties
===================================================================
--- trunk/resource/locales/XuluVisualisationTool_de.properties	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/resource/locales/XuluVisualisationTool_de.properties	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,14 @@
+# ----------------------------------------------------------------
+# ------ German Translations for Xulu Visualisation Plugins ------
+# ----------------------------------------------------------------
+
+# ======== GTVisualisationTool ========
+GTVisualisationTool.FrameTitle=Geotools Visualisierung
+
+# ======== GTEditorTool ========
+GTEditorTool.FrameTitle=Geotools Editor
+
+# ======== JFreeChartVisualisationTool ========
+JFreeChartVisualiationTool.FrameTitle=JFreeChart Visualisierung
+JFreeChartVisualiationTool.RotateData=Daten rotieren
+JFreeChartVisualiationTool.ChartObjects=Chart-Objekte

Added: trunk/resource/unused/edit_clear.gif
===================================================================
(Binary files differ)


Property changes on: trunk/resource/unused/edit_clear.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/unused/edit_redo.gif
===================================================================
(Binary files differ)


Property changes on: trunk/resource/unused/edit_redo.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/unused/edit_undo.gif
===================================================================
(Binary files differ)


Property changes on: trunk/resource/unused/edit_undo.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/unused/layer_cancel3.png
===================================================================
(Binary files differ)


Property changes on: trunk/resource/unused/layer_cancel3.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/unused/xulu_icon.gif
===================================================================
(Binary files differ)


Property changes on: trunk/resource/unused/xulu_icon.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/unused/xulu_icon_green.gif
===================================================================
(Binary files differ)


Property changes on: trunk/resource/unused/xulu_icon_green.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/unused/xulu_icon_red.gif
===================================================================
(Binary files differ)


Property changes on: trunk/resource/unused/xulu_icon_red.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/unused/xulu_icon_yellow.gif
===================================================================
(Binary files differ)


Property changes on: trunk/resource/unused/xulu_icon_yellow.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/resource/unused/xuluv.png
===================================================================
(Binary files differ)


Property changes on: trunk/resource/unused/xuluv.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/src/META-INF/PREFERRED.LIST
===================================================================
--- trunk/src/META-INF/PREFERRED.LIST	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/META-INF/PREFERRED.LIST	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,8 @@
+PreferredResources-Version: 1.0
+Preferred: false
+
+Name: edu/bonn/xulu/plugin/model/*
+Preferred: true
+
+Name: edu/bonn/xulu/plugin/model/-
+Preferred: true

Added: trunk/src/appl/data/DataLoader.java
===================================================================
--- trunk/src/appl/data/DataLoader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/DataLoader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,31 @@
+package appl.data;
+
+import java.io.Serializable;
+
+/**
+ * A class that automatically loads a specified object and returns it, as soon
+ * as the {@link #load()} method is invoked. It is the counterpart of {@link DataUnloader}.
+ * 
+ * @author Dominik Appl
+ * @see DataUnloader
+ */
+public interface DataLoader extends Serializable {
+	
+	/**
+	 * On invocation the data is loaded and returned
+	 * 
+	 * @return the newly loaded object
+	 * 
+	 * @throws LoadingException if for some reason the data could not
+	 * be loaded
+	 */
+	public Object load() throws LoadingException;
+	
+	/**
+	 * @return some general information about the loading class 
+	 * (like what the class exactly loads)
+	 * 
+	 */
+	public String getLoadInfo();
+
+}

Added: trunk/src/appl/data/DataProxy.java
===================================================================
--- trunk/src/appl/data/DataProxy.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/DataProxy.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,12 @@
+package appl.data;
+
+/**
+ * A DataProxy class should forward calls to exactly one encapsulated object.
+ * 
+ * @author Dominik Appl
+ */
+public interface DataProxy {
+
+	/** get the encapsulated Object */
+	Object getProxiedObject();
+}

Added: trunk/src/appl/data/DataUnloader.java
===================================================================
--- trunk/src/appl/data/DataUnloader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/DataUnloader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,22 @@
+package appl.data;
+
+/**
+ * A instances of <code>DataUnloader</code> unloads a specified object to a
+ * location, as soon as the {@link #unload()} method is invoked. Counterpart of
+ * {@link DataLoader}.
+ * 
+ * @author Dominik Appl
+ */
+public interface DataUnloader {
+
+	/**
+	 * unloads the Data to a specific location
+	 */
+	public void unload();
+
+	/**
+	 * @return a short description of what the class exactly does
+	 */
+	public String getUnloadInfo();
+
+}

Added: trunk/src/appl/data/FactoryLoader.java
===================================================================
--- trunk/src/appl/data/FactoryLoader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/FactoryLoader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,56 @@
+package appl.data;
+
+import schmitzm.data.WritableGrid;
+import appl.util.RasterMetaData;
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+
+/**
+ * This is an implementation of a loader class which loads data with a
+ * {@link WritableGridFactory}. It is used for Late Loading.
+ * 
+ * @author Dominik Appl
+ * @see WritableGridLLProxy
+ */
+public class FactoryLoader implements DataLoader {
+
+	private WritableGridFactory fac;
+
+	private RasterMetaData metaData;
+
+	private FactoryLoader() {
+	}
+
+	/**
+	 * @param factory
+	 *            the factory which is used for instantiation
+	 * @param metaData
+	 *            the meta data is required for grid instantiation
+	 */
+	public FactoryLoader(WritableGridFactory factory, RasterMetaData metaData) {
+		fac = factory;
+		this.metaData = metaData;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#load()
+	 */
+	public WritableGrid load() {
+		return fac.newInstance(metaData.getDataType(), metaData.getWidth(),
+				metaData.getHeight(), metaData.getMinX(), metaData.getMinY(),
+				metaData.getX(), metaData.getY(), metaData.getRealWidth(),
+				metaData.getRealHeight(), metaData
+						.getCoordinateReferenceSystem());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#getLoadInfo()
+	 */
+	public String getLoadInfo() {
+		return "FactoryLoader|" + fac + "|" + metaData;
+	}
+
+}

Added: trunk/src/appl/data/ImportFactoryLoader.java
===================================================================
--- trunk/src/appl/data/ImportFactoryLoader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/ImportFactoryLoader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,68 @@
+package appl.data;
+
+import edu.bonn.xulu.appl.XuluRegistry;
+import edu.bonn.xulu.io.ImportFactory;
+
+/**
+ * This is an implementation of a loader class which loads data with an
+ * importer. It is for Late Loading.
+ * 
+ * @author Dominik Appl
+ * @see WritableGridLLProxy
+ * @author Dominik Appl
+ */
+public class ImportFactoryLoader implements DataLoader {
+
+	private ImportFactory fac;
+
+	private Object inputPara;
+
+	private XuluRegistry reg;
+
+	/**
+	 * not usable
+	 */
+	private ImportFactoryLoader() {
+	}
+
+	/**
+	 * @param importFac
+	 *            the import factory to be used for loading
+	 * @param inputPara
+	 *            the input object (usually a file)
+	 * @param reg
+	 *            the {@link XuluRegistry}
+	 */
+	public ImportFactoryLoader(ImportFactory importFac, Object inputPara,
+			XuluRegistry reg) {
+		fac = importFac;
+		this.inputPara = inputPara;
+		this.reg = reg;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#load()
+	 */
+	public Object load() throws LoadingException {
+		try {
+			return fac.importObject(inputPara, reg);
+		} catch (Exception e) {
+			throw new LoadingException(
+					"Could not load Grid with Importfactory <"
+							+ fac.getClass().getName() + ">" + " and "
+							+ inputPara, inputPara);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#getLoadInfo()
+	 */
+	public String getLoadInfo() {
+		return "ImportFactoryLoader|" + fac + "|" + inputPara;
+	}
+
+}

Added: trunk/src/appl/data/LateLoadingProxy.java
===================================================================
--- trunk/src/appl/data/LateLoadingProxy.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/LateLoadingProxy.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,178 @@
+package appl.data;
+
+import java.io.File;
+import java.io.Serializable;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.util.GeneralUtil;
+
+/**
+ * Loads an object on demand with the help of an <code>DataLoader</code>. The
+ * unload() method unloads a serializable {@link Object} into a temporary folder
+ * on the hard disk. Unloading can be disabled via the
+ * {@link #setUnloading(boolean)} method.
+ * 
+ * @see DataLoader
+ * @author Dominik Appl
+ */
+public class LateLoadingProxy implements DataProxy, Serializable {
+
+	private File unloadFile;
+
+	protected transient final Logger LOG = LogManager.getLogger(this.getClass()
+			.getName());
+
+	/** Object loaded? */
+	protected boolean loaded = false;
+
+	protected transient DataLoader dataLoader;
+
+	/**
+	 * The loader which constructs the object
+	 */
+	protected transient DataLoader intialDataLoader;
+
+	protected Object baseObject;
+
+	private boolean unloadingEnabled;
+
+	/**
+	 * Creates a new instance with the specified data loader
+	 * 
+	 * @param loader
+	 *            the load method of the {@link DataLoader} is called for
+	 *            loading
+	 */
+	public LateLoadingProxy(DataLoader loader) {
+		if (loader == null) {
+			throw new UnsupportedOperationException(
+					"Error: the dataloader may not be null");
+		}
+		setUnloadDir("Temp");
+		this.intialDataLoader = loader;
+		this.dataLoader = loader;
+	}
+
+	private LateLoadingProxy() {
+	};
+
+	/**
+	 * returns the File, in which the object is/will be unloaded
+	 */
+	protected File getUnloadFile() {
+		return unloadFile;
+	}
+
+	/**
+	 * Loads the data into memory (if not already loaded).<br>
+	 * This method is thread-safe
+	 * 
+	 * @throws LoadingException
+	 */
+	public synchronized void loadData() throws LoadingException {
+		if (loaded)
+			return;
+		try {
+			if (dataLoader == null)
+				throw new UnsupportedOperationException(
+						"A dataloader was found to be null!");
+			baseObject = dataLoader.load();
+			if (LOG.isDebugEnabled())
+				LOG.debug("Successfully loaded " + baseObject + " with "
+						+ dataLoader.getLoadInfo());
+			loaded = true;
+
+		} catch (LoadingException e) {
+			throw e;
+		}
+	}
+
+	/***************************************************************************
+	 * If no Data is loaded or unloading is disabled this method does nothing,
+	 * else it saves the Data into a temporary File. <br>
+	 * Warning: Should be Thread-Safe with loadData, but was not tested
+	 **************************************************************************/
+	public synchronized void unloadData() {
+		// only do something if the Data is loaded and unloading is enabled:
+		if (!loaded)
+			return;
+		if (!unloadingEnabled)
+			return;
+		// there is no way to save the Grid to a File, when its not serializible
+		if (!(baseObject instanceof java.io.Serializable)) {
+			LOG.warn("Could not unload the Data because the class "
+					+ baseObject.getClass().getName() + "is not serializable");
+			return;
+		}
+
+		// unload the Data
+		try {
+			GeneralUtil.SerializeToFile(baseObject, unloadFile);
+			loaded = false;
+			baseObject = null;
+			dataLoader = new SerializedDataLoader(unloadFile, true);
+			LOG.debug("Successfully unloaded Grid into File: "
+					+ unloadFile.getPath());
+		} catch (Exception e) {
+			LOG.error("Error while trying to unload a grid into file '"
+					+ unloadFile.getAbsolutePath() + "'");
+			e.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * This class supports late loading, of course.
+	 * 
+	 * @see appl.data.LateLoadable#unloadData()
+	 * @return true;
+	 * @see appl.data.LateLoadable#isLateLoadable()
+	 */
+	public boolean isLateLoadable() {
+		return true;
+	}
+
+	/**
+	 * returns the baseObject
+	 * 
+	 * @see appl.data.DataProxy#getProxiedObject()
+	 */
+	public Object getProxiedObject() {
+		try {
+			loadData();
+		} catch (LoadingException e) {
+			System.err.println("Error while loading Griddata ... ");
+			e.printStackTrace();
+		}
+		return baseObject;
+	}
+
+	/** returns true, if the baseObject is loaded */
+	public boolean isLoaded() {
+		return loaded;
+	}
+
+	public void setUnloadDir(String newUnloadDirectory) {
+		unloadFile = new File(newUnloadDirectory + File.separatorChar
+				+ this.toString() + ".tmp");
+		// the unload file will be deleted after the JVM shuts down (only after
+		// "normal" shutdown)
+		unloadFile.deleteOnExit();
+	}
+
+	/**
+	 * Set to false, if you want to disable the unloading in a temporary file
+	 */
+	public void setUnloading(boolean unloadingEnabled) {
+		this.unloadingEnabled = unloadingEnabled;
+	}
+
+	/**
+	 * @return true, if unloading is enabled
+	 */
+	public boolean isUnloadingEnabled() {
+		return unloadingEnabled;
+	}
+}

Added: trunk/src/appl/data/SerializedDataLoader.java
===================================================================
--- trunk/src/appl/data/SerializedDataLoader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/SerializedDataLoader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,93 @@
+package appl.data;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import schmitzm.data.WritableGrid;
+
+/**
+ * @author Dominik Appl
+ */
+public class SerializedDataLoader implements DataLoader {
+
+	protected File loadFile;
+
+	private boolean del_after_loading;
+
+	private SerializedDataLoader() {
+	}
+
+	public SerializedDataLoader(File loadFile,
+			boolean DELETE_SOURCE_AFTER_LOADING) {
+		this.loadFile = loadFile;
+		del_after_loading = DELETE_SOURCE_AFTER_LOADING;
+	}
+
+	public SerializedDataLoader(File loadFile) {
+		this(loadFile, false);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#load()
+	 */
+	public Object load() throws LoadingException {
+		Object loadedObject = null;
+		try {
+			BufferedInputStream fis = new BufferedInputStream(
+					new FileInputStream(loadFile));
+			ObjectInputStream ois = new ObjectInputStream(fis);
+			loadedObject = ois.readObject();
+			ois.close();
+			fis.close();
+			// remove File from Filesystem
+			if (del_after_loading)
+				loadFile.delete();
+
+		} catch (FileNotFoundException e) {
+			throw new LoadingException("Could not find temporary unload-file:"
+					+ loadFile, loadFile);
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw new LoadingException("Could not load from temporary file "
+					+ loadFile, loadFile);
+
+		}
+		return loadedObject;
+
+	}
+
+	public static void SerializeToFile(Object o, File destFile)
+			throws LoadingException {
+		try {
+			destFile.createNewFile();
+			BufferedOutputStream fos = new BufferedOutputStream(
+					new FileOutputStream(destFile));
+			ObjectOutputStream oos = new ObjectOutputStream(fos);
+			oos.writeObject(o);
+			oos.close();
+			fos.close();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#getLoadInfo()
+	 */
+	public String getLoadInfo() {
+		return "SerializedDataLoader|" + loadFile.getPath();
+	}
+
+}

Added: trunk/src/appl/data/WritableGridArrayLoader.java
===================================================================
--- trunk/src/appl/data/WritableGridArrayLoader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/WritableGridArrayLoader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,45 @@
+package appl.data;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+import appl.util.RasterMetaData;
+
+/**
+ * Simply loads an empty {@link WritableGridArray} with the specified meta data.
+ * 
+ * @author Dominik Appl
+ */
+public class WritableGridArrayLoader implements DataLoader {
+
+	private RasterMetaData metaData;
+
+	private WritableGridArrayLoader() {
+	}
+
+	/**
+	 * @param metaData
+	 *            the metadata with the exact dimensions/datatype
+	 */
+	public WritableGridArrayLoader(RasterMetaData metaData) {
+		this.metaData = metaData;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#load()
+	 */
+	public WritableGrid load() {
+		return WritableGridArray.createEmpty(metaData);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#getLoadInfo()
+	 */
+	public String getLoadInfo() {
+		return "WritableGridArrayLoader|" + metaData;
+	}
+
+}

Added: trunk/src/appl/data/WritableGridLLProxy.java
===================================================================
--- trunk/src/appl/data/WritableGridLLProxy.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/WritableGridLLProxy.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,251 @@
+package appl.data;
+
+import java.awt.Rectangle;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+import appl.util.RasterMetaData;
+import edu.bonn.xulu.appl.XuluRegistry;
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+/**
+ * This is an a late loading implementation for {@link WritableGrid WritableGrids}.
+ * 
+ * @author Dominik Appl
+ */
+public class WritableGridLLProxy extends LateLoadingProxy implements
+		WritableGrid {
+
+	protected RasterMetaData metaData;
+
+	public WritableGridLLProxy(ImportFactory importFac,
+			RasterMetaData metaData, Object inputPara, XuluRegistry reg) {
+		super(new ImportFactoryLoader(importFac, inputPara, reg));
+		this.metaData = metaData;
+	}
+
+	public WritableGridLLProxy(WritableGridFactory targetFactory,
+			RasterMetaData metaData) {
+		super(new FactoryLoader(targetFactory, metaData));
+		this.metaData = metaData;
+	}
+
+	public WritableGridLLProxy(RasterMetaData metaData) {
+		super(new WritableGridArrayLoader(metaData));
+		baseObject = null;
+		loaded = false;
+		this.metaData = metaData;
+	}
+
+	protected WritableGridLLProxy(RasterMetaData metaData, DataLoader loader) {
+		super(loader);
+		loaded = false;
+		this.metaData = metaData;
+	}
+
+	public double convertRasterToReal(int cell, int dim) {
+		if (!loaded)
+			tryLoadingGrid();
+		;
+		return ((WritableGrid) baseObject).convertRasterToReal(cell, dim);
+	}
+
+	public int convertRealToRaster(double coord, int dim) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).convertRealToRaster(coord, dim);
+	}
+
+	/** @see WritableGrid#dispose() */
+	public void dispose() {
+		if (baseObject != null)
+			((WritableGrid) baseObject).dispose();
+	}
+
+	public Object getGridSample(double... coord) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getGridSample();
+	}
+
+	public byte getGridSampleAsByte(double... coord) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getGridSampleAsByte(coord);
+	}
+
+	public double getGridSampleAsDouble(double... coord) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getGridSampleAsDouble(coord);
+	}
+
+	public float getGridSampleAsFloat(double... coord) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getGridSampleAsFloat(coord);
+	}
+
+	public int getGridSampleAsInt(double... coord) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getGridSampleAsInt(coord);
+	}
+
+	public long getGridSampleAsLong(double... coord) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getGridSampleAsLong(coord);
+	}
+
+	public short getGridSampleAsShort(double... coord) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getGridSampleAsShort(coord);
+	}
+
+	public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+		return metaData.getCoordinateReferenceSystem();
+	}
+
+	public int getHeight() {
+		return metaData.getHeight();
+	}
+
+	public int getMinX() {
+		return metaData.getMinX();
+
+	}
+
+	public int getMinY() {
+		return metaData.getMinY();
+	}
+
+	public Object getRasterSample(int... cell) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getRasterSample(cell);
+	}
+
+	public byte getRasterSampleAsByte(int... cell) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getRasterSampleAsByte(cell);
+	}
+
+	public double getRasterSampleAsDouble(int... cell) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getRasterSampleAsDouble(cell);
+	}
+
+	public float getRasterSampleAsFloat(int... cell) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getRasterSampleAsFloat(cell);
+	}
+
+	public int getRasterSampleAsInt(int... cell) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getRasterSampleAsInt(cell);
+	}
+
+	public long getRasterSampleAsLong(int... cell) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getRasterSampleAsLong(cell);
+	}
+
+	public short getRasterSampleAsShort(int... cell) {
+		if (!loaded)
+			tryLoadingGrid();
+		return ((WritableGrid) baseObject).getRasterSampleAsShort(cell);
+	}
+
+	public double getRealHeight() {
+		return metaData.getRealHeight();
+	}
+
+	public double getRealWidth() {
+		return metaData.getRealWidth();
+	}
+
+	public int getSampleType() {
+		return metaData.getDataType();
+	}
+
+	/** Returns the Width of the Grid */
+	public int getWidth() {
+		return metaData.getWidth();
+	}
+
+	public double getX() {
+		return metaData.getX();
+	}
+
+	public double getY() {
+		return metaData.getY();
+	}
+
+	public void setGridSample(Object value, double... coord) {
+		if (!loaded)
+			tryLoadingGrid();
+		((WritableGrid) baseObject).setGridSample(value, coord);
+	}
+
+	public void setRasterSample(Object value, int... cell) {
+		if (!loaded)
+			tryLoadingGrid();
+		((WritableGrid) baseObject).setRasterSample(value, cell);
+
+	}
+
+	/**
+	 * Trys to load the grid and gives out an error to the LOG, if the loading
+	 * fails.
+	 */
+	protected void tryLoadingGrid() {
+		try {
+			super.loadData();
+		} catch (LoadingException e) {
+			LOG.error("Error while Loading Grid " + this + " from Source "
+					+ e.getLoadSource());
+			e.printStackTrace();
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see schmitzm.data.WritableGrid#getCellHeight()
+	 */
+	public double getCellHeight() {
+		// TODO Auto-generated method stub
+		return metaData.getCellHeight();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see schmitzm.data.WritableGrid#getCellWidth()
+	 */
+	public double getCellWidth() {
+		// TODO Auto-generated method stub
+		return metaData.getCellWidth();
+	}
+
+	/**
+	 * This class supports late loading
+	 * 
+	 * @see appl.data.LateLoadable#unloadData()
+	 * @return true;
+	 * @see appl.data.LateLoadable#isLateLoadable()
+	 */
+	public boolean isLateLoadable() {
+		return true;
+	}
+}

Added: trunk/src/appl/data/package.html
===================================================================
--- trunk/src/appl/data/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/data/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,8 @@
+<html>
+<body>
+	This package contains files responsible for data handling. It contains several loader
+	and unloader classes. Important and frequently used classes are the WritableGridLLProxy
+	and the LateLoadingProxy. Thease classes are responsible for the late loading functionality
+	in Xulu.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/ext/ConfigurationEditor.java
===================================================================
--- trunk/src/appl/ext/ConfigurationEditor.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/ext/ConfigurationEditor.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,62 @@
+package appl.ext;
+
+import javax.swing.SwingUtilities;
+import java.awt.BorderLayout;
+import javax.swing.JPanel;
+import javax.swing.JFrame;
+import javax.swing.WindowConstants;
+import java.awt.Dimension;
+
+/**
+ * Displays the {@link XuluConfig} in a frame based using the
+ * {@link ConfigurationEditorEngine}. This class is independent of Xulu and may
+ * be used separately.
+ * 
+ * @author Dominik Appl
+ */
+public class ConfigurationEditor extends JFrame {
+
+	private static final long serialVersionUID = 1L;
+
+	private JPanel jContentPane = null;
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		// TODO Auto-generated method stub
+		SwingUtilities.invokeLater(new Runnable() {
+			public void run() {
+				ConfigurationEditor thisClass = new ConfigurationEditor();
+				thisClass.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+				thisClass.setVisible(true);
+			}
+		});
+	}
+
+	/**
+	 * This is the default constructor
+	 */
+	public ConfigurationEditor() {
+		super();
+		initialize();
+	}
+
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		this.setSize(621, 445);
+		this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+		this.setContentPane(new ConfigurationEditorEngine().getGUI());
+		this.setTitle("Xulu Configuration Editor");
+	}
+
+	public void dispose() {
+		XuluConfig.getXuluConfig().store();
+		System.exit(0);
+	}
+
+} // @jve:decl-index=0:visual-constraint="10,10"

Added: trunk/src/appl/ext/ConfigurationEditorEngine.java
===================================================================
--- trunk/src/appl/ext/ConfigurationEditorEngine.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/ext/ConfigurationEditorEngine.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,215 @@
+package appl.ext;
+
+import java.awt.Component;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JTable;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableModel;
+
+import appl.util.NonEditableTableModel;
+
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.gui.XuluInternalFrame;
+import edu.bonn.xulu.plugin.appl.AbstractMenuPlugin;
+
+/**
+ * Handles the {@link ConfigurationEditorGUI}. The prefixes of the
+ * {@link XuluConfig} are added to the {@link JList} and the suffixes to the
+ * {@link JTable}. For the documentation column for every key with a name lets
+ * say 'key' the value of "key.doc" is looked up in the configuration. The
+ * prefixes which are values of the key "Filter.prefixes" in the
+ * configuration are ignored. Also all keys which show up in "Filter.keys"
+ * 
+ * @see XuluConfig
+ * @author Dominik Appl
+ */
+public class ConfigurationEditorEngine implements ListSelectionListener,
+		TableModelListener {
+
+	ConfigurationEditorGUI GUI = null;
+
+	private DefaultTableModel tableModel;
+
+	private JTable entryTable;
+
+	private JList categoryList;
+
+	private XuluConfig config;
+
+	private String currentCategory;
+
+	/**
+	 * creates a new Editor. Use {@link #getGUI()} to access the GUI.
+	 */
+	public ConfigurationEditorEngine() {
+		config = XuluConfig.getXuluConfig();
+		GUI = new ConfigurationEditorGUI();
+		initGUI();
+	}
+
+	/**
+	 * inits the GUI
+	 */
+	private void initGUI() {
+
+		entryTable = GUI.entryTable;
+		categoryList = GUI.keyList;
+		initList();
+		initTable();
+	}
+
+	/**
+	 * initializes the table
+	 */
+	private void initTable() {
+		// only the 2nd column is editable
+		tableModel = new NonEditableTableModel(
+				new Object[] { "Name", "Entry" },
+				new boolean[] { false, true }, 0);
+		entryTable.setModel(tableModel);
+		entryTable.setDefaultRenderer(Object.class, new ToolTipRenderer());
+		entryTable.getModel().addTableModelListener(this);
+		entryTable.getSelectionModel().addListSelectionListener(this);
+		String firstElement = (String) categoryList.getModel().getElementAt(0);
+		if (firstElement != null)
+			initTableData(firstElement);
+	}
+
+	/**
+	 * The table is initalized with the given category
+	 * 
+	 * @param firstElement
+	 */
+	private void initTableData(String categoryName) {
+		// get ignored keys
+		String[] filteredKeys = config.getMultiProperty("Filter.keys");
+		Vector<String> filter = new Vector<String>();
+		for (String string : filteredKeys) {
+			filter.add(string);
+		}
+		Set<String> suffixes = config.getSuffixesOfPrefix(categoryName);
+		// clear table
+		tableModel.setRowCount(0);
+		for (String suffix : suffixes) {
+			// do not enter the documentation as seperate entries
+			if (suffix.endsWith(".doc"))
+				continue;
+			String key = categoryName + "." + suffix;
+			// do not enter filtered keys
+			if (filter.contains(key))
+				continue;
+			String value = config.getProperty(key);
+			tableModel.addRow(new Object[] { suffix, value });
+		}
+		currentCategory = categoryName;
+	}
+
+	public ConfigurationEditorGUI getGUI() {
+		return GUI;
+	}
+
+	/**
+	 * 
+	 */
+	private void initList() {
+		// get ignored prefixes
+		String[] filteredPrefixes = config.getMultiProperty("Filter.prefixes");
+		Vector<String> filter = new Vector<String>();
+		for (String string : filteredPrefixes) {
+			filter.add(string);
+		}
+		DefaultListModel listModel = new DefaultListModel();
+		Object[] prefixes = config.getPrefixes().toArray();
+		for (Object object : prefixes) {
+			if (!filter.contains(object))
+				listModel.addElement(object);
+		}
+		this.GUI.keyList.setModel(listModel);
+		// select first element
+		categoryList.setSelectedIndex(0);
+		categoryList.addListSelectionListener(this);
+	}
+
+	/**
+	 * Listens for selection changes in list and table
+	 * 
+	 * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
+	 */
+	public void valueChanged(ListSelectionEvent e) {
+		if (e.getSource() == categoryList) {
+			String value = (String) categoryList.getSelectedValue();
+			if (value != null)
+				initTableData(value);
+			// clear documentation field
+			GUI.docArea
+					.setText("<select a table value to see its documentation>");
+		}
+		// update documentation
+		else if (e.getSource() == entryTable.getSelectionModel()) {
+			int selRow = entryTable.getSelectedRow();
+			// if a row is selected:
+			if (selRow >= 0) {
+				String value = (String) entryTable.getModel().getValueAt(
+						selRow, 0);
+				String docKey = currentCategory + "." + value + ".doc";
+				String doc = config.getProperty(docKey);
+				if (doc == null)
+					doc = "<no documentation found for this entry>";
+				GUI.docArea.setText(doc);
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.swing.event.TableModelListener#tableChanged(javax.swing.event.TableModelEvent)
+	 */
+	public void tableChanged(TableModelEvent e) {
+		// handle the editing the user does
+		if (e.getType() == TableModelEvent.UPDATE) {
+			int changedRow = e.getFirstRow();
+			// only the 2nd col is editable
+			String value = tableModel.getValueAt(changedRow, 1).toString();
+			String suffix = tableModel.getValueAt(changedRow, 0).toString();
+			String prefix = categoryList.getSelectedValue().toString();
+			String key = prefix + "." + suffix;
+			config.setProperty(key, value);
+
+		}
+	}
+
+	/**
+	 * just for the tooltips
+	 * 
+	 * @author Dominik Appl
+	 */
+	private class ToolTipRenderer extends DefaultTableCellRenderer {
+
+		public ToolTipRenderer() {
+			setOpaque(true);
+		}
+
+		public Component getTableCellRendererComponent(JTable table,
+				Object color, boolean isSelected, boolean hasFocus, int row,
+				int column) {
+			Object value = table.getModel().getValueAt(row, column);
+			if (value != null)
+				setToolTipText(value.toString());
+			return super.getTableCellRendererComponent(table, color,
+					isSelected, hasFocus, row, column);
+		}
+
+	}
+}
\ No newline at end of file

Added: trunk/src/appl/ext/ConfigurationEditorGUI.java
===================================================================
--- trunk/src/appl/ext/ConfigurationEditorGUI.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/ext/ConfigurationEditorGUI.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,272 @@
+package appl.ext;
+
+import java.awt.BorderLayout;
+import javax.swing.JPanel;
+import javax.swing.JFrame;
+import java.awt.Dimension;
+import javax.swing.JList;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.BoxLayout;
+
+import edu.bonn.xulu.gui.XuluInternalFrame;
+
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import javax.swing.ListSelectionModel;
+import javax.swing.JLabel;
+import javax.swing.border.SoftBevelBorder;
+import javax.swing.BorderFactory;
+import javax.swing.border.BevelBorder;
+import javax.swing.JTextField;
+import javax.swing.JTextArea;
+import javax.swing.SwingConstants;
+
+/**
+ * Displays the properties of {@link XuluConfig}. The interesting stuff happens
+ * in {@link ConfigurationEditorEngine}.
+ * 
+ * @see XuluConfig
+ * @see ConfigurationEditorEngine
+ * @author Dominik Appl
+ */
+public class ConfigurationEditorGUI extends JPanel {
+
+	private static final long serialVersionUID = 1L;
+
+	JList keyList = null;
+
+	JScrollPane scrollPane = null;
+
+	JTable entryTable = null;
+
+	private JPanel jPanel = null;
+
+	private JPanel jPanel1 = null;
+
+	private JLabel jLabel = null;
+
+	private JScrollPane jScrollPane = null;
+
+	JTextArea docArea = null;
+
+	private JLabel jLabel1 = null;
+
+	private JPanel jPanel2 = null;
+
+	/**
+	 * This is the default constructor
+	 */
+	public ConfigurationEditorGUI() {
+		super();
+		initialize();
+	}
+
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
+		gridBagConstraints4.insets = new Insets(0, 0, 0, 0);
+		gridBagConstraints4.gridy = 0;
+		gridBagConstraints4.ipady = 0;
+		gridBagConstraints4.gridwidth = 1;
+		gridBagConstraints4.weightx = 1.0;
+		gridBagConstraints4.weighty = 1.0;
+		gridBagConstraints4.fill = GridBagConstraints.BOTH;
+		gridBagConstraints4.ipadx = 0;
+		gridBagConstraints4.gridx = 1;
+		GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
+		gridBagConstraints3.gridx = 0;
+		gridBagConstraints3.ipadx = 135;
+		gridBagConstraints3.ipady = 0;
+		gridBagConstraints3.anchor = GridBagConstraints.WEST;
+		gridBagConstraints3.fill = GridBagConstraints.VERTICAL;
+		gridBagConstraints3.gridheight = 1;
+		gridBagConstraints3.gridwidth = 1;
+		gridBagConstraints3.weightx = 0.0;
+		gridBagConstraints3.weighty = 1.0;
+		gridBagConstraints3.gridy = 0;
+		this.setLayout(new GridBagLayout());
+		this.setSize(682, 239);
+		this.add(getJPanel(), gridBagConstraints3);
+		this.add(getJPanel1(), gridBagConstraints4);
+	}
+
+	/**
+	 * This method initializes keyList
+	 * 
+	 * @return javax.swing.JList
+	 */
+	private JList getKeyList() {
+		if (keyList == null) {
+			keyList = new JList();
+			keyList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		}
+		return keyList;
+	}
+
+	/**
+	 * This method initializes scrollPane
+	 * 
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getScrollPane() {
+		if (scrollPane == null) {
+			scrollPane = new JScrollPane();
+			scrollPane.setViewportView(getEntryTable());
+		}
+		return scrollPane;
+	}
+
+	/**
+	 * This method initializes entryTable
+	 * 
+	 * @return javax.swing.JTable
+	 */
+	private JTable getEntryTable() {
+		if (entryTable == null) {
+			entryTable = new JTable();
+		}
+		return entryTable;
+	}
+
+	/**
+	 * This method initializes jPanel
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
+			gridBagConstraints2.fill = GridBagConstraints.BOTH;
+			gridBagConstraints2.gridy = 1;
+			gridBagConstraints2.ipadx = 0;
+			gridBagConstraints2.ipady = 0;
+			gridBagConstraints2.weightx = 1.0;
+			gridBagConstraints2.weighty = 1.0;
+			gridBagConstraints2.insets = new Insets(0, 10, 10, 10);
+			gridBagConstraints2.gridx = 0;
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.insets = new Insets(5, 0, 5, 0);
+			gridBagConstraints.gridy = 0;
+			gridBagConstraints.gridx = 0;
+			jLabel = new JLabel();
+			jLabel.setText("Category:");
+			jPanel = new JPanel();
+			jPanel.setLayout(new GridBagLayout());
+			jPanel.add(jLabel, gridBagConstraints);
+			jPanel.add(getJScrollPane(), gridBagConstraints2);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes jPanel1
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJPanel1() {
+		if (jPanel1 == null) {
+			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
+			gridBagConstraints8.insets = new Insets(0, 0, 1, 0);
+			gridBagConstraints8.gridy = 1;
+			gridBagConstraints8.ipadx = 419;
+			gridBagConstraints8.ipady = 0;
+			gridBagConstraints8.fill = GridBagConstraints.NONE;
+			gridBagConstraints8.gridx = 0;
+			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
+			gridBagConstraints7.fill = GridBagConstraints.BOTH;
+			gridBagConstraints7.gridy = 0;
+			gridBagConstraints7.ipadx = 55;
+			gridBagConstraints7.ipady = 0;
+			gridBagConstraints7.weightx = 1.0;
+			gridBagConstraints7.weighty = 1.0;
+			gridBagConstraints7.insets = new Insets(25, 0, 0, 10);
+			gridBagConstraints7.gridx = 0;
+			jLabel1 = new JLabel();
+			jLabel1.setText("Documentation:");
+			jLabel1.setVerticalAlignment(SwingConstants.TOP);
+			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+			gridBagConstraints1.anchor = GridBagConstraints.EAST;
+			gridBagConstraints1.insets = new Insets(0, 150, 0, 0);
+			gridBagConstraints1.gridx = -1;
+			gridBagConstraints1.gridy = -1;
+			gridBagConstraints1.ipady = 0;
+			gridBagConstraints1.weightx = 1.0;
+			gridBagConstraints1.weighty = 1.0;
+			gridBagConstraints1.fill = GridBagConstraints.BOTH;
+			jPanel1 = new JPanel();
+			jPanel1.setLayout(new GridBagLayout());
+			jPanel1.add(getScrollPane(), gridBagConstraints7);
+			jPanel1.add(getJPanel2(), gridBagConstraints8);
+		}
+		return jPanel1;
+	}
+
+	/**
+	 * This method initializes jScrollPane
+	 * 
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setPreferredSize(new Dimension(100, 100));
+			jScrollPane.setViewportView(getKeyList());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes docArea
+	 * 
+	 * @return javax.swing.JTextArea
+	 */
+	private JTextArea getDocArea() {
+		if (docArea == null) {
+			docArea = new JTextArea();
+			docArea.setPreferredSize(new Dimension(0, 50));
+			docArea.setText("<select a value to see its documentation>");
+			docArea.setRows(2);
+			docArea.setLineWrap(true);
+			docArea.setEditable(false);
+		}
+		return docArea;
+	}
+
+	/**
+	 * This method initializes jPanel2
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJPanel2() {
+		if (jPanel2 == null) {
+			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
+			gridBagConstraints6.fill = GridBagConstraints.HORIZONTAL;
+			gridBagConstraints6.gridy = 1;
+			gridBagConstraints6.ipadx = 0;
+			gridBagConstraints6.ipady = 21;
+			gridBagConstraints6.weightx = 1.0;
+			gridBagConstraints6.weighty = 1.0;
+			gridBagConstraints6.insets = new Insets(0, 0, 10, 10);
+			gridBagConstraints6.gridx = 1;
+			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
+			gridBagConstraints5.insets = new Insets(0, 0, 0, 0);
+			gridBagConstraints5.gridy = 0;
+			gridBagConstraints5.anchor = GridBagConstraints.WEST;
+			gridBagConstraints5.gridx = 1;
+			jPanel2 = new JPanel();
+			jPanel2.setLayout(new GridBagLayout());
+			jPanel2.add(jLabel1, gridBagConstraints5);
+			jPanel2.add(getDocArea(), gridBagConstraints6);
+		}
+		return jPanel2;
+	}
+
+} // @jve:decl-index=0:visual-constraint="10,10"

Added: trunk/src/appl/ext/ConfigurationEditorPlugin.java
===================================================================
--- trunk/src/appl/ext/ConfigurationEditorPlugin.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/ext/ConfigurationEditorPlugin.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,41 @@
+package appl.ext;
+
+import java.util.ResourceBundle;
+
+import appl.util.XuluFrameAdapter;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.gui.XuluInternalFrame;
+import edu.bonn.xulu.plugin.appl.AbstractMenuPlugin;
+import static edu.bonn.xulu.appl.XuluConstants.XULUGUI_RES;
+/**
+ * The configuration plug-in.
+ *
+ * @see XuluConfig
+ * @see ConfigurationEditorGUI
+ * @see ConfigurationEditorEngine
+ * @author Dominik Appl
+ */
+public class ConfigurationEditorPlugin extends AbstractMenuPlugin {
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see edu.bonn.xulu.plugin.appl.AbstractMenuPlugin#createPluginApplication()
+	 */
+
+	@Override
+	protected XuluInternalFrame createPluginApplication() throws Exception {
+		ConfigurationEditorGUI GUI = new ConfigurationEditorEngine().getGUI();
+		return new XuluFrameAdapter(XULUGUI_RES
+				.getString("Menu_Advanced_Preferences"), GUI);
+	}
+
+	/**
+	 *
+	 */
+	public ConfigurationEditorPlugin() {
+		super(4, XULUGUI_RES.getString("Menu_Advanced_Preferences"));
+
+	}
+
+}

Added: trunk/src/appl/ext/XuluConfig.java
===================================================================
--- trunk/src/appl/ext/XuluConfig.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/ext/XuluConfig.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,446 @@
+package appl.ext;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.geotools.io.DefaultFileFilter;
+
+/**
+ * Simple Property store, which is loaded at each Xulu start and saved at each
+ * Xulu exit. Every class or plugin can store and retrieve configuration
+ * information easy through a static method. To keep the property file readable
+ * and to avoid conflicts with other plugins please prefix the key-name with a
+ * unique name, which identifies your class, followed by a dot and the property.
+ * This is important for correct display in a User-GUI (which could be
+ * implemented). <br>
+ * <br>
+ * Keyformat: <code>domain.property</code> <br>
+ * Example key: <code>DiscoveryService.className</code> <br>
+ * <br>
+ * There could be no double entries.But you can save multiple values to one key
+ * using the {@link #setMultiProperty(String, String[]) setMultiProperty}
+ * method. <br>
+ * <b>These values are internally separated with ';', so see that you don't use
+ * ';' in your values of {@link #setMultiProperty(String, String[]) Multi
+ * Properties}</b> <br>
+ * <br>
+ * First the settings of the file "DefaultProperties" are loaded. After that the
+ * values are possibly overwritten by the loading of the file "XuluProperties"
+ * in which is intended to store a actual user configuration.
+ * <b>"DefaultPropoerties" should never be modified by the user.</b> The
+ * programmer should store all default values there. <br>
+ * <br>
+ * The user may change values through the {@link ConfigurationEditorGUI}.
+ *
+ * @see ConfigurationEditorGUI
+ * @see ConfigurationEditorEngine
+ * @author Dominik Appl
+ */
+public class XuluConfig {
+
+	private final String delimiter = ";";
+
+	// File for default values
+	File defaultFile = new File("DefaultProperties");
+
+	// File in which the props are stored
+	File file = new File("XuluProperties");
+
+	Properties propStore = null;
+
+	private static XuluConfig instance = null;
+
+        private XuluConfig() {
+          this(null);
+        }
+
+	private XuluConfig(File rootDir) {
+                if ( rootDir != null && rootDir.isDirectory() ) {
+                  defaultFile = new File(rootDir, defaultFile.getName());
+                  file        = new File(rootDir, file.getName());
+                }
+		// try to read defaults
+		Properties defaults = new Properties();
+		try {
+			defaults.load(new FileInputStream(defaultFile));
+		} catch (Exception e) {
+			System.out
+					.println("Warning: defaults could not be loaded from file '"
+							+ defaultFile + "'");
+			System.out.println(e.getMessage());
+		}
+		propStore = new Properties(defaults);
+		if (file.exists())
+			load();
+		else
+			store();
+	}
+
+        public static XuluConfig getXuluConfig() {
+          return getXuluConfig(null);
+        }
+
+	public static XuluConfig getXuluConfig(File rootDir) {
+		if (instance == null)
+			instance = new XuluConfig(rootDir);
+		return instance;
+	}
+
+	/**
+	 * Saves the configuration to the file system
+	 */
+	public void store() {
+		try {
+			propStore.store(new FileOutputStream(file),
+					"Stored properties of the Xulu modelling platform");
+		} catch (FileNotFoundException e) {
+			System.err.println("Could not write PropertyStore!!!");
+			e.printStackTrace();
+		} catch (IOException e) {
+			System.err.println("Could not write PropertyStore!!!");
+			e.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * Sets the Property file. Notice that this has only an effect if you call
+	 * load afterwards.
+	 *
+	 * @param file
+	 */
+	public void setPropertyFile(File file) {
+		this.file = file;
+	}
+
+	/**
+	 * loads the Properties from the Propertyfile. No loaded values are deleted -
+	 * only existing ones are overwritten;
+	 */
+	public void load() {
+		try {
+			propStore.load(new FileInputStream(file));
+		} catch (FileNotFoundException e) {
+			System.err.println("Property file with name '" + file
+					+ "' not found");
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * inserts the property value with the specified key into the
+	 * {@link XuluConfig}
+	 *
+	 * @param key
+	 *            the key
+	 * @param value
+	 *            the value associated with the key
+	 */
+	public void setProperty(String key, String value) {
+		if (!key.contains("."))
+			System.out
+					.println("WARNING for key "
+							+ key
+							+ ": Propertykeys in XuluConfig should have at least one '.' ! ");
+		propStore.setProperty(key, value);
+	}
+
+	/***************************************************************************
+	 * @return the property associated with the provided key. If not found the
+	 *         defaults are searched. If still not found, null is returned.
+	 *         Gives out a warning to console if the key was not found
+	 **************************************************************************/
+	public String getProperty(String key) {
+		String value = propStore.getProperty(key);
+		if (value == null)
+			System.err.println("Warning! Value for property '" + key
+					+ "' was not found in property file!");
+		return value;
+	}
+
+	/***************************************************************************
+	 * Same as {@link #getProperty(String)}, but you can disable the warning
+	 * message
+	 *
+	 * @param giveWarning
+	 *            if true, a warning is given to the console if the specified
+	 *            entry was not found
+	 * @return the property associated with the provided key. If not found the
+	 *         defaults are searched. If still not found, null is returned.
+	 *         Gives out a warning to console if the key was not found
+	 **************************************************************************/
+	public String getProperty(String key, boolean giveWarning) {
+		String value = propStore.getProperty(key);
+		if (value == null && giveWarning)
+			System.err.println("Warning! Value for property '" + key
+					+ "' was not found in property file!");
+		return value;
+	}
+
+	/***************************************************************************
+	 *
+	 * @return the property associated with the provided key as integer value.
+	 *         If not found the defaults are searched. If not found or the value
+	 *         is in a wrong format 0 is returned and a warning is given to the
+	 *         console
+	 **************************************************************************/
+	public int getIntProperty(String key) {
+		String value = propStore.getProperty(key);
+		if (value == null) {
+			System.err.println("Error! Value for property '" + key
+					+ "' was not found in property file!");
+			return 0;
+		}
+		int returnvalue = 0;
+		try {
+			returnvalue = Integer.valueOf(value);
+		} catch (java.lang.NumberFormatException e) {
+			System.err
+					.println("Error! Value for property '"
+							+ key
+							+ "' was not in the right format. Should be a Integer value! - Returning 0");
+		}
+		return returnvalue;
+	}
+
+	/***************************************************************************
+	 * @return the property associated with the provided key as double value. If
+	 *         not found the defaults are searched. If not found or the value is
+	 *         in a wrong format 0 is returned and a warning is given to the
+	 *         console
+	 **************************************************************************/
+	public double getDoubleProperty(String key) {
+		String value = propStore.getProperty(key);
+		if (value == null) {
+			System.err.println("Error! Value for property '" + key
+					+ "' was not found in property file!");
+			return 0;
+		}
+		double returnvalue = 0;
+		try {
+			returnvalue = Double.valueOf(value);
+		} catch (java.lang.NumberFormatException e) {
+			System.err
+					.println("Error! Value for property '"
+							+ key
+							+ "' was not in the right format. Should be a Integer value! - Returning 0");
+		}
+		return returnvalue;
+	}
+
+	/**
+	 * inserts the property value with the specified key into the
+	 * {@link XuluConfig}
+	 *
+	 * @param key
+	 *            the key
+	 * @param value
+	 *            the value associated with the key
+	 */
+	public void setBooleanProperty(String key, boolean value) {
+		this.setProperty(key, String.valueOf(value));
+	}
+
+	/**
+	 * inserts the property value with the specified key into the
+	 * {@link XuluConfig}
+	 *
+	 * @param key
+	 *            the key
+	 * @param value
+	 *            the value associated with the key
+	 */
+	public void setIntProperty(String key, int value) {
+		this.setProperty(key, String.valueOf(value));
+	}
+
+	/***************************************************************************
+	 * @return the property associated with the provided key as boolean value.
+	 *         If not found the defaults are searched. If still not found or
+	 *         null then false is returned. Gives out a warning to console if
+	 *         the key was not found
+	 **************************************************************************/
+	public boolean getBooleanProperty(String key) {
+		String value = propStore.getProperty(key);
+		if (value == null) {
+			System.err.println("Error! Value for property '" + key
+					+ "' was not found in property file!");
+			return false;
+		}
+		if(value.equals("1"))
+			return true;
+		boolean bool = false;
+		try {
+			bool = Boolean.valueOf(value);
+		} catch (Exception e) {
+			System.err.println("Error! Value for property '" + key
+					+ "' was not a valid boolean value");
+		}
+		return bool;
+	}
+
+	/**
+	 * A multiproperty stores multiple values for one key. These values are
+	 * internaly seperated with spaces, so see that you dont use spaces in your
+	 * values.
+	 *
+	 * @param key
+	 *            the key
+	 * @param values
+	 *            array of the values which should be associated with the key
+	 */
+	public void setMultiProperty(String key, String values[]) {
+		if (!key.contains("."))
+			System.out
+					.println("WARNING for key "
+							+ key
+							+ ": Propertykeys in XuluConfig should have at least one '.' ! ");
+		String value = "";
+		if (values != null)
+			for (String string : values) {
+				value += (string + delimiter);
+			}
+		propStore.setProperty(key, value);
+	}
+
+	/***************************************************************************
+	 * A multiproperty stores multiple values for one key. These values are
+	 * internaly seperated with ';', so do not use ';' in your values. if the
+	 * key was not found it gives out a warning to console and a empty array is
+	 * retured.
+	 *
+	 * @return the multiProperty associated with the provided key, which is in
+	 *         this case just a String array
+	 **************************************************************************/
+
+	public String[] getMultiProperty(String key) {
+		String value = propStore.getProperty(key);
+		if (value != null)
+			return value.split(delimiter);
+		System.err.println("Error! Value for property '" + key
+				+ "' was not found in property file!");
+		return new String[0];
+	}
+
+	/**
+	 * removes the Property from the list
+	 *
+	 * @param key
+	 */
+	public void removeProperty(String key) {
+		propStore.remove(key);
+	}
+
+	/**
+	 * removes all keys starting with the value given. USE WITH CAUTION! If you
+	 * give a String "a" all entrys starting with "a" will be removed from the
+	 * registry
+	 *
+	 * @param key
+	 */
+	public void removeAll(String key) {
+		if (key == null)
+			return;
+
+		Enumeration keys = propStore.propertyNames();
+		while (keys.hasMoreElements()) {
+			String propKey = (String) keys.nextElement();
+			if (propKey == null)
+				continue;
+			if (propKey.startsWith(key))
+				propStore.remove(propKey);
+		}
+	}
+
+	/**
+	 * Gets all prefixes. A Prefix is the string of all characters up to the
+	 * first dot. A Suffix is the string of all characters following this dot.
+	 *
+	 * @return the prefixes
+	 *
+	 */
+	public Set<String> getPrefixes() {
+		TreeSet set = new TreeSet();
+		Enumeration keys = propStore.propertyNames();
+		while (keys.hasMoreElements()) {
+			String propKey = (String) keys.nextElement();
+			String[] strings = propKey.split("\\.");
+			set.add(strings[0]);
+		}
+		return set;
+	}
+
+	/**
+	 * Gets all suffixes for one prefix. A Prefix is the string of all
+	 * characters up to the first dot. A Suffix is the string of all characters
+	 * following this dot. The Strings are ordered alphabeticly
+	 *
+	 * @param prefix
+	 *            the prefix.
+	 */
+	public Set<String> getSuffixesOfPrefix(String prefix) {
+		TreeSet set = new TreeSet();
+		Enumeration keys = propStore.propertyNames();
+		while (keys.hasMoreElements()) {
+			String propKey = (String) keys.nextElement();
+			String[] strings = propKey.split("\\.");
+			if (strings.length > 1 && strings[0].equals(prefix))
+				set.add(propKey.substring(strings[0].length() + 1));
+		}
+		return set;
+	}
+
+	/**
+	 * Gets all entries starting with the given {@link String}
+	 *
+	 * @param startingString
+	 *            the prefixstring
+	 * @return all keys starting the given prefix
+	 */
+	public Set<String> getKeysStartingWith(String startingString) {
+		TreeSet set = new TreeSet();
+		Enumeration keys = propStore.propertyNames();
+		while (keys.hasMoreElements()) {
+			String propKey = (String) keys.nextElement();
+			if (propKey.startsWith(startingString))
+				set.add(propKey);
+		}
+		return set;
+	}
+
+	/**
+	 * Just for testing.
+	 *
+	 * @deprecated
+	 */
+	public static void main(String[] args) {
+		XuluConfig config = XuluConfig.getXuluConfig();
+		config.setProperty("atest2", "test3");
+		config.setProperty("test4.testproperty", "test");
+		String[] multiTest = { "value1", "value2", "value3" };
+		config.setMultiProperty("multiproperty.1", multiTest);
+		String[] multioutput = config.getMultiProperty("multiproperty.1");
+		for (String string : multioutput) {
+			System.out.println("Multivalue: " + string);
+		}
+		config.store();
+		config.setPropertyFile(new File("XuluTestfile"));
+		config.load();
+		String[] multiTest2 = { "value1", "value2", "value3" };
+		config.setMultiProperty("multiproperty.2", multiTest);
+		config.removeAll("multiproperty");
+		config.removeProperty("atest2");
+		config.store();
+	}
+}

Added: trunk/src/appl/ext/package.html
===================================================================
--- trunk/src/appl/ext/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/ext/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,6 @@
+<html>
+<body>
+	At the moment this classes contains only classes related to the Configuration Editor in Xulu. 
+	Beside the plugin functionality in the ConfigurationEditorPlugin-class it is independent of Xulu itself and may be used in other projects.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/package.html
===================================================================
--- trunk/src/appl/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,8 @@
+<html>
+<body>
+	In diesem Paket können sämtliche benutzerdefinierten Komponenten für die
+	Xulu-Modelling-Platform implementiert werden.
+	z.B. Benutzerdefinierte Datentypen in {@link edu.bonn.xulu.plugin.data edu.bonn.xulu.plugin.data}
+	und die dazugehörigen Factorys in {@link edu.bonn.xulu.plugin.data edu.bonn.xulu.plugin.io}.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/ComputingResource.java
===================================================================
--- trunk/src/appl/parallel/ComputingResource.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/ComputingResource.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,64 @@
+package appl.parallel;
+
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.Vector;
+
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.gui.ModelControlFrame;
+
+import appl.parallel.spmd.SPMDTask;
+import appl.parallel.spmd.split.SinglePartitionInfo;
+import appl.parallel.spmd.split.SplitMap;
+import appl.parallel.spmd.split.SplittableResource;
+
+/**
+ * This is the base class for remote computing resources, which could be
+ * displayed e.g. in the {@link ModelControlFrame} of the
+ * {@link XuluModellingPlatform}. It provides very basic functionality like
+ * connecting, disconnecting or pinging. Also it provides a flag saying if the
+ * resource is available for computation (or e.g. in use).
+ *
+ * @author Dominik Appl
+ */
+public interface ComputingResource extends java.rmi.Remote {
+
+	/**
+	 * Should return Information about the ComputingResource. This Information
+	 * is primary used to display infos to the user.
+	 */
+	public ComputingResourceProperties getResourceInformation()
+			throws RemoteException;
+
+	/**
+	 * Can be used to ping the object
+	 *
+	 * @param o
+	 *            the object to ping with
+	 * @return the same object
+	 * @throws RemoteException
+	 */
+	public Object ping(Object... o) throws RemoteException;
+
+	/**
+	 * tries to connect to the resource
+	 *
+	 * @return true for success
+	 * @throws RemoteException
+	 */
+	public boolean connect() throws RemoteException;
+
+	/**
+	 * disconnects from the resource
+	 *
+	 * @throws RemoteException
+	 */
+	public void disconnect() throws RemoteException;
+
+	/**
+	 * @return true, if the resource is available for computation (may return
+	 *         false, if the resource is used by another client)
+	 * @throws RemoteException
+	 */
+	public boolean isAvailable() throws RemoteException;
+}

Added: trunk/src/appl/parallel/ComputingResourceContainer.java
===================================================================
--- trunk/src/appl/parallel/ComputingResourceContainer.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/ComputingResourceContainer.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,53 @@
+package appl.parallel;
+
+
+/**
+ * Encapsulates {@link ComputingResource ComputingResources} and their meta
+ * Information (for fast access)
+ *
+ * @author Dominik Appl
+ */
+public class ComputingResourceContainer {
+
+	private final ComputingResource resource;
+
+	private final ComputingResourceProperties information;
+
+	private boolean supportsSimpleRemoteExecution = false;
+
+	/**
+	 * @param resource
+	 * @param information
+	 */
+	public ComputingResourceContainer(ComputingResource resource,
+			ComputingResourceProperties information) {
+		this.resource = resource;
+		this.information = information;
+	}
+
+	/**
+	 * @return the information
+	 */
+	public ComputingResourceProperties getInformation() {
+		return information;
+	}
+
+	/**
+	 * @return the resource
+	 */
+	public ComputingResource getResource() {
+		return resource;
+	}
+
+	public String toString() {
+		if (information != null)
+			return information.getProperty("Name");
+		else
+			return "Unknown Resource(No Information available)";
+	}
+
+	public boolean supportsSimpleRemoteExecution() {
+		return supportsSimpleRemoteExecution;
+	}
+
+}

Added: trunk/src/appl/parallel/ComputingResourceProperties.java
===================================================================
--- trunk/src/appl/parallel/ComputingResourceProperties.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/ComputingResourceProperties.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,62 @@
+package appl.parallel;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+/**
+ * Information about a {@link ComputingResource}. All entries may return
+ * <code>null</code> if no information is available. Notice that the 
+ * information represents the state of the remote Object at the time it was
+ * created. So it may be outdated. The following Properties should be available
+ * on all systems <br>
+ * <ul>
+ * <li>ActiveModel</li>
+ * <li>isAvailable - says if the resource is currently available for use</li>
+ * <li>SystemInformation - Identifies the current System/OS</li>
+ * <li>Name - a name which will be displayed to the user</li>
+ * <li>IP - the IP address of the Object<br>
+ * </li>
+ * </ul>
+ * <br>
+ * 
+ * @author Dominik Appl
+ */
+public interface ComputingResourceProperties extends Serializable {
+
+	Properties getProperties();
+
+	/**
+	 * Sets a property
+	 * @param key the key
+	 * @param value the value
+	 */
+	public void setProperty(String key, String value);
+
+	/**
+	 * 
+	 * @param key the key
+	 * @return the property property associated with that key or null if not found
+	 */
+	public String getProperty(String key);
+
+	/**
+	 * @return the name of the resource (usually the hostname)
+	 */
+	public String getName();
+
+	/**
+	 * @return says if the resource is available for computation (of in use).
+	 */
+	public boolean isAvailable();
+
+	/**
+	 * @return the ip of the resource
+	 */
+	public String getIP();
+
+	/**
+	 * @return port the resouce is bound to
+	 */
+	public String getPort();
+
+}

Added: trunk/src/appl/parallel/SimpleResourceProperties.java
===================================================================
--- trunk/src/appl/parallel/SimpleResourceProperties.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/SimpleResourceProperties.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,134 @@
+package appl.parallel;
+
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryUsage;
+import java.lang.management.ThreadMXBean;
+import java.net.UnknownHostException;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * Sets the following properties: <br>
+ * <br>
+ * Maximum Java Memory <br>
+ * Free Java Memory<br>
+ * System Information<br>
+ * System Architecture<br>
+ * System Version<br>
+ * Hostname<br>
+ * IP<br>
+ * 
+ * @see ComputingResourceProperties
+ * @author Dominik Appl
+ */
+public class SimpleResourceProperties implements ComputingResourceProperties,
+		Serializable {
+
+	protected Properties properties = new Properties();
+
+	public SimpleResourceProperties() {
+		java.net.InetAddress i;
+		try {
+			i = java.net.InetAddress.getLocalHost();
+			properties.setProperty("Hostname", i.getHostName());
+
+			// also the DefaultName of the machine, if not specified
+			properties.setProperty("Name", i.getHostName());
+			properties.setProperty("IP", i.getHostAddress());
+		} catch (UnknownHostException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		properties.setProperty("Memory Maximum", ""
+				+ getFormatedMemoryString(Runtime.getRuntime().maxMemory()));
+		properties.setProperty("Memory Free", ""
+				+ getFormatedMemoryString(Runtime.getRuntime().freeMemory()));
+		properties.setProperty("Memory Used", ""
+				+ getFormatedMemoryString(getUsedMemory()));
+		properties.setProperty("Operating System", System
+				.getProperty("os.name"));
+		properties.setProperty("System Architecture", System
+				.getProperty("os.arch"));
+		properties.setProperty("System Version", System
+				.getProperty("os.version"));
+		properties.setProperty("Available Processors", Runtime.getRuntime()
+				.availableProcessors()
+				+ "");
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.ComputingResourceProperties#getProperties()
+	 */
+	public Properties getProperties() {
+		return properties;
+	}
+
+	protected long getUsedMemory() {
+		ThreadMXBean tb = ManagementFactory.getThreadMXBean();
+		List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
+		long sum = 0;
+		for (MemoryPoolMXBean pool : pools) {
+			MemoryUsage peak = pool.getPeakUsage();
+			sum += peak.getUsed();
+		}
+		return sum;
+	}
+
+	protected String getFormatedMemoryString(long bytes) {
+		long mb = bytes / (1024 * 1024);
+		long kb = bytes / 1024 - (mb * 1024);
+		// only the first char of kb
+		kb = kb / 100;
+		return mb + "." + kb + " MB";
+
+	}
+
+	/*
+	 * (non-Javadoc) only indirection
+	 * 
+	 * @see appl.parallel.ComputingResourceProperties#getProperty(java.lang.String)
+	 */
+	public String getProperty(String key) {
+		return properties.getProperty(key);
+	}
+
+	/*
+	 * (non-Javadoc) only indirection
+	 * 
+	 * @see appl.parallel.ComputingResourceProperties#setProperty(java.lang.String,
+	 *      java.lang.String)
+	 */
+	public void setProperty(String key, String value) {
+		properties.setProperty(key, value);
+	}
+
+	public String toString() {
+		return getProperty("Name");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.ComputingResourceProperties#getName()
+	 */
+	public String getName() {
+		return getProperty("Name");
+	}
+
+	public boolean isAvailable() {
+		return getProperty("isAvailable").equals("true");
+	}
+
+	public String getIP() {
+		return getProperty("IP");
+	}
+
+	public String getPort() {
+		return getProperty("Port");
+	}
+}

Added: trunk/src/appl/parallel/client/ClientDataServer.java
===================================================================
--- trunk/src/appl/parallel/client/ClientDataServer.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/client/ClientDataServer.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,200 @@
+package appl.parallel.client;
+
+import java.awt.Rectangle;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.rmi.AccessException;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.ServerNotActiveException;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.ext.XuluConfig;
+import appl.parallel.event.CommEvent;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.event.TransferEvent;
+import appl.parallel.event.CommEvent.CommType;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.util.Helper;
+// fuer Doku
+import javax.activation.DataHandler;
+import appl.parallel.server.PartitionDataServer;
+import appl.parallel.server.XuluServer;
+import appl.parallel.spmd.split.SplittableResource;
+
+/**
+ * This class is used for storing all data which is needed for parallelization
+ * and may be requested remotely. On {@link DataPartition DataPartitions} the
+ * request of partitions is supported. {@link PartitionDataServer}s running on
+ * {@link XuluServer}s will typically use {@link DataHandler DataHandlers} for
+ * retrieving the partitions.
+ *
+ * @see PartitionDataServer
+ * @author Dominik Appl
+ */
+public class ClientDataServer extends UnicastRemoteObject implements DataServer {
+
+	protected final Logger LOG = LogManager
+			.getLogger(this.getClass().getName());
+
+	private final String bindingName = "DataServer";
+
+	// for retrieval with the baseID
+	private Hashtable<Integer, DataPartition> dataByID;
+
+	HashMap<String, String> hostnames = new HashMap<String, String>(10);
+
+	private int registryPort = 1099;
+
+	private final CommEventSink eventSink;
+
+	/**
+	 * The standard Constructor (binds itself to the running registry)
+	 *
+	 * @param eventSink
+	 *            the sink is used for generating events
+	 * @throws RemoteException
+	 *             if the connection fails
+	 */
+	public ClientDataServer(CommEventSink eventSink) throws RemoteException {
+		this.eventSink = eventSink;
+		dataByID = new Hashtable<Integer, DataPartition>();
+
+		// bind to the registry - create a new reg, if no reg is found
+		try {
+			// try to get port from registry
+			int port = XuluConfig.getXuluConfig().getIntProperty(
+					"XuluClient.registryport");
+			if (port != 0)
+				registryPort = port;
+			Helper.bind(bindingName, this, registryPort);
+		} catch (Exception e) {
+			LOG.error("Error while binding SPMDClient to the registry."
+					+ e.getMessage());
+		}
+		LOG.info("DataServer up and running....");
+	}
+
+	/**
+	 * Returns the data identified by the given id
+	 *
+	 * @param baseID
+	 *            Id identifiying the data
+	 * @see SplittableResource#getRootID()
+	 */
+	public DataPartition getData(int baseID) throws RemoteException {
+		DataPartition result = dataByID.get(baseID);
+		if (LOG.isDebugEnabled())
+			LOG.debug("Data retrieved from SPMDClient: ID:" + baseID);
+
+		// generate transfer event. Notice that this is very slow and
+		// will therefore only be created if a listener has registered
+		if (eventSink.isTransferMonitoringEnabled()) {
+			try {
+				// try to get Hostname (for performance reasons this is done
+				// only one time)
+				String hostIP = getClientHost();
+				// check if already looked up;
+				String hostname = hostnames.get(hostIP);
+				if (hostname == null) {
+					hostname = InetAddress.getByName(hostIP).getHostName();
+					hostnames.put(hostIP, hostname);
+				}
+				eventSink.fireRemoteEvent(new TransferEvent("DataServer",
+						hostname, CommType.TRANSFER_DATA, result));
+			} catch (ServerNotActiveException e) {
+				// if this is a purely local call no event
+				// should be generated.
+			} catch (UnknownHostException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * DataPartitions can be added
+	 *
+	 * @see appl.parallel.client.DataServer#addData(appl.parallel.spmd.split.DataPartition)
+	 */
+	public void addData(DataPartition splittable) {
+		this.dataByID.put(splittable.getRootID(), splittable);
+	}
+
+	/**
+	 * stops the client and removes it from the registry
+	 */
+	public void close() {
+		Helper.unbind(bindingName);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#getPartition(int,
+	 *      java.awt.Rectangle)
+	 */
+	public DataPartition getPartition(int id, Rectangle bounds)
+			throws RemoteException {
+		DataPartition data = (DataPartition) dataByID.get(id);
+		if (data == null && LOG.isDebugEnabled()) {
+			LOG.error("Partition with id " + id + " and bounds " + bounds
+					+ "was requested but not found on SPMDClient");
+			return null;
+		}
+		DataPartition result = data.getPartition(bounds);
+		if (eventSink.isTransferMonitoringEnabled()) {
+			try {
+				eventSink.fireRemoteEvent(new TransferEvent("DataServer",
+						getClientHost(), CommType.TRANSFER_DATA, result));
+			} catch (ServerNotActiveException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		if (LOG.isDebugEnabled())
+			LOG.debug("Data retrieved from SPMDClient: ID:" + id
+					+ " partition: " + bounds);
+		return result;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#setPartition(int,
+	 *      appl.parallel.spmd.split.DataPartition, java.awt.Rectangle)
+	 */
+	public void updatePartition(int id, DataPartition partition,
+			Rectangle bounds) throws RemoteException {
+		DataPartition data = (DataPartition) dataByID.get(id);
+		if (data == null && LOG.isDebugEnabled()) {
+			LOG.error("Partition of data with id " + id + " and bounds "
+					+ bounds + "should be set but was not found on SPMDClient");
+			return;
+		}
+		data.setPartition(partition, bounds);
+		if (LOG.isDebugEnabled())
+			LOG.debug("Partition set on SPMDClient with id " + id
+					+ " and partition bounds: " + bounds);
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.client.DataServer#removeData(int)
+	 */
+	public void removeData(int id) {
+		dataByID.remove(id);
+	}
+
+}

Added: trunk/src/appl/parallel/client/DataServer.java
===================================================================
--- trunk/src/appl/parallel/client/DataServer.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/client/DataServer.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,84 @@
+package appl.parallel.client;
+
+import java.awt.Rectangle;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+import appl.parallel.event.CommEvent;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.server.PartitionDataServer;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.SplittableResource;
+
+/**
+ * A {@link DataServer} shares resources over a network. For
+ * {@link SplittableResource}s it allows also the retrieval of
+ * {@link DataPartition}s. The data is retrieved using a unique id identifying
+ * the resource.
+ *
+ * @author Dominik Appl
+ */
+public interface DataServer extends Remote {
+
+	/**
+	 * gets the data with the id of a SplittableRessource
+	 *
+	 * @param id
+	 *            the {@link SplittableResource#getRootID() ID} of a the base
+	 *            data
+	 * @param bounds
+	 *            the bounds of the partition to retrieve (using global
+	 *            coordinates)
+	 * @return the partition
+	 * @throws RemoteException
+	 */
+	public DataPartition getPartition(int id, Rectangle bounds)
+			throws RemoteException;
+
+	/**
+	 * sets the data with the id of a SplittableRessource
+	 *
+	 * @param id
+	 *            the {@link SplittableResource#getRootID() ID} of a the base
+	 *            data
+	 * @param bounds
+	 *            the location where the partition is to be updated (using
+	 *            global coordinates)
+	 * @param updateData
+	 *            the updateData (which may only a partitial update, depending
+	 *            on the bounds set with the last parameter)
+	 * @throws RemoteException
+	 */
+	public void updatePartition(int id, DataPartition updateData,
+			Rectangle bounds) throws RemoteException;
+
+	/**
+	 * Returns the whole Partition with the given ID
+	 *
+	 * @param id
+	 *            the id of the partition
+	 * @return the partition
+	 * @throws RemoteException
+	 *             if the connection to the server fails
+	 */
+	public DataPartition getData(int id) throws RemoteException;
+
+	/**
+	 * Adds a Partition to the server
+	 *
+	 * @param partition
+	 *            the partition to add
+	 * @throws RemoteException
+	 */
+	public void addData(DataPartition partition) throws RemoteException;
+
+	/**
+	 * Removes the partition with the specified id.
+	 *
+	 * @param id
+	 *            id of the partition to remove
+	 * @throws RemoteException
+	 */
+	public void removeData(int id) throws RemoteException;
+
+}

Added: trunk/src/appl/parallel/client/RemoteEventHandler.java
===================================================================
--- trunk/src/appl/parallel/client/RemoteEventHandler.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/client/RemoteEventHandler.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,225 @@
+package appl.parallel.client;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.Vector;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.ext.XuluConfig;
+import appl.parallel.event.CommEvent;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.event.RemoteEvent;
+import appl.parallel.event.RemoteEventSink;
+import appl.parallel.event.TimeEvent;
+import appl.parallel.event.TimeMonitor;
+import appl.parallel.event.TransferEvent;
+import appl.parallel.event.TransferMonitor;
+import appl.parallel.services.Service;
+import appl.parallel.util.Helper;
+
+/**
+ * Starts a Service for receiving local and remote events. Monitors can register
+ * to this service. All events are forwarded the registered listeners. The
+ * service tries to get info for registry port from property
+ * <code>XuluClient.registryport</code> in {@link XuluConfig}.
+ * 
+ * @author Dominik Appl
+ */
+public class RemoteEventHandler extends UnicastRemoteObject implements Service,
+		CommEventSink {
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	// defaults
+	private String bindingName = "RemoteEventReceiver";
+
+	private int registryPort = 1099;
+
+	private Vector<TimeMonitor> timeMonitors = new Vector<TimeMonitor>();
+
+	private Vector<TransferMonitor> transferMonitors = new Vector<TransferMonitor>();
+
+	private boolean timeMonitoring = false;
+
+	private boolean transferMonitoring = false;
+
+	private boolean isRunning;
+
+	/**
+	 * @throws RemoteException
+	 * @throws RemoteException
+	 *             if binding fails
+	 */
+	public RemoteEventHandler() throws RemoteException {
+		super();
+		isRunning = false;
+	}
+
+	/**
+	 * tries to bind to a running registry or creates one.
+	 * 
+	 * @throws RemoteException
+	 *             if binding fails
+	 */
+	private void bind() throws RemoteException {
+		// try to get port from registry
+		int port = XuluConfig.getXuluConfig().getIntProperty(
+				"XuluClient.registryport");
+		if (port != 0)
+			registryPort = port;
+		// bind it
+		CommEventSink sink = this;
+		Helper.bind(bindingName, sink, registryPort);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.Service#isRunning()
+	 */
+	public boolean isRunning() {
+		return isRunning;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.Service#startService()
+	 */
+	public void startService() {
+		try {
+			bind();
+		} catch (RemoteException e) {
+			LOG.error("Could not bind " + bindingName
+					+ " to the registry! Eventsystem will fail.");
+		}
+		isRunning = true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.Service#stopService()
+	 */
+	public void stopService() {
+		unbind();
+		isRunning = false;
+	}
+
+	/**
+	 * unbinds the Service
+	 */
+	private void unbind() {
+		Helper.unbind(bindingName);
+	}
+
+	public void fireRemoteEvent(TimeEvent t) throws RemoteException {
+		for (TimeMonitor timeMonitor : timeMonitors) {
+			timeMonitor.receiveTimeEvent(t);
+		}
+	}
+
+
+	public void fireRemoteEvent(TransferEvent t) throws RemoteException {
+		for (TransferMonitor transferMonitor : transferMonitors) {
+			transferMonitor.receiveTransferEvent(t);
+		}
+	}
+
+	
+
+	/**
+	 * Adds a new time monitor
+	 * 
+	 * @param monitor
+	 *            a time monitor
+	 */
+	public void addTimeEventListener(TimeMonitor monitor) {
+		if (monitor != null) {
+			timeMonitors.add(monitor);
+			timeMonitoring = true;
+		}
+	}
+
+	/**
+	 * Adds a new {@link TransferMonitor}
+	 * 
+	 * @param monitor
+	 *            a time monitor
+	 */
+	public void addTransferEventListener(TransferMonitor monitor) {
+		if (monitor != null) {
+			transferMonitors.add(monitor);
+			transferMonitoring = true;
+		}
+	}
+
+	/**
+	 * removes the given monitor
+	 * 
+	 * @param monitor
+	 */
+	public void removeTimeMonitor(TimeMonitor monitor) {
+		timeMonitors.remove(monitor);
+		if (timeMonitors.size() == 0)
+			timeMonitoring = false;
+	}
+
+	/**
+	 * adds the given Monitor
+	 * 
+	 * @param monitor
+	 */
+	public void removeTransferMonitor(TransferMonitor monitor) {
+		transferMonitors.remove(monitor);
+		if (transferMonitors.size() == 0)
+			transferMonitoring = false;
+
+	}
+
+	/**
+	 * @return true if the service is running and time monitoring is enabled
+	 */
+	public boolean isTimeMonitoringEnabled() throws RemoteException {
+		return timeMonitoring;
+	}
+
+	/**
+	 * @return true if the service is running and transfer monitoring is enabled
+	 */
+	public boolean isTransferMonitoringEnabled() throws RemoteException {
+		return transferMonitoring;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.event.RemoteEventSink#fireRemoteEvent(appl.parallel.event.RemoteEvent)
+	 */
+	public void fireRemoteEvent(RemoteEvent e) throws RemoteException {
+		if (e instanceof TimeEvent)
+			fireRemoteEvent((TimeEvent) e);
+		else if (e instanceof TransferEvent)
+			fireRemoteEvent((TransferEvent) e);
+		else
+			// All events should be handled properly
+			System.err.println("Received unknown event of class "
+					+ e.getClass().getName());
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.event.RemoteEventSink#fireRemoteEvents(appl.parallel.event.RemoteEvent[])
+	 */
+	public void fireRemoteEvents(RemoteEvent[] e) throws RemoteException {
+		for (RemoteEvent event : e) {
+			fireRemoteEvent(event);
+		}
+	}
+
+}

Added: trunk/src/appl/parallel/client/RemoteExecutionController.java
===================================================================
--- trunk/src/appl/parallel/client/RemoteExecutionController.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/client/RemoteExecutionController.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,370 @@
+package appl.parallel.client;
+
+import java.io.IOException;
+import java.rmi.RemoteException;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.swing.JOptionPane;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.lf5.StartLogFactor5;
+
+import com.sun.jini.tool.ClassServer;
+
+import appl.ext.XuluConfig;
+import appl.parallel.ComputingResource;
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.ComputingResourceProperties;
+import appl.parallel.model.ParallelStepModel;
+import appl.parallel.server.XuluServer;
+import appl.parallel.services.DiscoveryService;
+import appl.parallel.services.GlobalDiscoveryService;
+import appl.parallel.spmd.AdvancedSPMDClientController;
+import appl.parallel.spmd.SPMDClientController;
+import appl.parallel.spmd.SPMDClientInterface;
+import appl.parallel.spmd.split.SplitMap;
+import appl.parallel.util.Helper;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.appl.XuluPlugin;
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import schmitzm.lang.AbstractNamedObject;
+
+/**
+ * This plugin is responsible that all services required for remote
+ * execution are properly started. It first starts the
+ * {@link GlobalDiscoveryService}. Then it uses the following entries of
+ * {@link XuluConfig} for configuration: <br>
+ * <br>
+ * <code>RemoteExecutionController.spmd.start</code> - if, <code>true</code>
+ * the {@link ClientDataServer} is started. <br><br>
+ * <code>RemoteExecutionController.http.start</code> - if, <code>true</code>
+ * the {@link ClassServer HTTP-Class server} is started. <br><br>
+ * <code>RemoteExecutionController.startLocalXuluServer</code> - if,
+ * <code>true</code> a local {@link XuluServer} is started. <br>.
+ * 
+ * @author Dominik Appl
+ */
+public class RemoteExecutionController extends AbstractNamedObject implements
+		XuluPlugin {
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	private ClientDataServer spmdClient;
+
+	private boolean started = false;
+
+	private XuluServer localServer;
+
+	private ClassServer httpServer;
+
+	private RemoteEventHandler eventHandlerProxy;
+
+	private GlobalDiscoveryService discoveryService;
+
+	private boolean startHTTP = false;
+
+	private boolean startSPMD = false;
+
+	private boolean startXuluServer = false;
+
+	private boolean httpVerbose = false;
+
+	private int httpPort = 80;
+
+	private String httpBaseDir = ".\\classes"; //default: will be overwritten with the configuration
+	
+	private Vector<ResourceChangeListener> activeChangeListeners = new Vector<ResourceChangeListener>();
+
+	private Vector<ComputingResourceContainer> lastKnownResources;
+	
+	public RemoteExecutionController() {
+		startDiscovery();
+	}
+
+	/**
+	 * Starts the Plugin
+	 * 
+	 * @see edu.bonn.xulu.appl.XuluPlugin#execute(edu.bonn.xulu.XuluModellingPlatform)
+	 */
+	public void execute(XuluModellingPlatform appl) {
+		started = true;
+		loadConfig();
+		startEventSystem();
+		startSPMDClient();
+		startXuluServer();
+		startDiscovery();
+		startHTTPServer();
+		//discover own server
+		refreshResources();
+	}
+
+	private void startEventSystem() {
+		// start EventProxy
+		try {
+			eventHandlerProxy = new RemoteEventHandler();
+			eventHandlerProxy.startService();
+		} catch (RemoteException e1) {
+			// TODO Auto-generated catch block
+			e1.printStackTrace();
+		}
+	}
+
+	private void startDiscovery() {
+		if (discoveryService != null)
+			discoveryService.stopService();
+		discoveryService = new GlobalDiscoveryService();
+	}
+
+	/**
+	 * Load the configuration form the {@link XuluConfig}
+	 */
+	private void loadConfig() {
+		XuluConfig config = XuluConfig.getXuluConfig();
+		startSPMD = config
+				.getBooleanProperty("RemoteExecutionController.spmd.start");
+		startXuluServer = config
+				.getBooleanProperty("RemoteExecutionController.startlocalxuluserver");
+		startHTTP = config
+				.getBooleanProperty("RemoteExecutionController.http.start");
+		httpVerbose = config
+				.getBooleanProperty("RemoteExecutionController.http.verbose");
+		if (config.getIntProperty("RemoteExecutionController.http.port") != 0)
+			httpPort = config
+					.getIntProperty("RemoteExecutionController.http.port");
+		if (config.getProperty("RemoteExecutionController.http.basedir") != null)
+			httpBaseDir = config
+					.getProperty("RemoteExecutionController.http.basedir");
+	}
+
+	private void startHTTPServer() {
+		// start the http server
+		if (startHTTP) {
+			try {
+				httpServer = new ClassServer(httpPort, httpBaseDir, true,
+						httpVerbose);
+				httpServer.start();
+			} catch (IOException e) {
+				LOG.error("Could not create HTTP-Server!", e);
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private void startSPMDClient() {
+		try {
+			if (startSPMD)
+				spmdClient = new ClientDataServer(eventHandlerProxy);
+		} catch (RemoteException e) {
+			LOG.error("SPMD Client could NOT be started. " + e.getMessage());
+			e.printStackTrace();
+		}
+	}
+
+	private void startXuluServer() {
+		try {
+			if (startXuluServer)
+				localServer = new XuluServer(false, spmdClient);
+		} catch (RemoteException e) {
+			LOG.error("XuluServer could NOT be started. " + e.getMessage());
+			e.printStackTrace();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see edu.bonn.xulu.appl.XuluPlugin#isStarted()
+	 */
+	public boolean isStarted() {
+		return started;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see edu.bonn.xulu.appl.XuluPlugin#isVisible()
+	 */
+	public boolean isVisible() {
+		// TODO Auto-generated method stub
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see edu.bonn.xulu.appl.XuluPlugin#setVisible(boolean)
+	 */
+	public void setVisible(boolean visible) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see edu.bonn.xulu.appl.XuluPlugin#stop()
+	 */
+	public void stop() {
+		started = false;
+		if (httpServer != null)
+			httpServer.stop();
+		if (spmdClient != null)
+			spmdClient.close();
+		spmdClient = null;
+		if (localServer != null)
+			localServer.stopServer();
+		spmdClient = null;
+		eventHandlerProxy.stopService();
+	}
+
+	/**
+	 * Gets active Resources and triggers the discovery-process. After
+	 * the resources are found an update is called on all registered 
+	 * {@link ResourceChangeListener}s.
+	 * 	 * 
+	 */
+	public void refreshResources() {
+		Vector<ComputingResourceContainer> remoteResources = discoveryService
+				.getRemoteResources();
+		
+		lastKnownResources = remoteResources;
+		//notify listeners about the resource update
+		for (ResourceChangeListener listener : activeChangeListeners) {
+			listener.updateResources(remoteResources);
+		}
+
+		// The advanced Server still makes some problems and therefore is here
+		// deactivated. May be fixed later.
+		// try {
+		// if(localServer!=null){
+		// ComputingResourceProperties localInfo =
+		// localServer.getResourceInformation();
+		// localInfo.setProperty("Name", "Advanced Internal Server");
+		// remoteResources.add(new ComputingResourceContainer(localServer,
+		// localInfo));
+		// }
+		//				
+		// } catch (RemoteException e) {
+		// // TODO Auto-generated catch block
+		// e.printStackTrace();
+		// }
+	}
+	
+	
+	/**
+	 * adds the change lister
+	 * 
+	 * @param r the change listener
+	 */
+	public void addResourceChangeListener(ResourceChangeListener r){
+		activeChangeListeners.add(r);
+	}
+	
+	/**
+	 * Removes the change listener
+	 * @param r the change listener to remove
+	 */
+	public void removeResourceChangeListener(ResourceChangeListener r){
+		activeChangeListeners.remove(r);
+	}
+
+	
+
+	/**
+	 * Calculates weight for the given resources for the use in {@link SplitMap}
+	 * splitmaps. For this the PerfomanceRating read out of the
+	 * {@link XuluConfig} property <br>
+	 * "PerformanceRating." + name of the machine <br>
+	 * If the rating is 0 an average rating is assumed.
+	 * 
+	 * @param computingResources
+	 * @return the weights
+	 */
+	private double[] calculateWeights(
+			Vector<ComputingResourceContainer> computingResources) {
+		// first get the rating. Try to find the value in the
+		// (user defined)configuration first, if not there try resource info.
+		int ratings[] = new int[computingResources.size()];
+		for (int i = 0; i < ratings.length; i++) {
+			ComputingResourceContainer container = computingResources.get(i);
+			String resName = container.getInformation().getName();
+			String rating = XuluConfig.getXuluConfig().getProperty(
+					"PerformanceRating." + resName, false);
+			// if not found take the benchmark value
+			if (rating == null) {
+				rating = container.getInformation().getProperty("Rating");
+			}
+			if (rating == null)
+				rating = "0";
+			ratings[i] = Integer.valueOf(rating);
+		}
+		return Helper.calculateWeights(ratings);
+	}
+
+	/**
+	 * Gives a new {@link SPMDClientController}.
+	 * 
+	 * @param computingResources
+	 *            the resources to be used by the new controller
+	 * @return a new {@link SPMDClientController} for the given resources
+	 */
+	public SPMDClientController getNewSPMDClientController(
+			ComputingResourceContainer[] computingResources) {
+		Vector<ComputingResourceContainer> resvec = new Vector<ComputingResourceContainer>(
+				computingResources.length);
+		for (ComputingResourceContainer container : computingResources) {
+			resvec.add(container);
+		}
+		return getNewSPMDClientController(resvec);
+	}
+
+	/**
+	 * Gives a new {@link SPMDClientController}.
+	 * 
+	 * @param computingResources
+	 *            the resources to be used by the new controller
+	 * @return a new {@link SPMDClientController} for the given resources
+	 */
+	public SPMDClientController getNewSPMDClientController(
+			Vector<ComputingResourceContainer> computingResources) {
+		double[] weights = calculateWeights(computingResources);
+		return new AdvancedSPMDClientController(computingResources, weights,
+				spmdClient, eventHandlerProxy);
+	}
+
+	/**
+	 * @return the execution controller of the given
+	 *         {@link XuluModellingPlatform} or null, if not found
+	 */
+	public static RemoteExecutionController getRemoteExecutionController(
+			XuluModellingPlatform modellingPlatform) {
+		XuluPlugin[] plugins = modellingPlatform.getRegistry().getPlugins();
+		for (XuluPlugin plugin : plugins) {
+			if (plugin instanceof RemoteExecutionController)
+				return (RemoteExecutionController) plugin;
+		}
+		return null;
+	}
+
+	public RemoteEventHandler getEventProxy() {
+		return eventHandlerProxy;
+	}
+
+	/**
+	 * Prepares a Model for execution, which means it creates a
+	 * {@link SPMDClientController} with the given Resources
+	 * 
+	 * @param model
+	 *            the model which is to be executed parallel
+	 * @param selectedResourceContainers
+	 *            the resources on which the model is executed
+	 */
+	public void prepareModelForSPMDExecution(ParallelStepModel model,
+			ComputingResourceContainer[] selectedResourceContainers) {
+		SPMDClientInterface controller = getNewSPMDClientController(selectedResourceContainers);
+		model.setSPMDController(controller);
+	}
+}

Added: trunk/src/appl/parallel/client/ResourceChangeListener.java
===================================================================
--- trunk/src/appl/parallel/client/ResourceChangeListener.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/client/ResourceChangeListener.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,22 @@
+package appl.parallel.client;
+
+import java.util.Vector;
+
+import appl.parallel.ComputingResourceContainer;
+
+/**
+ * Listeners which implement this interface can react on changes on the availability of
+ * remote resources. GUI classes use the interface to keep their resource list up to date.
+ *  
+ * @see RemoteExecutionController for a handler
+ * 
+ * @author Dominik Appl
+ */
+public interface ResourceChangeListener {
+	
+	/**
+	 * @param currentResources the current active remote resources
+	 */
+	public void updateResources(Vector<ComputingResourceContainer> currentResources);  
+
+}

Added: trunk/src/appl/parallel/client/package.html
===================================================================
--- trunk/src/appl/parallel/client/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/client/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains some classes for parallelization which are especially important on client side.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/data/AbstractDataHandler.java
===================================================================
--- trunk/src/appl/parallel/data/AbstractDataHandler.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/AbstractDataHandler.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,186 @@
+package appl.parallel.data;
+
+import java.awt.Rectangle;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.rmi.Naming;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.data.LoadingException;
+import appl.parallel.client.DataServer;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.SplittableResource;
+
+/**
+ * This class is used as a base class for loaders. It is especially intended for
+ * use with the SPMD-Paradigm, but may be used with other loaders, too. It
+ * implements the reusable stuff of the {@link PartitionDataHandler} Interface.
+ * Notice that each loader is responsible for exactly one data element. It must
+ * be {@link Cloneable}, so that multi-data elements can add another element.
+ * 
+ * @author Dominik Appl
+ */
+public abstract class AbstractDataHandler implements PartitionDataHandler {
+
+	protected transient Logger LOG = LogManager.getLogger(this.getClass()
+			.getName());
+
+	/**
+	 * The id of the currently handled {@link SplittableResource}
+	 */
+	protected int rootID;
+
+	/**
+	 * The partition bounds (the whole bounds) of the current
+	 * {@link SplittableResource}
+	 */
+	protected Rectangle partitionBounds;
+
+	/**
+	 * the currently handled data (must be initialized before calling
+	 * {@link #unload()}
+	 */
+	protected transient DataPartition data;
+
+	/**
+	 * The unload bounds differ may differ from the partitionBounds. If there is
+	 * a neighborhood region it is important, that only the core-region (without
+	 * the neighborhood) is unloaded.
+	 */
+	protected Rectangle unloadBounds;
+
+	/**
+	 * A {@link ClientDataServer} may be used locally for faster access.
+	 */
+	protected transient ClientDataServer spmdClient;
+
+	/**
+	 * Constructs a new {@link AbstractDataHandler}. The local IP address at
+	 * the time of construction is later used on serverside for communication
+	 * (e.g. unloading).
+	 * 
+	 * @param rootID
+	 *            the id of the data
+	 * @param client
+	 *            a {@link ClientDataServer} which may be used to get meta
+	 *            information on client side before transferring the loader to
+	 *            its destination
+	 * @param partitionBounds
+	 *            the bounds of the partition to be retrieved on server side
+	 * @param unloadBounds
+	 *            the bounds of the partition which is to be uploaded to the
+	 *            client after calculation (may only be the calculation area)
+	 */
+	public AbstractDataHandler(int rootID, ClientDataServer client,
+			Rectangle partitionBounds, Rectangle unloadBounds) {
+		this.spmdClient = client;
+		this.rootID = rootID;
+		this.partitionBounds = partitionBounds;
+		this.unloadBounds = unloadBounds;
+	}
+
+	/**
+	 * sets a local {@link ClientDataServer} which MAY be used by the handler
+	 * for local access
+	 * 
+	 * @param localSPMDClient
+	 */
+	public void setSPMDClient(ClientDataServer localSPMDClient) {
+		this.spmdClient = localSPMDClient;
+	}
+
+	/**
+	 * (empty constructors are important for deserialization)
+	 * 
+	 * @see #AbstractDataHandler(int, ClientDataServer, Rectangle, Rectangle)
+	 */
+	public AbstractDataHandler() {
+		this(-1, null, new Rectangle(0, 0, 0, 0), new Rectangle(0, 0, 0, 0));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#getLoadInfo()
+	 */
+	public abstract String getLoadInfo();
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#getLoadInfo()
+	 */
+	public abstract String getUnloadInfo();
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#load()
+	 */
+	public abstract DataPartition load() throws LoadingException;
+
+	/**
+	 * Initializes the {@link Logger} after deserialization (used by
+	 * {@link java.io.Serializable})
+	 * 
+	 * @throws IOException
+	 * @see Serializable
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s)
+			throws IOException, ClassNotFoundException {
+		// reading standard fields
+		s.defaultReadObject();
+		// initialize Logger
+		LOG = LogManager.getLogger(this.getClass().getName());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.PartitionDataHandler#setUnloadPartition(java.awt.Rectangle)
+	 */
+	public void setUnloadBounds(Rectangle unloadBounds) {
+		this.unloadBounds = unloadBounds;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.PartitionDataHandler#setBasePartition(appl.parallel.spmd.split.DataPartition)
+	 */
+	public void setBasePartition(DataPartition data) {
+		this.data = data;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataUnloader#unload()
+	 */
+	public abstract void unload();
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.PartitionDataHandler#setRootID(int)
+	 */
+	public void setRootID(int rootID) {
+		this.rootID = rootID;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#clone()
+	 */
+	public PartitionDataHandler clone() {
+		return newInstance(rootID, spmdClient, this.unloadBounds,
+				this.partitionBounds);
+	}
+
+}

Added: trunk/src/appl/parallel/data/DataLoadHandler.java
===================================================================
--- trunk/src/appl/parallel/data/DataLoadHandler.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/DataLoadHandler.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,14 @@
+package appl.parallel.data;
+
+import appl.data.DataLoader;
+import appl.data.DataUnloader;
+
+/**
+ * Instances of this interface are both {@link DataLoader} and
+ * {@link DataUnloader}.
+ * 
+ * @author Dominik Appl
+ */
+public interface DataLoadHandler extends DataLoader, DataUnloader {
+
+}

Added: trunk/src/appl/parallel/data/PartitionDataHandler.java
===================================================================
--- trunk/src/appl/parallel/data/PartitionDataHandler.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/PartitionDataHandler.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,55 @@
+package appl.parallel.data;
+
+import java.awt.Rectangle;
+
+import appl.data.LoadingException;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.spmd.split.DataPartition;
+
+/**
+ * Responsible for loading and unloading data partitions
+ * 
+ * @author Dominik Appl
+ */
+public interface PartitionDataHandler extends DataLoadHandler, Cloneable {
+
+	/**
+	 * sets the bounds of the data to be unloaded so that not all data is
+	 * unloaded to the destination. This is for example useful if there is a
+	 * neighborhood region which should not be uploaded to the destination.
+	 * 
+	 * @param bounds
+	 */
+	public void setUnloadBounds(Rectangle bounds);
+
+	public void setBasePartition(DataPartition data);
+
+	public void setRootID(int rootID);
+
+	/**
+	 * @param rootID
+	 *            the id of the data
+	 * @param partitionBounds
+	 *            the bounds of the partition to be retrieved on server side
+	 * @param unloadBounds
+	 *            the bounds of the partition which is to be uploaded to the
+	 *            client after calculation
+	 * @return the new instance
+	 */
+	public PartitionDataHandler newInstance(int rootID,
+			ClientDataServer spmdClient, Rectangle partitionBounds,
+			Rectangle unloadBounds);
+
+	public DataPartition load() throws LoadingException;
+
+	public PartitionDataHandler clone();
+
+	/**
+	 * sets a local spmd client which MAY be used by the handler for local
+	 * access
+	 * 
+	 * @param localSPMDClient
+	 */
+	public void setSPMDClient(ClientDataServer localSPMDClient);
+
+}

Added: trunk/src/appl/parallel/data/PartitionHandlerFactory.java
===================================================================
--- trunk/src/appl/parallel/data/PartitionHandlerFactory.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/PartitionHandlerFactory.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,65 @@
+package appl.parallel.data;
+
+import java.awt.Rectangle;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.ext.XuluConfig;
+import appl.parallel.client.ClientDataServer;
+
+/**
+ * Reads out of {@link XuluConfig} which {@link PartitionDataHandler} needs to
+ * be used for data loading/unloading and constructs an instance of this class.
+ * The classname is read out of the property <br>
+ * <br>
+ * Parallel.partitionhandlerfactory.classname
+ * 
+ * @author Dominik Appl
+ */
+public class PartitionHandlerFactory {
+
+	private static Logger LOG = LogManager
+			.getLogger("appl.data.PartitionHandlerFactory");
+
+	/**
+	 * @param rootID
+	 *            the id of the data
+	 * @param partitionBounds
+	 *            the bounds of the partition to be retrieved on server side
+	 * @param unloadBounds
+	 *            the bounds of the partition which is to be uploaded to the
+	 *            client after calculation
+	 * @return a new {@link PartitionDataHandler} instance
+	 */
+	public static PartitionDataHandler newInstance(int rootID,
+			ClientDataServer client, Rectangle partitionBounds,
+			Rectangle unloadBounds) {
+		PartitionDataHandler returnhandler = null;
+		// try to get info from xulu config
+		String classname = XuluConfig.getXuluConfig().getProperty(
+				"Parallel.partitionhandlerfactory.classname");
+		if (classname != null) {
+			try {
+				returnhandler = (PartitionDataHandler) Class.forName(classname)
+						.newInstance();
+			} catch (InstantiationException e) {
+				LOG.error(e);
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				LOG.error(e);
+				e.printStackTrace();
+			} catch (ClassNotFoundException e) {
+				e.printStackTrace();
+				LOG.error("Could not find PartitionHandler class '" + classname
+						+ "'", e);
+			}
+		}
+		if (returnhandler != null) {
+			return returnhandler.newInstance(rootID, client, partitionBounds,
+					unloadBounds);
+		}
+		return null;
+	}
+
+}

Added: trunk/src/appl/parallel/data/WritableGridArrayPartition.java
===================================================================
--- trunk/src/appl/parallel/data/WritableGridArrayPartition.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/WritableGridArrayPartition.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,276 @@
+package appl.parallel.data;
+
+import java.awt.Rectangle;
+import java.awt.image.DataBuffer;
+
+import appl.data.DataProxy;
+import appl.parallel.server.XuluServer;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.WritableGridPartition;
+import appl.parallel.util.PartitionUtil;
+import appl.util.RasterMetaData;
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+
+/** 
+ * A WritableGridArrayPartition extends the {@link WritableGridArray} so that
+ * it can be used in parallel computation. Every partition represents a 
+ * rectangle-shaped part of a father-grid. It has information about its bounds
+ * and about its father-grid. The partition may be used for data transfer
+ * between computing resources. It is very fast, because it is not proxyied
+ * by a {@link DataProxy}, but uses the {@link WritableGridArray} directly. 
+ * 
+ * @see WritableGridArrayPartition
+ * 
+ * @author Dominik Appl
+ */
+public abstract class WritableGridArrayPartition {
+
+	/**
+	 * For Float data types
+	 * 
+	 * @see WritableGridArray.Float
+	 * @author Dominik Appl
+	 */
+	public static class Float extends WritableGridArray.Float implements
+			WritableGridPartition {
+
+		private final int rootID;
+
+		private final Rectangle thisPartition;
+
+		private final RasterMetaData metaData;
+
+		public Float(RasterMetaData metaData, int rootID,
+				Rectangle thisPartition) {
+			super(metaData.getMinX(), metaData.getMinY(), metaData.getWidth(),
+					metaData.getHeight(), metaData.getX(), metaData.getY(),
+					metaData.getRealWidth(), metaData.getRealHeight(), metaData
+							.getCoordinateReferenceSystem(), null);
+			this.metaData = metaData;
+			this.rootID = rootID;
+			this.thisPartition = thisPartition;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getBounds(java.awt.Rectangle)
+		 */
+		public Rectangle getPartitionBounds() {
+			return thisPartition;
+
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getPartition(java.awt.Rectangle)
+		 */
+		public DataPartition getPartition(Rectangle partitionBounds) {
+			return PartitionUtil.getPartitialGrid2D(this, partitionBounds,
+					rootID);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getRootID()
+		 */
+		public int getRootID() {
+			return rootID;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#setPartition(appl.parallel.spmd.split.DataPartition,
+		 *      java.awt.Rectangle)
+		 */
+		public void setPartition(DataPartition partition,
+				Rectangle partitionBounds) {
+			if (!(partition instanceof WritableGrid))
+				throw new UnsupportedOperationException(
+						"The partition must be an instance of WritableGrid!");
+			PartitionUtil.setPartition(this, (WritableGrid) partition,
+					partitionBounds);
+
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getEmpty(int id)
+		 */
+		public DataPartition getEmpty(int id) {
+			return new WritableGridArrayPartition.Float(this.metaData, id,
+					thisPartition);
+		}
+	}
+	
+	/**
+	 * For Double data types
+	 * 
+	 * @see WritableGridArray.Double
+	 * @author Dominik Appl
+	 */
+	public static class Double extends WritableGridArray.Float implements
+			WritableGridPartition {
+
+		private final int rootID;
+
+		private final Rectangle thisPartition;
+
+		private final RasterMetaData metaData;
+
+		
+		public Double(RasterMetaData metaData, int rootID,
+				Rectangle thisPartition) {
+			super(metaData.getMinX(), metaData.getMinY(), metaData.getWidth(),
+					metaData.getHeight(), metaData.getX(), metaData.getY(),
+					metaData.getRealWidth(), metaData.getRealHeight(), metaData
+							.getCoordinateReferenceSystem(), null);
+			this.metaData = metaData;
+			this.rootID = rootID;
+			this.thisPartition = thisPartition;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getBounds(java.awt.Rectangle)
+		 */
+		public Rectangle getPartitionBounds() {
+			return thisPartition;
+
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getPartition(java.awt.Rectangle)
+		 */
+		public DataPartition getPartition(Rectangle partitionBounds) {
+			return PartitionUtil.getPartitialGrid2D(this, partitionBounds,
+					rootID);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getRootID()
+		 */
+		public int getRootID() {
+			return rootID;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#setPartition(appl.parallel.spmd.split.DataPartition,
+		 *      java.awt.Rectangle)
+		 */
+		public void setPartition(DataPartition partition,
+				Rectangle partitionBounds) {
+			if (!(partition instanceof WritableGrid))
+				throw new UnsupportedOperationException(
+						"The partition must be an instance of WritableGrid!");
+			PartitionUtil.setPartition(this, (WritableGrid) partition,
+					partitionBounds);
+
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getEmpty(int id)
+		 */
+		public DataPartition getEmpty(int id) {
+			return new WritableGridArrayPartition.Double(this.metaData, id,
+					thisPartition);
+		}
+	}
+	
+	/**
+	 * For Integer data types
+	 * 
+	 * @see WritableGridArray.Integer
+	 * @author Dominik Appl
+	 */
+	public static class Integer extends WritableGridArray.Integer implements
+			WritableGridPartition {
+
+		private final int rootID;
+
+		private final Rectangle thisPartition;
+
+		private final RasterMetaData metaData;
+
+		public Integer(RasterMetaData metaData, int rootID,
+				Rectangle thisPartition) {
+			super(metaData.getMinX(), metaData.getMinY(), metaData.getWidth(),
+					metaData.getHeight(), metaData.getX(), metaData.getY(),
+					metaData.getRealWidth(), metaData.getRealHeight(), metaData
+							.getCoordinateReferenceSystem(), null);
+			this.metaData = metaData;
+			this.rootID = rootID;
+			this.thisPartition = thisPartition;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getBounds(java.awt.Rectangle)
+		 */
+		public Rectangle getPartitionBounds() {
+			return thisPartition;
+
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getPartition(java.awt.Rectangle)
+		 */
+		public DataPartition getPartition(Rectangle partitionBounds) {
+			return PartitionUtil.getPartitialGrid2D(this, partitionBounds,
+					rootID);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getRootID()
+		 */
+		public int getRootID() {
+			return rootID;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#setPartition(appl.parallel.spmd.split.DataPartition,
+		 *      java.awt.Rectangle)
+		 */
+		public void setPartition(DataPartition partition,
+				Rectangle partitionBounds) {
+			if (!(partition instanceof WritableGrid))
+				throw new UnsupportedOperationException(
+						"The partition must be an instance of WritableGrid!");
+			PartitionUtil.setPartition(this, (WritableGrid) partition,
+					partitionBounds);
+
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.parallel.spmd.split.DataPartition#getEmpty(int id)
+		 */
+		public DataPartition getEmpty(int id) {
+			return new WritableGridArrayPartition.Integer(this.metaData, id,
+					thisPartition);
+		}
+	}
+
+}

Added: trunk/src/appl/parallel/data/XuluClientLoader.java
===================================================================
--- trunk/src/appl/parallel/data/XuluClientLoader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/XuluClientLoader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,207 @@
+package appl.parallel.data;
+
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.io.IOException;
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.UnknownHostException;
+import java.rmi.Naming;
+import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.data.LoadingException;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.client.DataServer;
+import appl.parallel.server.XuluServer;
+import appl.parallel.spmd.split.DataPartition;
+
+import schmitzm.data.WritableGrid;
+
+/**
+ * Loads partitioned data from a {@link ClientDataServer}. And unloads the data
+ * 
+ * @author Dominik Appl
+ */
+public class XuluClientLoader extends AbstractDataHandler implements
+		PartitionDataHandler {
+
+	protected InetAddress address;
+
+	protected String namingString;
+
+	private String unloadTarget = null;
+
+	/**
+	 * constructs a new {@link XuluClientLoader}. The local IP adress at the
+	 * time of construction is later used on serverside for communication (e.g.
+	 * unloading).
+	 * 
+	 * @param rootID
+	 *            the id of the data
+	 * @param partitionBounds
+	 *            the bounds of the partition to be retrieved on server side
+	 * @param unloadBounds
+	 *            the bounds of the partition which is to be uploaded to the
+	 *            client after calculation
+	 */
+	public XuluClientLoader(int rootID, ClientDataServer client,
+			Rectangle partitionBounds, Rectangle unloadBounds) {
+		super(rootID, client, partitionBounds, unloadBounds);
+		address = null;
+		namingString = null;
+		try {
+			this.address = InetAddress.getLocalHost();
+			unloadTarget = address.getHostAddress();
+			namingString = "rmi://" + unloadTarget + "/DataServer";
+		} catch (UnknownHostException e) {
+			LOG.error("The client IP could not be determined!!", e);
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * constructs a new {@link XuluClientLoader}. The unloading is done to the
+	 * {@link DataServer} at the machine given with the parameter unloadTarget
+	 * (IP/Adress or Hostname).
+	 * 
+	 * @param rootID
+	 *            the id of the data
+	 * @param partitionBounds
+	 *            the bounds of the partition to be retrieved on server side
+	 * @param unloadBounds
+	 *            the bounds of the partition which is to be uploaded to the
+	 *            client after calculation
+	 */
+	public XuluClientLoader(int rootID, ClientDataServer client,
+			Rectangle partitionBounds, Rectangle unloadBounds,
+			String unloadTarget) {
+		spmdClient = client;
+		this.unloadTarget = unloadTarget;
+		address = null;
+		namingString = null;
+		try {
+			this.address = InetAddress.getLocalHost();
+			namingString = "rmi://" + unloadTarget + "/DataServer";
+		} catch (UnknownHostException e) {
+			LOG.error("The client IP could not be determined!!", e);
+			e.printStackTrace();
+		}
+		this.rootID = rootID;
+		this.partitionBounds = partitionBounds;
+		this.unloadBounds = unloadBounds;
+	}
+
+	public XuluClientLoader newInstance(int rootID, ClientDataServer client,
+			Rectangle partitionBounds, Rectangle unloadBounds) {
+		return new XuluClientLoader(rootID, client, partitionBounds,
+				unloadBounds);
+	}
+
+	/**
+	 * Used for deserialization. Do not use for other purposes
+	 */
+	public XuluClientLoader() {
+		super();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#getLoadInfo()
+	 */
+	public String getLoadInfo() {
+		return "XuluClientLoader tries to load data with rootID " + rootID
+				+ " from IP: " + address.getHostAddress() + " with naming: "
+				+ namingString;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#getLoadInfo()
+	 */
+	public String getUnloadInfo() {
+		return "XuluClientLoader tries to unload data with rootID " + rootID
+				+ " to IP: " + address.getHostAddress() + " with naming: "
+				+ namingString;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataLoader#load()
+	 */
+	public DataPartition load() throws LoadingException {
+		try {
+			LOG.debug(getLoadInfo());
+			DataServer client = (DataServer) Naming.lookup(namingString);
+			data = client.getPartition(rootID, partitionBounds);
+			LOG.debug("Partition with id  " + rootID
+					+ " successfully retrieved from client");
+			return data;
+		} catch (Exception e) {
+			LOG.error("Partition retrieval failed: " + e.getMessage());
+		}
+		return null;
+	}
+
+	/**
+	 * Initializes the {@link Logger} after deserialization (used by
+	 * {@link java.io.Serializable}
+	 * 
+	 * @author Dominik Appl
+	 * @param s
+	 * @throws IOException
+	 * @see Serializable
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s)
+			throws IOException, ClassNotFoundException {
+		// reading standard fields
+		s.defaultReadObject();
+		// initialize Logger
+		LOG = LogManager.getLogger(this.getClass().getName());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.data.DataUnloader#unload()
+	 */
+	public void unload() {
+		try {
+			if (LOG.isDebugEnabled())
+				LOG.debug(getUnloadInfo());
+			if (data == null) {
+				if (LOG.isDebugEnabled())
+					LOG.debug("No data loaded -> nothing to unload");
+				return;
+			}
+			// construct return grid only if necessary
+			DataPartition returnPartition = null;
+			if (unloadBounds.equals(data.getPartitionBounds()))
+				returnPartition = data;
+			else
+				returnPartition = data.getPartition(unloadBounds);
+			// if there is a local spmdClient try to use it
+			if (spmdClient != null)
+				spmdClient.updatePartition(rootID, returnPartition,
+						unloadBounds);
+			// else connect remotely to client
+			else {
+				DataServer client = (DataServer) Naming.lookup(namingString);
+				client.updatePartition(rootID, returnPartition, unloadBounds);
+			}
+
+			LOG.debug("Partition with id  " + rootID
+					+ " was transfered back to client!");
+		} catch (Exception e) {
+			LOG.error("Backtransfer of data to client failed!", e);
+		}
+	}
+
+}

Added: trunk/src/appl/parallel/data/package.html
===================================================================
--- trunk/src/appl/parallel/data/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains data related parallelization classes. 
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/data/splittable/GridListFactory.java
===================================================================
--- trunk/src/appl/parallel/data/splittable/GridListFactory.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/GridListFactory.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,27 @@
+package appl.parallel.data.splittable;
+
+import edu.bonn.xulu.io.InstantiationFactory;
+
+// nur fuer Doku
+import schmitzm.data.WritableGrid;
+import edu.bonn.xulu.plugin.data.grid.GridList;
+
+/**
+ * Diese Factory erzeugt Standard-Instanzen von {@link GridList} mit
+ * durch die Factory {@link SplittableGridLLFactory} erzeugten (auf Standard-Arrays
+ * basierenden) {@link WritableGrid}-Instanzen als Inhalt.
+ * 
+ * @author Dominik Appl
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class GridListFactory extends edu.bonn.xulu.plugin.io.grid.awt.GridListFactory {
+  /**
+   * Liefert eine Instanz von {@link SplittableGridLLFactory}, die auf
+   * Standard-Arrays basierende Instanzen von {@link WritableGrid} erzeugt. Mit diesen
+   * Instanzen wird die GridList gefuellt.
+   */
+  protected InstantiationFactory getWritableGridFactory() {
+    return new SplittableGridLLFactory();
+  }
+}

Added: trunk/src/appl/parallel/data/splittable/GridListFactory_ArcInfoAsciiGrid.java
===================================================================
--- trunk/src/appl/parallel/data/splittable/GridListFactory_ArcInfoAsciiGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/GridListFactory_ArcInfoAsciiGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,162 @@
+package appl.parallel.data.splittable;
+
+import java.io.File;
+
+import appl.data.DataProxy;
+import appl.data.WritableGridLLProxy;
+import appl.ext.XuluConfig;
+import appl.util.RasterUtil;
+
+import schmitzm.io.IOUtil;
+import schmitzm.data.WritableGridArray;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ListPropertyReadAccess;
+
+import edu.bonn.xulu.io.Factory;
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.io.InstantiationFactory;
+import edu.bonn.xulu.io.ExportFactory;
+import edu.bonn.xulu.io.AbstractFactory;
+import edu.bonn.xulu.appl.XuluRegistry;
+
+import edu.bonn.xulu.plugin.data.grid.GridList;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory_ArcInfoAsciiGrid;
+
+/**
+ * Diese Factory importiert und exportiert Instanzen des Datentyps
+ * {@link GridList} aus/in Dateien im ArcInfo-ASCII-Grid-Format.
+ * Beim Import liefert die Factory eine Standard-Arrays basierendes Raster-Liste
+ * ({@link WritableGridArray}).
+ * 
+ * 
+ * @author Dominik Appl
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class GridListFactory_ArcInfoAsciiGrid extends AbstractFactory implements ImportFactory,ExportFactory {
+ private static final ImportFactory importFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+ private static final ExportFactory exportFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ImportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Liefert den Datentyp, den die Factory erzeugt.
+   * @return immer {@link GridList GridList.class}
+   */
+  public Class getImportType() {
+    return GridList.class;
+  }
+
+  /**
+   * Liefert den Datentyp, den die Factory als Import-Quelle benoetigt.
+   * @return immer {@link File File[].class}
+   */
+  public Class getImportSourceType() {
+     return File[].class;
+  }
+
+  /**
+   * Importiert Raster aus Dateien im ArcInfoAsciiGrid-Format
+   * und fuegt diese in einer {@link GridList} zusammen.
+   * @param input Eingabe-Quelle (muss ein {@link File File[]} sein!)
+   * @param reg   Instanz der Xulu-Registry, ueber die eine Factory ermittelt
+   *              wird, die eine Standard-Instanz von {@link GridList} erzeugt, in
+   *              die das Objekt importiert wird
+   * @exception UnsupportedOperationException falls als Eingabe-Quelle keine
+   *            Dateien angegeben werden
+   */
+  public GridList importObject(Object input, XuluRegistry reg) throws Exception {
+    AbstractFactory.checkImportSourceObject(this,input,getImportSourceType(),true);
+    InstantiationFactory instFac = AbstractFactory.getInstantiationFactoryFromRegistry(reg,getImportType(),true);
+    GridList sg = (GridList)instFac.newInstance(false);
+    // Raster importieren und in GridList einfuegen
+    for (int i=0; i<((Object[])input).length; i++){
+    	SplittableLLProxyGrid grid =  new SplittableLLProxyGrid(importFac,
+        		RasterUtil.getRasterMetaData_from_ArcGridASCII_File(((File[])input)[i]), 
+        		((File[])input)[i], 
+        		reg );
+    	//read and apply settings from the registry
+        String unloadFolder = XuluConfig.getXuluConfig().getProperty("Datatypes.proxy.unloadFolder");
+        boolean unloading = XuluConfig.getXuluConfig().getBooleanProperty("Datatypes.proxy.enableUnloading");
+        if(unloadFolder!=null)
+        	grid.setUnloadDir(unloadFolder);
+        grid.setUnloading(unloading);
+    	sg.addGrid(  grid  );
+    }
+//    // Dateinamen in die Bezeichnung aufnehmen
+//    sg.setDescription(sg.getDescription().concat(" [").concat(((File)input).getName()).concat("]"));
+    return sg;
+  }
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ExportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Prueft, ob ein Objekt exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um eine {@link GridList} handelt, die nur Instanzen
+   * von {@link WritableGridArray} als Elemente enthaelt.
+   * @param obj zu pruefendes Objekt
+   */
+  public boolean isExportable(Object obj) {
+    if ( obj==null || !(obj instanceof GridList) )
+      return false;
+    GridList list = (GridList)obj;
+    for (int i=0; i<list.getGridCount(); i++)
+      if ( !(list.getGrid(i) instanceof SplittableLLProxyGrid) )
+        return false;
+    return true;
+  }
+
+  /**
+   * Prueft, ob ein Objekttyp exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um {@link GridList} (oder eine Unterklasse)
+   * handelt.
+   * @param c zu pruefender Objekttyp
+   */
+  public boolean isExportable(Class c) {
+    return GridList.class.isAssignableFrom(c);
+  }
+
+  /**
+   * Liefert den Objekt-Typ, den die Factory als Ziel zum Exportieren
+   * benoetigt. Dabei handelt es sich um eine <b>einzelne Datei</b>, da
+   * die die letztendlichen Export-Dateien automatisch durchnummeriert werden!!
+   * @return immer {@link File File.class}
+   */
+  public Class getExportDestinationType() {
+    return File.class;
+  }
+
+  /**
+   * Exportiert eine Instanz von {@link GridList} in Dateien des
+   * ArcInfoAsciiGrid-Formats.<br>
+   * <b>Beachte:</b><br>
+   * Als Ausgabe-Objekt ist eine <b>einzelne</b> Datei anzugeben, kein
+   * Array! Die Dateien werden ausgehend von dem angegebenen Dateinamen
+   * durchnummeriert!!
+   * @param object zu exportiertende Raster (muss eine {@link GridList} sein
+   * @param output Export-Ziel (muss ein einzelner {@link File} sein!)
+   * @exception UnsupportedOperationException falls als Export-Ziel keine
+   *            einzelne Datei angegeben wird
+   * @exception IllegalArgumentException falls es sich bei dem angegeben Objekt
+   *            nicht um eine {@link GridList} handelt
+   */
+  public void exportObject(Object object, Object output) throws Exception {
+    AbstractFactory.checkExportDestinationObject(this,output,getExportDestinationType(),true);
+    if ( !isExportable(object) )
+      throw new IllegalArgumentException(getClass().getName().concat(" can not export instances of ").concat(object.getClass().getName()));
+
+    // Dateinamen-Teile ermitteln
+    String fileName = IOUtil.getBaseFileName((File)output);
+    String fileExt  = IOUtil.getFileExt((File)output);
+
+    // Grids in der Liste einzeln exportieren
+    ListPropertyReadAccess listAccess = ((ListProperty) (((GridList)object).getProperty(GridList.PROP_GRIDS))).getReadAccess(this);
+    for (int i=0; i<listAccess.getCount(); i++) {
+      File outFile = new File( fileName.concat("_"+i).concat(fileExt) );
+      exportFac.exportObject( ((DataProxy)listAccess.getValue(i)).getProxiedObject() ,outFile );
+    }
+    listAccess.release();
+
+  }
+}

Added: trunk/src/appl/parallel/data/splittable/MultiGridFactory.java
===================================================================
--- trunk/src/appl/parallel/data/splittable/MultiGridFactory.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/MultiGridFactory.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,26 @@
+package appl.parallel.data.splittable;
+
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+// nur fuer Doku
+import schmitzm.data.WritableGrid;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+/**
+ * Diese Factory erzeugt Standard-Instanzen von {@link MultiGrid} mit
+ * durch die Factory {@link SplittableGridLLFactory} erzeugten (auf Standard-Arrays
+ * basierenden) {@link WritableGrid}-Instanzen als Inhalt.
+ * @author Dominik Appl
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class MultiGridFactory extends edu.bonn.xulu.plugin.io.grid.awt.MultiGridFactory {
+  /**
+   * Liefert eine Instanz von {@link SplittableGridLLFactory}, die auf Standard-Arrays
+   * basierende Instanzen von {@link WritableGrid} erzeugt. Mit diesen
+   * Instanzen wird die GridList gefuellt.
+   */
+  protected WritableGridFactory getWritableGridFactory() {
+    return new SplittableGridLLFactory();
+  }
+
+}

Added: trunk/src/appl/parallel/data/splittable/MultiGridFactory_ArcInfoAsciiGrid.java
===================================================================
--- trunk/src/appl/parallel/data/splittable/MultiGridFactory_ArcInfoAsciiGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/MultiGridFactory_ArcInfoAsciiGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,94 @@
+package appl.parallel.data.splittable;
+
+import java.io.File;
+
+import appl.data.WritableGridLLProxy;
+import appl.ext.XuluConfig;
+import appl.util.RasterUtil;
+
+import schmitzm.data.WritableGrid;
+
+import edu.bonn.xulu.appl.XuluRegistry;
+import edu.bonn.xulu.io.AbstractFactory;
+import edu.bonn.xulu.io.ImportFactory;
+
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+import edu.bonn.xulu.plugin.data.grid.GridList;
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory_ArcInfoAsciiGrid;
+//import edu.bonn.xulu.plugin.io.grid.gt.GridListFactory_ArcInfoAsciiGrid;
+
+// nur fuer Doku
+import schmitzm.data.WritableGridArray;
+import edu.bonn.xulu.io.InstantiationFactory;
+
+/**
+ * Diese Factory importiert und exportiert Instanzen des Datentyps
+ * {@link MultiGrid} aus/in Dateien im ArcInfo-ASCII-Grid-Format.
+ * Beim Import liefert die Factory eine Standard-Arrays basierendes Raster-Liste
+ * 
+ * 
+ * @author Dominik Appl
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class MultiGridFactory_ArcInfoAsciiGrid extends GridListFactory_ArcInfoAsciiGrid {
+  private static final ImportFactory importFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ImportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Liefert den Datentyp, den die Factory erzeugt.
+   * @return immer {@link MultiGrid MultiGrid.class}
+   */
+  public Class getImportType() {
+    return MultiGrid.class;
+  }
+
+  /**
+   * Importiert Raster aus Dateien im ArcInfoAsciiGrid-Format
+   * und fuegt diese in einem {@link MultiGrid} zusammen.
+   * @param input Eingabe-Quelle (muss ein {@link File File[]} sein!)
+   * @param reg   Instanz der Xulu-Registry, ueber die eine Factory ermittelt
+   *              wird, die eine Standard-Instanz von {@link MultiGrid} erzeugt, in
+   *              die das Objekt importiert wird
+   * @exception UnsupportedOperationException falls als Eingabe-Quelle keine
+   *            Dateien angegeben werden
+   */
+  public MultiGrid importObject(Object input, XuluRegistry reg) throws Exception {
+    AbstractFactory.checkImportSourceObject(this,input,getImportSourceType(),true);
+
+    // MultiGrid erst erzeugen, wenn ein Beispiel-Raster vorliegt
+    MultiGrid mg = null;
+    // Raster importieren und in GridList einfuegen
+    for (int i=0; i<((Object[])input).length; i++) {
+    	SplittableLLProxyGrid grid = new SplittableLLProxyGrid
+                                (importFac,
+                                 RasterUtil.getRasterMetaData_from_ArcGridASCII_File(((File[])input)[i]), 
+                                 ((File[])input)[i], reg );
+      //read and apply settings from the registry
+      String unloadFolder = XuluConfig.getXuluConfig().getProperty("Datatypes.proxy.unloadFolder");
+      boolean unloading = XuluConfig.getXuluConfig().getBooleanProperty("Datatypes.proxy.enableUnloading");
+      if(unloadFolder!=null)
+      	grid.setUnloadDir(unloadFolder);
+      grid.setUnloading(unloading);
+      // das erste Grid dient dem MultiGrid als Vorlage
+      if ( mg == null )
+        mg = new MultiGrid(grid,getWritableGridFactory());
+
+      mg.addGrid(grid);
+    }
+    return mg;
+  }
+
+  /**
+   * Liefert eine Instanz von {@link SplittableGridLLFactory}, die auf Standard-Arrays
+   * basierende Instanzen von {@link WritableGrid} erzeugt. Mit diesen
+   * Instanzen wird das SingleGrid gefuellt.
+   */
+  protected WritableGridFactory getWritableGridFactory() {
+    return new SplittableGridLLFactory();
+  }
+
+}

Added: trunk/src/appl/parallel/data/splittable/SingleGridFactory.java
===================================================================
--- trunk/src/appl/parallel/data/splittable/SingleGridFactory.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/SingleGridFactory.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,27 @@
+package appl.parallel.data.splittable;
+
+import edu.bonn.xulu.io.InstantiationFactory;
+// nur fuer Doku
+import schmitzm.data.WritableGrid;
+import edu.bonn.xulu.plugin.data.grid.SingleGrid;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory;
+
+/**
+ * Diese Factory erzeugt Standard-Instanzen von {@link SingleGrid} mit einem
+ * durch die Factory {@link SplittableGridLLFactory} erzeugten (auf Standard-Arrays basierenden)
+ * {@link WritableGrid}.
+ * @author Dominik Appl
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class SingleGridFactory  extends edu.bonn.xulu.plugin.io.grid.awt.SingleGridFactory{
+
+  /**
+   * Liefert eine Instanz von {@link WritableGridArrayFactory}, die auf Standard-Arrays
+   * basierende Instanzen von {@link WritableGrid} erzeugt. Mit diesen
+   * Instanzen wird das SingleGrid gefuellt.
+   */
+  protected InstantiationFactory getWritableGridFactory() {
+    return new SplittableGridLLFactory();
+  }
+}

Added: trunk/src/appl/parallel/data/splittable/SingleGridFactory_ArcInfoAsciiGrid.java
===================================================================
--- trunk/src/appl/parallel/data/splittable/SingleGridFactory_ArcInfoAsciiGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/SingleGridFactory_ArcInfoAsciiGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,137 @@
+package appl.parallel.data.splittable;
+
+import java.io.File;
+
+import appl.data.DataProxy;
+import appl.data.WritableGridLLProxy;
+import appl.ext.XuluConfig;
+import appl.util.RasterMetaData;
+import appl.util.RasterUtil;
+
+import schmitzm.data.WritableGridArray;
+
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.io.InstantiationFactory;
+import edu.bonn.xulu.io.ExportFactory;
+import edu.bonn.xulu.io.AbstractFactory;
+import edu.bonn.xulu.appl.XuluRegistry;
+
+import edu.bonn.xulu.plugin.data.grid.SingleGrid;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory_ArcInfoAsciiGrid;
+
+// nur fuer Doku
+
+/**
+ * Diese Factory importiert und exportiert Instanzen des Datentyps
+ * {@link SingleGrid} aus/in das ArcInfo-ASCII-Grid-Format.
+ * Beim Import liefert die Factory ein auf Standard-Arrays basierendes Raster
+ * ({@link WritableGridArray}).
+ 
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class SingleGridFactory_ArcInfoAsciiGrid extends AbstractFactory implements ImportFactory, ExportFactory {
+  private static final ImportFactory importFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+  private static final ExportFactory exportFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ImportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Liefert den Datentyp, den die Factory erzeugt.
+   * @return immer {@link SingleGrid SingleGrid.class}
+   */
+  public Class getImportType() {
+    return SingleGrid.class;
+  }
+
+  /**
+   * Liefert den Datentyp, den die Factory als Import-Quelle benoetigt.
+   * @return immer {@link File File.class}
+   */
+  public Class getImportSourceType() {
+    return File.class;
+  }
+
+  /**
+   * Importiert eine Instanz von {@link SingleGrid} aus einer Datei im
+   * ArcInfoAsciiGrid-Format.
+   * @param input Eingabe-Quelle (muss ein {@link File} sein!)
+   * @param reg   Instanz der Xulu-Registry, ueber die eine Factory ermittelt
+   *              wird, die eine Standard-Instanz von {@link SingleGrid} erzeugt, in
+   *              die das Raster importiert wird
+   * @exception UnsupportedOperationException falls als Eingabe-Quelle keine
+   *            Datei angegeben wird
+   */
+  public SingleGrid importObject(Object input, XuluRegistry reg) throws Exception {
+    AbstractFactory.checkImportSourceObject(this,input,getImportSourceType(),true);
+    // Aus Registry die passende Factory fuer SingleGrid suchen
+    InstantiationFactory instFac = AbstractFactory.getInstantiationFactoryFromRegistry(reg,getImportType(),true);
+    // Raster importieren und in ein SingleGrid einfuegen
+    SingleGrid sg = (SingleGrid)instFac.newInstance(false);
+    SplittableLLProxyGrid newGrid = new SplittableLLProxyGrid(importFac, 
+            RasterUtil.getRasterMetaData_from_ArcGridASCII_File((File) input),
+            (File)input,reg);
+    //read and apply settings from the registry
+    String unloadFolder = XuluConfig.getXuluConfig().getProperty("Datatypes.proxy.unloadFolder");
+    boolean unloading = XuluConfig.getXuluConfig().getBooleanProperty("Datatypes.proxy.enableUnloading");
+    if(unloadFolder!=null)
+    	newGrid.setUnloadDir(unloadFolder);
+    newGrid.setUnloading(unloading);
+    sg.setGrid(newGrid);
+    // Dateinamen in die Bezeichnung aufnehmen
+    sg.setDescription(sg.getDescription().concat(" [").concat(((File)input).getName()).concat("]"));
+    return sg;
+  }
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ExportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Prueft, ob ein Objekt exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um ein {@link SingleGrid} handelt, das ein
+   * {@link WritableGridArray} in seiner Raster-Eigenschaft besitzt.
+   * @param obj zu pruefendes Objekt
+   */
+  public boolean isExportable(Object obj) {
+    return obj!=null &&
+           obj instanceof SingleGrid &&
+           ((SingleGrid)obj).getGrid() instanceof SplittableLLProxyGrid;
+  }
+
+  /**
+   * Prueft, ob ein Objekttyp exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um {@link SingleGrid} (oder eine Unterklasse)
+   * handelt.
+   * @param c zu pruefender Objekttyp
+   */
+  public boolean isExportable(Class c) {
+    return SingleGrid.class.isAssignableFrom(c);
+  }
+
+  /**
+   * Liefert den Objekt-Typ, den die Factory als Ziel zum Exportieren
+   * benoetigt.
+   * @return immer {@link File File.class}
+   */
+  public Class getExportDestinationType() {
+    return File.class;
+  }
+
+  /**
+   * Exportiert eine Instanz von {@link SingleGrid} in eine ArcInfoAsciiGrid-Datei.
+   * @param grid zu exportiertendes Raster (muss ein {@link SingleGrid} sein
+   * @param output Export-Ziel (muss ein {@link File} sein!)
+   * @exception UnsupportedOperationException falls als Export-Ziel keine
+   *            Datei angegeben wird
+   * @exception IllegalArgumentException falls es sich bei dem angegeben Raster
+   *            nicht um ein {@link SingleGrid} handelt
+   */
+  public void exportObject(Object grid, Object output) throws Exception {
+    AbstractFactory.checkExportDestinationObject(this,output,getExportDestinationType(),true);
+    if ( !isExportable(grid) )
+      throw new IllegalArgumentException(getClass().getName().concat(" can not export instances of ").concat(grid.getClass().getName()));
+    exportFac.exportObject( ((DataProxy)((SingleGrid)grid).getGrid()).getProxiedObject(),(File)output );
+  }
+
+}

Added: trunk/src/appl/parallel/data/splittable/SingleGridFactory_GeoTiff.java
===================================================================
--- trunk/src/appl/parallel/data/splittable/SingleGridFactory_GeoTiff.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/SingleGridFactory_GeoTiff.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,129 @@
+package appl.parallel.data.splittable;
+
+import java.io.File;
+
+import appl.data.DataProxy;
+
+
+import schmitzm.data.WritableGridArray;
+
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.io.InstantiationFactory;
+import edu.bonn.xulu.io.ExportFactory;
+import edu.bonn.xulu.io.AbstractFactory;
+import edu.bonn.xulu.appl.XuluRegistry;
+
+import edu.bonn.xulu.plugin.data.grid.SingleGrid;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory_GeoTiff;
+
+// nur fuer Doku
+import appl.data.WritableGridLLProxy;
+
+/**
+ * Diese Factory importiert und exportiert Instanzen des Datentyps
+ * {@link SingleGrid} aus/in das GeoTiff-Format.
+ * Beim Import liefert die Factory ein auf Standard-Arrays basierendes Raster
+ * ({@link WritableGridArray}).
+ *
+ * @author Dominik Appl
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class SingleGridFactory_GeoTiff extends AbstractFactory implements ImportFactory, ExportFactory {
+  private static final WritableGridArrayFactory_GeoTiff GRID_FAC = new WritableGridArrayFactory_GeoTiff();
+  private static final WritableGridArrayFactory_GeoTiff importFac = new WritableGridArrayFactory_GeoTiff();
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ImportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Liefert den Datentyp, den die Factory erzeugt.
+   * @return immer {@link SingleGrid SingleGrid.class}
+   */
+  public Class getImportType() {
+    return SingleGrid.class;
+  }
+
+  /**
+   * Liefert den Datentyp, den die Factory als Import-Quelle benoetigt.
+   * @return immer {@link File File.class}
+   */
+  public Class getImportSourceType() {
+    return File.class;
+  }
+
+  /**
+   * Importiert eine Instanz von {@link SingleGrid} aus einer Datei im
+   * GeoTiff-Format.
+   * @param input Eingabe-Quelle (muss ein {@link File} sein!)
+   * @param reg   Instanz der Xulu-Registry, ueber die eine Factory ermittelt
+   *              wird, die eine Standard-Instanz von {@link SingleGrid} erzeugt, in
+   *              die das Raster importiert wird
+   * @exception UnsupportedOperationException falls als Eingabe-Quelle keine
+   *            Datei angegeben wird
+   */
+  public SingleGrid importObject(Object input, XuluRegistry reg) throws Exception {
+	  throw new UnsupportedOperationException("currently this import type is not supported for Proxy Grids. Use the standard data type");
+//    AbstractFactory.checkImportSourceObject(this,input,getImportSourceType(),true);
+//    // Aus Registry die passende Factory fuer SingleGrid suchen
+//    InstantiationFactory instFac = AbstractFactory.getInstantiationFactoryFromRegistry(reg,getImportType(),true);
+//    // Raster importieren und in ein SingleGrid einfuegen
+//    SingleGrid sg = (SingleGrid)instFac.newInstance(false);
+//    //new WritableGridLLProxy(importFac, new FileInputStream((File)input),reg)
+//    ;
+//    // Dateinamen in die Bezeichnung aufnehmen
+//    sg.setDescription(sg.getDescription().concat(" [").concat(((File)input).getName()).concat("]"));
+
+  }
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ExportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Prueft, ob ein Objekt exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um ein {@link SingleGrid} handelt, das ein
+   * {@link WritableGridLLProxy} in seiner Raster-Eigenschaft besitzt.
+   * @param obj zu pruefendes Objekt
+   */
+  public boolean isExportable(Object obj) {
+    return obj!=null &&
+           obj instanceof SingleGrid &&
+           ((SingleGrid)obj).getGrid() instanceof SplittableLLProxyGrid;
+  }
+
+  /**
+   * Prueft, ob ein Objekttyp exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um {@link SingleGrid} (oder eine Unterklasse)
+   * handelt.
+   * @param c zu pruefender Objekttyp
+   */
+  public boolean isExportable(Class c) {
+    return SingleGrid.class.isAssignableFrom(c);
+  }
+
+  /**
+   * Liefert den Objekt-Typ, den die Factory als Ziel zum Exportieren
+   * benoetigt.
+   * @return immer {@link File File.class}
+   */
+  public Class getExportDestinationType() {
+    return File.class;
+  }
+
+  /**
+   * Exportiert eine Instanz von {@link SingleGrid} in eine GeoTiff-Datei.
+   * @param grid zu exportiertendes Raster (muss ein {@link SingleGrid} sein
+   * @param output Export-Ziel (muss ein {@link File} sein!)
+   * @exception UnsupportedOperationException falls als Export-Ziel keine
+   *            Datei angegeben wird
+   * @exception IllegalArgumentException falls es sich bei dem angegeben Raster
+   *            nicht um ein {@link SingleGrid} handelt
+   */
+  public void exportObject(Object grid, Object output) throws Exception {
+    AbstractFactory.checkExportDestinationObject(this,output,getExportDestinationType(),true);
+    if ( !isExportable(grid) )
+      throw new IllegalArgumentException(getClass().getName().concat(" can not export instances of ").concat(grid.getClass().getName()));
+    GRID_FAC.exportObject( ((DataProxy)((SingleGrid)grid).getGrid()).getProxiedObject(), (File)output );
+  }
+
+}

Added: trunk/src/appl/parallel/data/splittable/SplittableGridLLFactory.java
===================================================================
--- trunk/src/appl/parallel/data/splittable/SplittableGridLLFactory.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/SplittableGridLLFactory.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,65 @@
+package appl.parallel.data.splittable;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.DataBuffer;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import appl.data.WritableGridLLProxy;
+import appl.util.RasterMetaData;
+import schmitzm.data.WritableGrid;
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory;
+
+// nur fuer Doku
+import edu.bonn.xulu.data.XuluObject;
+import edu.bonn.xulu.io.Factory;
+import edu.bonn.xulu.plugin.data.grid.SingleGrid;
+
+/**
+ * Diese Factory erzeugt Standard-Instanzen des Datentyps {@link SplittableLLProxyGrid}.<br>
+ * <b>Bemerke:</b><br>
+ * Dieser stellt <b>kein</b> {@linkplain XuluObject Xulu-Objekt} dar, kann also
+ * nicht direkt im Xulu-Datenpool gespeichert werden. Hierzu ist der Datentyp
+ * {@link SingleGrid} (bzw. eine entsprechende Factory) zu verwenden!
+ * @author Dominik Appl
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class SplittableGridLLFactory extends WritableGridFactory {
+
+
+    WritableGridFactory  targetFactory = new WritableGridArrayFactory();
+
+
+  /**
+   * Liefert den Datentyp, den die Factory erzeugt.
+   * @return immer {@link SplittableLLProxyGrid SplittableLLProxyGrid.class}
+   */
+  public Class getInstanceType() {
+    return SplittableLLProxyGrid.class;
+  }
+
+  /**
+   * Erzeugt ein neues Grid.
+   * @param type    Datentyp der gespeicherten Objekte
+   * @param widthc  Breite in Zellen
+   * @param heightc Hoehe in Zellen
+   * @param minX    Index der ersten Zelle in X-Richtung
+   * @param minY    Index der ersten Zelle in Y-Richtung
+   * @param x       Georeferenz Latitude (Suedliche/Untere Kante)
+   * @param y       Georeferenz Longitute (Westliche/Linke Kante)
+   * @param width   Breite
+   * @param height  Hoehe
+   */
+  public SplittableLLProxyGrid newInstance(int type, int widthc, int heightc, int minX, int minY, double x, double y, double width, double height, CoordinateReferenceSystem crs) {
+
+
+	  return new SplittableLLProxyGrid(targetFactory,new RasterMetaData(
+			  											type,widthc,heightc,
+			  											minX,minY,x,y,width,
+			  											height, crs));
+    }
+}

Added: trunk/src/appl/parallel/data/splittable/SplittableLLProxyGrid.java
===================================================================
--- trunk/src/appl/parallel/data/splittable/SplittableLLProxyGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/SplittableLLProxyGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,132 @@
+package appl.parallel.data.splittable;
+
+import java.awt.Rectangle;
+import java.io.Serializable;
+
+import schmitzm.data.WritableGrid;
+import appl.data.DataLoader;
+import appl.data.WritableGridLLProxy;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.SplittableGrid;
+import appl.parallel.spmd.split.SplittableResource;
+import appl.parallel.spmd.split.WritableGridPartition;
+import appl.parallel.util.PartitionUtil;
+import appl.util.RasterMetaData;
+import edu.bonn.xulu.appl.XuluRegistry;
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+
+/**
+ * @version 1.0
+ */
+public class SplittableLLProxyGrid extends WritableGridLLProxy implements
+		SplittableGrid, Serializable {
+
+	private final int id;
+
+	public SplittableLLProxyGrid(ImportFactory importFac,
+			RasterMetaData metaData, Object inputPara, XuluRegistry reg) {
+		super(importFac, metaData, inputPara, reg);
+		id = this.hashCode();
+	}
+
+	public SplittableLLProxyGrid(WritableGridFactory targetFactory,
+			RasterMetaData metaData) {
+		super(targetFactory, metaData);
+		id = this.hashCode();
+	}
+
+	public SplittableLLProxyGrid(RasterMetaData metaData, int id) {
+		super(metaData);
+		this.id = id;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.split.SplittableResource#getFileSystemLoader()
+	 */
+	public DataLoader getLocalLoader() {
+		return this.intialDataLoader;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.split.SplittableResource#getID()
+	 */
+	public int getRootID() {
+		return this.id;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.split.SplittableResource#getPartition(java.awt.Rectangle)
+	 */
+	public WritableGridPartition getPartition(Rectangle partitionBounds) {
+		if (!loaded)
+			tryLoadingGrid();
+		return PartitionUtil.getPartitialGrid2D(this, partitionBounds,
+				getRootID());
+	}
+
+	/**
+	 * Overwrites the data at the location specified by the {@link Rectangle}
+	 * with the given partition-data.
+	 *
+	 * @param partition
+	 *            the grid to be inserted which MUST be an instance of
+	 *            {@link WritableGrid}!
+	 * @param partitionBounds
+	 *            the target location of the data
+	 * @see appl.parallel.spmd.split.DataPartition#setPartition(DataPartition,
+	 *      java.awt.Rectangle)
+	 */
+	public void setPartition(DataPartition partition, Rectangle partitionBounds) {
+		if (!loaded)
+			tryLoadingGrid();
+		if (!(partition instanceof WritableGrid))
+			throw new UnsupportedOperationException(
+					"The partition must be an instance of WritableGrid!");
+		PartitionUtil.setPartition(this, (WritableGrid) partition,
+				partitionBounds);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.split.SplittableResource#getSplitHeight()
+	 */
+	public int getSplitHeight() {
+		return this.getHeight();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.split.SplittableResource#getSplitWidth()
+	 */
+	public int getSplitWidth() {
+		return this.getWidth();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.split.DataPartition#getPartitionBounds()
+	 */
+	public Rectangle getPartitionBounds() {
+		return new Rectangle(0, 0, this.getWidth(), this.getHeight());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.split.DataPartition#getEmpty()
+	 */
+	public DataPartition getEmpty(int id) {
+		return new SplittableLLProxyGrid(this.metaData, id);
+	}
+
+}

Added: trunk/src/appl/parallel/data/splittable/package.html
===================================================================
--- trunk/src/appl/parallel/data/splittable/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/splittable/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,7 @@
+<html>
+<body>
+	The SplittableLLProxyGrid is an extension to the WritableGridLLProxyGrid for use with parallelization.
+	The new class can handle partition of itself properly. The other classes are all xulu-specific factory classes
+	required for all data types which should be used in the Xulu-Application.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/data/xulugridfile/BufferedHelper.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/BufferedHelper.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/BufferedHelper.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,91 @@
+package appl.parallel.data.xulugridfile;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+// fuer Doku
+import java.io.RandomAccessFile;
+
+/**
+ * The methods of this class can be used to efficiently read or write values
+ * into a Bytestream (it is e.g. used by the {@link XuluGridFile}).
+ *
+ * @author Dominik Appl
+ *
+ */
+public class BufferedHelper {
+
+	/**
+	 * Reads a long value out of the given bytestream Used for buffered reading.
+	 * Used the code of {@link RandomAccessFile#readInt()}
+	 *
+	 * @exception IOException
+	 *                if an I/O error occurs.
+	 */
+	public static final int readIntFromStream(ByteArrayInputStream input)
+			throws IOException {
+		int ch1 = input.read();
+		int ch2 = input.read();
+		int ch3 = input.read();
+		int ch4 = input.read();
+		if ((ch1 | ch2 | ch3 | ch4) < 0)
+			throw new EOFException();
+		return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
+	}
+
+	/**
+	 * Writes a int value in the the given bytestream Used for buffered writing.
+	 * Used the code of {@link RandomAccessFile#writeInt(int)}
+	 *
+	 * @exception IOException
+	 *                if an I/O error occurs.
+	 *
+	 */
+	public static final void writeInt(int v, ByteArrayOutputStream output)
+			throws IOException {
+		output.write((v >>> 24) & 0xFF);
+		output.write((v >>> 16) & 0xFF);
+		output.write((v >>> 8) & 0xFF);
+		output.write((v >>> 0) & 0xFF);
+		// written += 4;
+	}
+
+	/**
+	 * Writes a <code>long</code> to the stream as eight bytes, high byte
+	 * first. The write starts at the current position of the file pointer. Used
+	 * for buffered writing. Used the code of
+	 * {@link RandomAccessFile#writeLong(long)}
+	 *
+	 * @param output the stream to be written to
+	 * @param v
+	 *            a <code>long</code> to be written.
+	 * @exception IOException
+	 *                if an I/O error occurs.
+	 */
+	public static final void writeLong(long v, ByteArrayOutputStream output)
+			throws IOException {
+		output.write((int) (v >>> 56) & 0xFF);
+		output.write((int) (v >>> 48) & 0xFF);
+		output.write((int) (v >>> 40) & 0xFF);
+		output.write((int) (v >>> 32) & 0xFF);
+		output.write((int) (v >>> 24) & 0xFF);
+		output.write((int) (v >>> 16) & 0xFF);
+		output.write((int) (v >>> 8) & 0xFF);
+		output.write((int) (v >>> 0) & 0xFF);
+		// written += 8;
+	}
+
+	/**
+	 * Reads a long value out of the given {@link ByteArrayInputStream}. Used for buffered
+	 * reading. Used the code of {@link RandomAccessFile#readLong()} *
+	 *
+	 * @exception IOException
+	 *                if an I/O error occurs.
+	 */
+	public static final long readLongFromStream(ByteArrayInputStream input)
+			throws IOException {
+		return ((long) (readIntFromStream(input) << 32) + (readIntFromStream(input) & 0xFFFFFFFFL));
+	}
+
+}

Added: trunk/src/appl/parallel/data/xulugridfile/BufferedRandomAccessFile.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/BufferedRandomAccessFile.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/BufferedRandomAccessFile.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,130 @@
+package appl.parallel.data.xulugridfile;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * Copied from java world.
+ * 
+ * See http://www.javaworld.com/javaworld/javatips/jw-javatip26.html
+ * 
+ * @author Nick Zhang
+ * 
+ */
+public class BufferedRandomAccessFile extends RandomAccessFile {
+
+	byte buffer[];
+
+	int buf_end = 0;
+
+	int buf_pos = 0;
+
+	long real_pos = 0;
+
+	private int BUF_SIZE;
+
+	public BufferedRandomAccessFile(String filename, String mode, int bufsize)
+			throws IOException {
+		super(filename, mode);
+		invalidate();
+		BUF_SIZE = bufsize;
+		buffer = new byte[BUF_SIZE];
+	}
+
+	public final int read() throws IOException {
+		if (buf_pos >= buf_end) {
+			if (fillBuffer() < 0)
+				return -1;
+		}
+		if (buf_end == 0) {
+			return -1;
+		} else {
+			return buffer[buf_pos++];
+		}
+	}
+
+	private int fillBuffer() throws IOException {
+		int n = super.read(buffer, 0, BUF_SIZE);
+		if (n >= 0) {
+			real_pos += n;
+			buf_end = n;
+			buf_pos = 0;
+		}
+		return n;
+	}
+
+	private void invalidate() throws IOException {
+		buf_end = 0;
+		buf_pos = 0;
+		real_pos = super.getFilePointer();
+	}
+
+	public int read(byte b[], int off, int len) throws IOException {
+		int leftover = buf_end - buf_pos;
+		if (len <= leftover) {
+			System.arraycopy(buffer, buf_pos, b, off, len);
+			buf_pos += len;
+			return len;
+		}
+		for (int i = 0; i < len; i++) {
+			int c = this.read();
+			if (c != -1)
+				b[off + i] = (byte) c;
+			else {
+				return i;
+			}
+		}
+		return len;
+	}
+
+	public long getFilePointer() throws IOException {
+		long l = real_pos;
+		return (l - buf_end + buf_pos);
+	}
+
+	public void seek(long pos) throws IOException {
+		int n = (int) (real_pos - pos);
+		if (n >= 0 && n <= buf_end) {
+			buf_pos = buf_end - n;
+		} else {
+			super.seek(pos);
+			invalidate();
+		}
+	}
+
+	/**
+	 * return a next line in String 
+	 */
+	public final String getNextLine() throws IOException {
+		String str = null;
+		if (buf_end - buf_pos <= 0) {
+			if (fillBuffer() < 0) {
+				throw new IOException("error in filling buffer!");
+			}
+		}
+		int lineend = -1;
+		for (int i = buf_pos; i < buf_end; i++) {
+			if (buffer[i] == '\n') {
+				lineend = i;
+				break;
+			}
+		}
+		if (lineend < 0) {
+			StringBuffer input = new StringBuffer(256);
+			int c;
+			while (((c = read()) != -1) && (c != '\n')) {
+				input.append((char) c);
+			}
+			if ((c == -1) && (input.length() == 0)) {
+				return null;
+			}
+			return input.toString();
+		}
+		if (lineend > 0 && buffer[lineend - 1] == '\r')
+			str = new String(buffer, 0, buf_pos, lineend - buf_pos - 1);
+		else
+			str = new String(buffer, 0, buf_pos, lineend - buf_pos);
+		buf_pos = lineend + 1;
+		return str;
+	}
+}

Added: trunk/src/appl/parallel/data/xulugridfile/GridFileDataLoader.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/GridFileDataLoader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/GridFileDataLoader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,46 @@
+package appl.parallel.data.xulugridfile;
+
+import schmitzm.data.WritableGrid;
+import appl.data.DataLoader;
+import appl.data.LoadingException;
+
+/**
+ * This {@link DataLoader} is responsible to load data from a
+ * {@link XuluGridFile}. When {@link #load()} is called it tries to load the
+ * whole(!) grid into the memory. Notice that using this loader will destroy all
+ * memory advantages of the {@link XuluGridFile}. It is intended as standard loader in
+ * the xulu application. The user can therefore force the loading of the grid
+ * into the local memory e.g. for visualization.
+ * 
+ * @author Dominik Appl
+ */
+public class GridFileDataLoader implements DataLoader {
+
+	private final XuluGridFile gridFile;
+
+	public GridFileDataLoader(XuluGridFile gridFile) {
+		this.gridFile = gridFile;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.data.DataLoader#getLoadInfo()
+	 */
+	public String getLoadInfo() {
+		// TODO Auto-generated method stub
+		return "Loading gridfile " + gridFile.getOutputFile().getPath() + ". ";
+	}
+
+	/** loads the whole grid into memory and returns it
+	 * @see appl.data.DataLoader#load()
+	 */
+	public WritableGrid load() throws LoadingException {
+		try {
+			return gridFile.getWholeGrid();
+		} catch (XuluGridFileException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+}

Added: trunk/src/appl/parallel/data/xulugridfile/XuluGridFile.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/XuluGridFile.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/XuluGridFile.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,670 @@
+package appl.parallel.data.xulugridfile;
+
+import java.awt.Rectangle;
+import java.awt.image.DataBuffer;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.RandomAccessFile;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+import appl.parallel.data.WritableGridArrayPartition;
+import appl.parallel.spmd.split.SplittableResource;
+import appl.parallel.spmd.split.WritableGridPartition;
+import appl.util.RasterMetaData;
+
+/**
+ * A XuluGridfile is a memory- and 2D-access optimized file format
+ * which can be used for parallel programming. All data is accessed
+ * on disk only (and not loaded into memory).
+ * For this the data is stored in a special uncompressed format.<p/>
+ *
+ * The values are stored line by line in the GridFile. The result is, that
+ * every value is stored at a well known position in the file,
+ * so that the position of the value in the file can be calculated.
+ * Because of this it is not necessary to search the file for a value
+ * of a given coordinate.<br>
+ * If a partition is requested it is possible to read the data directly from
+ * the file.<p/>
+ *
+ * The filename of the XuluGridFile must end with ".xgrid"
+ * The metadata of the gird is stored in a separate file with the same name in
+ * the same directory ending with ".xworld".<p/>
+ *
+ * The XuluGridFile is buffered, it can handle Float, Double and Int values.
+ * To create a XuluGridFile you can use {@link #XuluGridFile(File, RasterMetaData) this} constructor, or
+ * you can convert an existing Grid into the {@link XuluGridFile} format using
+ * the {@link XuluGridFileConverter}.<p/>
+ *
+ * A monitor is used to guarantee that only one XuluGridFile is accessed at a time.
+ * This guarantees a high disk performance.<p/>
+ *
+ * For use in the XuluPlatform you can use the {@link XuluWritableGridFile}, which
+ * implements the {@link WritableGrid} interface.<p/>
+ *
+ *
+ * @author Dominik Appl
+ *
+ */
+public class XuluGridFile {
+
+	protected RandomAccessFile gridFile = null;
+
+	protected RasterMetaData metaData = null;
+
+	//length of one datavalue in bytes
+	private int dataValueSize = 4;
+
+	//buffer of 256 kb
+	private int buffersize = 262144;
+
+	private final File outputFile;
+
+	//the monitor is used to guarantee that only one XuluGridFile is accessed at a time
+	private static Object monitor = new Object();
+
+	/**
+	 * Opens an <b>existing</b> Xulu Grid File. The File must have the ending ".xgrid" and there
+	 * must be a xuluGrid world file in the same directory with the ending ".xworld"
+	 *
+	 * @param file the filename to read from and write to
+	 * @param mode the input mode as specified at {@link RandomAccessFile#RandomAccessFile(java.lang.String, java.lang.String)}
+	 * <blockquote><table summary="Access mode permitted values and meanings">
+	 *<tr><th><p align="left">Value</p></th><th><p align="left">Meaning</p></th></tr>
+	 *<tr><td valign="top"><tt>"r"</tt></td>
+	 *    <td> Open for reading only.  Invoking any of the <tt>write</tt>
+	 *    methods of the resulting object will cause an <A HREF="../../java/io/IOException.html" title="class in java.io"><CODE>IOException</CODE></A> to be thrown. </td></tr>
+	 *
+	 *<tr><td valign="top"><tt>"rw"</tt></td>
+	 *    <td> Open for reading and writing.  If the file does not already
+	 *    exist then an attempt will be made to create it. </td></tr>
+	 *<tr><td valign="top"><tt>"rws"</tt></td>
+	 *    <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
+	 *    require that every update to the file's content or metadata be
+	 *    written synchronously to the underlying storage device.  </td></tr>
+	 *<tr><td valign="top"><tt>"rwd"&nbsp;&nbsp;</tt></td>
+	 *     <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
+	 *    require that every update to the file's content be written
+	 *    synchronously to the underlying storage device. </td></tr>
+	 *</table></blockquote>
+	 *
+	 * @throws FileNotFoundException
+	 * @see RandomAccessFile
+	 * */
+	public XuluGridFile(File file, String mode) throws FileNotFoundException,
+			XuluGridFileException {
+		outputFile = file;
+		checkFileName(file);
+		try {
+			//gridFile = new BufferedRandomAccessFile(file.getAbsolutePath(), mode, buffersize);
+			gridFile = new RandomAccessFile(file.getAbsolutePath(), mode);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		String worldFileName = file.getAbsolutePath().replaceAll(".xgrid$",
+				".xworld");
+		this.metaData = readXuluGridWorldFile(new File(worldFileName));
+	}
+
+	/**
+	 * Opens an<b> existing</b> gridfile in read/write mode.
+	 *
+	 * @param file the existing XuluGridFile to be opened
+	 * @throws FileNotFoundException
+	 * @throws XuluGridFileException
+	 */
+	public XuluGridFile(File file) throws FileNotFoundException,
+			XuluGridFileException {
+		this(file, "rw");
+	}
+
+	/**
+	 * Creates a <b>NEW</b> File with the sample given as {@link RasterMetaData}
+	 * @param targetFile the file the new grid will be written to. <b>Has to end with ".xgrid"!</b>
+	 * @param metaData the metadata of the new grid. Width and height are used to allocate the space for the new XGrid.
+	 * @throws XuluGridFileException
+	 */
+	public XuluGridFile(File targetFile, RasterMetaData metaData)
+			throws XuluGridFileException {
+		outputFile = targetFile;
+		this.metaData = metaData;
+		checkFileName(targetFile);
+		writeWorldFileForMetaData(targetFile, metaData);
+		setByteLength(metaData);
+		try {
+			//gridFile = new BufferedRandomAccessFile(targetFile.getAbsolutePath(), "rw",buffersize );
+			gridFile = new RandomAccessFile(targetFile.getAbsolutePath(), "rw");
+			//allocate space by extending the file
+			gridFile.setLength(metaData.getWidth() * metaData.getHeight()
+					* dataValueSize);
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * Sets the bytelength (4 bytes for float/int, 8 for double)
+	 *
+	 * @param meta the metadata object of the grid
+	 * @throws XuluGridFileException
+	 */
+	private void setByteLength(RasterMetaData meta)
+			throws XuluGridFileException {
+		switch (metaData.getDataType()) {
+		case DataBuffer.TYPE_DOUBLE:
+			dataValueSize = 8;
+			break;
+		case DataBuffer.TYPE_FLOAT:
+		case DataBuffer.TYPE_INT:
+			dataValueSize = 4;
+			break;
+		default:
+			throw new XuluGridFileException(
+					"XuluGridFile supports only float,double and int Datatypes!");
+		}
+	}
+
+	/**
+	 * Creates a new XuluGridFile out of an existing Writable Grid and opens it in read-write mode. The {@link WritableGrid}-Method
+	 * {@link WritableGrid#getSampleType() getSampleType} is used to determine the type and
+	 * the bytelength (4 bytes for Float/Int and 8 bytes for doubleValues);
+	 * @param grid
+	 * @param output
+	 * @throws XuluGridFileException
+	 */
+	public XuluGridFile(WritableGrid grid, File output)
+			throws XuluGridFileException {
+		this.outputFile = output;
+		//make a new MetaData object out of the grid
+		RasterMetaData metaData = new RasterMetaData(grid);
+
+		setByteLength(metaData);
+
+		//write the metadata file
+		writeWorldFileForMetaData(output, metaData);
+
+		// Write out the GridFile (32Bit and float only until now)
+		// for this go through the Grid line by line upwards
+
+		try {
+			output.createNewFile();
+			gridFile = new BufferedRandomAccessFile(output.getAbsolutePath(),
+					"rw", buffersize);
+
+		    for (int y = metaData.getMinY(); y < metaData.getHeight()
+					- metaData.getMinY(); y++)
+				for (int x = metaData.getMinY(); x < metaData.getWidth()
+						- metaData.getMinX(); x++)
+					gridFile.writeFloat(grid.getRasterSampleAsFloat(x, y));
+
+		    gridFile.close();
+
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Returns a partition of a {@link WritableGrid} as a
+	 * {@link WritableGridArray}. Notice, that the minX and minY values are
+	 * ignored and will be set to 0 (see {@link WritableGrid} for more
+	 * information about minX and minY). If the given {@link WritableGrid} is
+	 * not an instance of {@link WritableGridPartition} it is assumed that the
+	 * topLeft corner of the source grid is (0,0). If it is a
+	 * {@link WritableGridPartition} it is assumed that the the bounds of the
+	 * two Partition refer to the same coordinate system. Real coordinates are
+	 * supposed to reference the South(!)-West Corner.
+	 *
+	 * @param partitionBounds
+	 *            the rectangle describing the partition
+	 *
+	 * @return the new partition including the given corners
+	 * @throws XuluGridFileException
+	 *             if the reading goes wrong
+	 */
+	public WritableGridPartition getPartitialGrid2D(
+			Rectangle partitionBounds) throws XuluGridFileException {
+		synchronized (monitor){
+
+		// get Metadata of the big Grid
+		RasterMetaData bigMeta = this.metaData;
+
+		// create MetaData for the new partitial Grid
+		// Height an width of the partitial Grid
+		int pHeight = (int) partitionBounds.getHeight();
+		int pWidth = (int) partitionBounds.getWidth();
+
+		// real coordinates of the partitial Grid (which are referenced by the
+		// SW Corner)
+		double pX = partitionBounds.getX() * bigMeta.getCellWidth()
+				+ bigMeta.getX();
+		double pY = (partitionBounds.getY() + partitionBounds.getHeight() - 1)
+				* bigMeta.getCellHeight() + bigMeta.getY();
+		double pRealWidth = pWidth * bigMeta.getCellWidth();
+		double pRealHeight = pHeight * bigMeta.getCellHeight();
+
+		// the MetaData of the new Grid
+		RasterMetaData pMetaData = new RasterMetaData(bigMeta.getDataType(),
+				pWidth, pHeight, 0, 0, pX, pY, pRealWidth, pRealHeight, bigMeta.getCoordinateReferenceSystem());
+
+		// if the sourceGrid is a partition itself then we do not want to to
+		// start reading from (0,0)
+		// but shifted relative to the global coordinate system. So we calculate
+		// now the start values:
+
+		// for standard WritableGrids these are simply the bounds of the new
+		// partition...
+		int startX = (int) partitionBounds.getX();
+		int startY = (int) partitionBounds.getY();
+
+		try {
+			//seek to starting Position offset (= datavalues until startx)
+			long offset = ((startY) * metaData.getWidth() // number of rows to skip
+			+ startX) // number of Colums to skip
+					* dataValueSize; // length of one value in bytes
+			gridFile.seek(offset);
+			//the read-buffer is as wide as the grid (because we read line by line)
+			byte[] buffer = new byte[pWidth * dataValueSize];
+
+			// create empty return Grid
+			WritableGridPartition pGrid;
+
+			//switch structures are a bad smell, but necessary here because of the
+			//implementation of WritableGridArray
+			switch (bigMeta.getDataType()) {
+			case DataBuffer.TYPE_INT:
+				pGrid = new WritableGridArrayPartition.Integer(pMetaData,
+						getRootID(), partitionBounds);
+
+				// read the data into the raster from left to right and upwards
+				for (int y = 0; y < pHeight; y++) {
+					//for buffered reading read first into a bytearray
+					gridFile.read(buffer);
+					ByteArrayInputStream stream = new ByteArrayInputStream(
+							buffer);
+					for (int x = 0; x < pWidth; x++) {
+						int data = BufferedHelper.readIntFromStream(stream);
+						pGrid.setRasterSample(data, x, y);
+					}
+					//seek to the next input position (if not last row)
+					int seek = (metaData.getWidth() - pWidth) * dataValueSize;
+					if (!(y == pHeight - 1))
+						gridFile.skipBytes(seek);
+				}
+				break;
+
+			case DataBuffer.TYPE_DOUBLE:
+				pGrid = new WritableGridArrayPartition.Double(pMetaData,
+						getRootID(), partitionBounds);
+
+				// read the data into the raster from left to right and upwards
+				for (int y = 0; y < pHeight; y++) {
+					//for buffered reading read first into a bytearray
+					gridFile.read(buffer);
+					ByteArrayInputStream stream = new ByteArrayInputStream(
+							buffer);
+
+					for (int x = 0; x < pWidth; x++) {
+						double data = Double.longBitsToDouble(BufferedHelper
+								.readLongFromStream(stream));
+						pGrid.setRasterSample(data, x, y);
+					}
+					//seek to the next input position (if not last row)
+					int seek = (metaData.getWidth() - pWidth) * dataValueSize;
+					if (!(y == pHeight - 1))
+						gridFile.skipBytes(seek);
+				}
+				break;
+
+			case DataBuffer.TYPE_FLOAT:
+				pGrid = new WritableGridArrayPartition.Float(pMetaData,
+						getRootID(), partitionBounds);
+
+				// read the data into the raster from left to right and downwards
+				System.out.print("[getX]");
+				for (int y = 0; y < pHeight; y++) {
+					//for buffered reading read first into a bytearray
+					gridFile.read(buffer);
+					ByteArrayInputStream stream = new ByteArrayInputStream(
+							buffer);
+
+					for (int x = 0; x < pWidth; x++) {
+						float data = Float.intBitsToFloat(BufferedHelper
+								.readIntFromStream(stream));
+						pGrid.setRasterSample(data, x, y);
+					}
+
+					// seek to the next input position (if not last row)
+					int seek = (metaData.getWidth() - pWidth) * dataValueSize;
+					if (!(y == pHeight - 1)) {
+						long currentOffset = gridFile.getFilePointer();
+						if (currentOffset + seek > gridFile.length())
+							System.err.println("Error: offset was "
+									+ gridFile.getFilePointer()
+									+ " and seek was " + seek
+									+ " but file has only " + gridFile.length()
+									+ " bytes");
+						gridFile.skipBytes(seek);
+					}
+				}
+				break;
+			default:
+				throw new UnsupportedOperationException("No value found");
+			}
+			return pGrid;
+
+		} catch (IOException e) {
+
+			throw new XuluGridFileException(
+					"IOException while operating on XuluGridFile. Reason was: \n"
+							+ e.getCause());
+		}
+		}
+	}
+
+	/**
+	 *  @return the hashcode of this object
+	 *  @see SplittableResource#getRootID()
+	 */
+	public int getRootID() {
+		return this.hashCode();
+	}
+
+	/**
+	 * Overwrites the data at the location specified by the {@link Rectangle} with
+	 * the given partition-data. It is assumed that the topLeft corner is (0,0).
+	 * The method is synchronized over a static variable to ensure that only
+	 * one XuluGridFile is read/write at a time. This reduces (hopefully) harddisk
+	 * seek times and increases the overall performance.
+	 *
+	 * @param gridPartition the grid to be inserted
+	 * @param partitionBounds the excact location in coordinates of the baseGrid
+	 * @throws XuluGridFileException if the writing goes wrong
+	 */
+	public void setPartition(WritableGrid gridPartition,
+			Rectangle partitionBounds) throws XuluGridFileException {
+		synchronized (monitor){
+		//Check if partition and the rectangle fit
+		if ((gridPartition.getWidth() != partitionBounds.getWidth())
+				|| (gridPartition.getHeight() != partitionBounds.getHeight()))
+			throw new UnsupportedOperationException(
+					"The partition width/height does not match the rectangle width/height");
+
+		if (this.metaData.getDataType() != gridPartition.getSampleType())
+			throw new UnsupportedOperationException("Datatypes incompatible: "
+					+ this.metaData.getDataType() + "!="
+					+ gridPartition.getSampleType());
+		//the start coodinates
+		int startX = (int) partitionBounds.getX();
+		int startY = (int) partitionBounds.getY();
+		int pHeight = (int) partitionBounds.getHeight();
+		int pWidth = (int) partitionBounds.getWidth();
+
+		try {
+			//			seek to starting Position offset = datavalues until startx
+			long offset = ((startY) * metaData.getWidth() // number of rows to skip
+			+ startX) // number of Colums to skip
+					* dataValueSize; // length of one value in bytes
+			gridFile.seek(offset);
+			//the buffer is exactly as wide as the grid
+			ByteArrayOutputStream bos = new ByteArrayOutputStream(dataValueSize
+					* pWidth);
+
+			switch (this.metaData.getDataType()) {
+			case DataBuffer.TYPE_FLOAT:
+				System.out.print("[setX]");
+				for (int y = 0; y < pHeight; y++) {
+					for (int x = 0; x < pWidth; x++) {
+						float data = gridPartition.getRasterSampleAsFloat(x, y);
+						BufferedHelper
+								.writeInt(Float.floatToIntBits(data), bos);
+					}
+					//write buffered bytes to file
+					gridFile.write(bos.toByteArray());
+					//clear the bos
+					bos.reset();
+					// seek to the next input position
+					gridFile.skipBytes((metaData.getWidth() - pWidth)
+							* dataValueSize);
+				}
+				break;
+			case DataBuffer.TYPE_INT:
+				for (int y = 0; y < pHeight; y++) {
+					for (int x = 0; x < pWidth; x++) {
+						int data = gridPartition.getRasterSampleAsInt(x, y);
+						this.gridFile.writeInt(data);
+					}
+					// seek to the next input position
+					gridFile.skipBytes((metaData.getWidth() - pWidth)
+							* dataValueSize);
+				}
+				break;
+			case DataBuffer.TYPE_DOUBLE:
+				for (int y = 0; y < pHeight; y++) {
+					for (int x = 0; x < pWidth; x++) {
+						double data = gridPartition.getRasterSampleAsDouble(x,
+								y);
+						this.gridFile.writeDouble(data);
+					}
+					// seek to the next input position
+					gridFile.skipBytes((metaData.getWidth() - pWidth)
+							* dataValueSize);
+				}
+			}
+
+		} catch (Exception e) {
+			throw new XuluGridFileException(
+					"Error while writing in XuluGridFile");
+		}
+		}
+	}
+
+	/**
+	 * Closes all used Filehandles. Should be called before destroying the
+	 * object.
+	 */
+	public void close() {
+		try {
+			gridFile.close();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+
+	/**
+	 * @return the metadata for this object
+	 */
+	public RasterMetaData getMetaData() {
+		return metaData;
+	}
+
+	/**
+	 * The Xulu world file ist just a serialized RasterMetaData-Object!
+	 *
+	 * @param worldFile the world file
+	 * @return a {@link RasterMetaData} Object, that contains all the raster meta data
+	 * @throws XuluGridFileException if an error occures
+	 */
+	public RasterMetaData readXuluGridWorldFile(File worldFile)
+			throws XuluGridFileException {
+		try {
+			FileInputStream fis = new FileInputStream(worldFile);
+			ObjectInputStream ois = new ObjectInputStream(fis);
+			RasterMetaData meta = (RasterMetaData) ois.readObject();
+			ois.close();
+			fis.close();
+			return meta;
+
+		} catch (IOException e) {
+			throw new XuluGridFileException(
+					"IOException while reading Worldfile"
+							+ worldFile.toString());
+		} catch (ClassNotFoundException e) {
+			throw new XuluGridFileException(
+					"ClassNotFoundException while reading Worldfile"
+							+ worldFile.toString());
+		}
+	}
+
+	/**
+	 * Writes the given Grid to a XuluGridFile. Warning: unbuffered write.
+	 *
+	 * @param grid the input grid
+	 * @param output the output file
+	 * @throws XuluGridFileException if something goes wrong
+	 */
+	public static void writeToXuluGridFile(WritableGrid grid, File output)
+			throws XuluGridFileException {
+		RasterMetaData metaData = new RasterMetaData(grid);
+
+		writeWorldFileForMetaData(output, metaData);
+
+		// Write out the GridFile (32Bit and float only until now)
+		// for this go through the Grid line by line upwards
+
+		try {
+			output.createNewFile();
+			RandomAccessFile randomFile = new RandomAccessFile(output, "rw");
+			//              fos = new FileOutputStream(output);
+			//            BufferedOutputStream bos = new BufferedOutputStream(fos);
+			//            ObjectOutputStream oos = new ObjectOutputStream(bos);
+			for (int y = metaData.getMinY(); y < metaData.getHeight()
+					- metaData.getMinY(); y++)
+				for (int x = metaData.getMinY(); x < metaData.getWidth()
+						- metaData.getMinX(); x++)
+					randomFile.writeFloat(grid.getRasterSampleAsFloat(x, y));
+			//            oos.close();
+			//            bos.close();
+			//            fos.close();
+			randomFile.close();
+
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Writes data out of a XuluGridFile into a {@link WritableGrid}. Warning: unbuffered. May be slow.
+	 * For buffered read use {@link #getWholeGrid()} instead.
+	 * @param grid the Grid in which the data should be written
+	 * @param input the File with the XuluGridFile
+	 *
+	 * */
+	public static void readIntoGridFromXuluGridFile(WritableGrid grid,
+			File input) throws XuluGridFileException {
+		synchronized (monitor) {
+
+		RasterMetaData metaData = new RasterMetaData(grid);
+
+		// Read from File into the given grid
+
+		try {
+			RandomAccessFile randomFile = new RandomAccessFile(input, "r");
+			for (int y = metaData.getMinY(); y < metaData.getHeight()
+					- metaData.getMinY(); y++)
+				for (int x = metaData.getMinY(); x < metaData.getWidth()
+						- metaData.getMinX(); x++)
+					grid.setRasterSample(randomFile.readFloat(), x, y);
+
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		}
+	}
+
+	/**
+	 * This File simply serializes the given {@link appl.util.RasterMetaData}
+	 * Object to the given file.
+	 */
+	public static void writeWorldFileForMetaData(File XuluGridFile,
+			RasterMetaData meta) throws XuluGridFileException {
+		try {
+			File xuluWorldFile = getWorldFileNameForGridFile(XuluGridFile);
+			xuluWorldFile.createNewFile();
+			FileOutputStream fos = new FileOutputStream(xuluWorldFile);
+			ObjectOutputStream oos = new ObjectOutputStream(fos);
+			oos.writeObject(meta);
+			oos.close();
+			fos.close();
+		} catch (FileNotFoundException e) {
+			throw new XuluGridFileException(
+					"Exception while processing WorldFile of XuluGridFile "
+							+ XuluGridFile);
+		} catch (IOException e) {
+			throw new XuluGridFileException(
+					"Exception while processing WorldFile of XuluGridFile "
+							+ XuluGridFile);
+		}
+	}
+
+
+	/**
+	 * Returns a worldfilename. For this the extension xgrid is replaced by xworld
+	 */
+	private static File getWorldFileNameForGridFile(File xuluGridFile)
+			throws XuluGridFileException {
+		checkFileName(xuluGridFile);
+		// create worldfilename by exchanging the file extension
+		File worldFile = new File(xuluGridFile.getAbsolutePath().replaceAll(
+				".xgrid$", ".xworld"));
+		return worldFile;
+	}
+
+	/**
+	 * Checks if the given filename is a valid grid file name. To be valid the name must end with .xgrid
+	 * @param xuluGridFile the file to be checked
+	 * @throws XuluGridFileException if this is not the case
+	 *
+	 */
+	static void checkFileName(File xuluGridFile) throws XuluGridFileException {
+		if (!xuluGridFile.getAbsolutePath().endsWith(".xgrid"))
+			throw new XuluGridFileException(
+					"XuluGridFiles must have the extension \".xgrid\"");
+
+	}
+
+	/**
+	 * gives back the whole grid as a {@link WritableGridArray} in memory! Notice
+	 * that this destroys all memory advantages of the GridFile. Is used e.g. by visualisation classes
+	 *
+	 */
+	public WritableGrid getWholeGrid() throws XuluGridFileException {
+		return getPartitialGrid2D(new Rectangle(0, 0, metaData.getWidth(),
+				metaData.getHeight()));
+	}
+
+	/**
+	 * @return the underlying file
+	 */
+	public File getOutputFile() {
+		return outputFile;
+	}
+
+}

Added: trunk/src/appl/parallel/data/xulugridfile/XuluGridFileConverter.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/XuluGridFileConverter.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/XuluGridFileConverter.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,264 @@
+/*
+ *    Geotools2 - OpenSource mapping toolkit
+ *    http://geotools.org
+ *    (C) 2002, Geotools Project Managment Committee (PMC)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    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
+ *    Lesser General Public License for more details.
+ *
+ */
+package appl.parallel.data.xulugridfile;
+import org.geotools.gce.arcgrid.ArcGridRaster;
+import org.geotools.resources.NIOUtilities;
+
+import appl.util.RasterMetaData;
+
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.WritableRaster;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.io.RandomAccessFile;
+import java.io.Reader;
+import java.io.StreamTokenizer;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import javax.media.jai.RasterFactory;
+
+
+/**
+ * This class converts a ArcGridInfo_ASCII file to a {@link XuluGridFile}. It directly writes from
+ * the the ArcGridInfo to the given file. It does not use the memory!
+ *
+ * It is a modified geotools import class. Buffering was added.
+ *
+ * @author Dominik Appl <br>
+ * For reading this class is based partly on the Geotools class {@link ArcGridRaster}. This was
+ * done to make sure that EVERY ArcInfoASCII can be read. The used {@link ArcGridRaster} was created by <br>
+ * @author <a href="mailto:ckl at dacelo.nl">Christiaan ten Klooster</a>
+ * @author <a href="mailto:aaime at users.sf.net">Andrea Aime</a>
+ * @author <a href="mailto:simboss_ml at tiscali.it">Simone Giannecchini
+ *         (simboss)</a>
+ * @see XuluGridFile
+ * @see http://svn.geotools.org/geotools/tags/2.2.0/plugin/arcgrid/src/org/geotools/gce/arcgrid/ArcGridRaster.java
+ */
+
+public class XuluGridFileConverter extends ArcGridRaster {
+
+    protected final File inputArcInfoGrid;
+	protected final File outputXuluGridFile;
+
+	/**
+	 * @throws FileNotFoundException
+	 */
+	public XuluGridFileConverter(File inputArcInfoGrid, File outputXuluGridFile) throws FileNotFoundException {
+		super(new BufferedReader(new InputStreamReader(new FileInputStream(inputArcInfoGrid))), false);
+		this.inputArcInfoGrid = inputArcInfoGrid;
+		this.outputXuluGridFile = outputXuluGridFile;
+	}
+
+
+   /**
+     * partly copied from Geotools. www.geotools.org.
+     *
+     * @param type the type of the values. Use the
+     * {@link DataBuffer} constants to identify the type
+     *
+     * @return the new XuluGridFile
+     *
+     * @throws IOException
+     * @throws XuluGridFileException
+     */
+    public XuluGridFile convertArcInfoToXuluGridFile(int type) throws IOException, XuluGridFileException {
+
+
+
+    	// open reader and make tokenizer
+        Reader reader = openReader();
+        StreamTokenizer st = new StreamTokenizer(reader);
+
+        // parse header
+        parseHeader(st);
+
+        //create metadata and outputFile
+        RasterMetaData meta = new RasterMetaData(type,getNCols(),getNRows(),0,0,getXlCorner(),getYlCorner(),getCellSize(),null);
+        RandomAccessFile outputFile = new RandomAccessFile(outputXuluGridFile,"rw");
+
+        // reconfigure tokenizer
+        st.resetSyntax();
+        st.parseNumbers();
+        st.whitespaceChars(' ', ' ');
+        st.whitespaceChars(' ', '\t');
+        st.whitespaceChars('\n', '\n');
+        st.whitespaceChars('\r', '\r'); //linefeed (on windows only?)
+        st.whitespaceChars('\f', '\f'); //form feed (on printers????)
+        st.eolIsSignificant(false);
+        st.ordinaryChars('E', 'E');
+
+
+
+        // Read values from grid and put into raster.
+        // Values must be numbers, which may be simple <num>, or expressed
+        // in scientific notation <num>E<exp>.
+        // The following loop can read both, even if mixed.
+        // The loop expects a token to be read already
+        st.nextToken();
+
+
+        for (int y = 0; y < getNRows(); y++) {
+        	ByteArrayOutputStream baos;
+        	if(type == DataBuffer.TYPE_DOUBLE)
+        		baos = new ByteArrayOutputStream(getNCols()*8);
+        	else
+        		baos = new ByteArrayOutputStream(getNCols()*4);
+
+        	for (int x = 0; x < getNCols(); x++) {
+                // this call always reads the next token
+                double d = readCell(st, x, y);
+
+                // mask no data values with NaN
+                if (d == getNoData()) {
+                    d = Double.NaN;
+                } else {
+                    minValue = Math.min(minValue, d);
+                    maxValue = Math.max(maxValue, d);
+                }
+                switch(type){
+                case DataBuffer.TYPE_FLOAT:
+                	BufferedHelper.writeInt(Float.floatToIntBits((float)d),baos);
+                break;
+                case DataBuffer.TYPE_DOUBLE:
+                	BufferedHelper.writeLong(Double.doubleToLongBits(d),baos);
+                case DataBuffer.TYPE_INT:
+                	BufferedHelper.writeInt((int)d,baos);
+                break;
+                default:
+                	throw new UnsupportedOperationException("Unsupported datatype");
+            }
+                outputFile.write(baos.toByteArray());
+                baos.reset();
+        }
+        }
+        reader.close();
+        try {
+			XuluGridFile.writeWorldFileForMetaData(outputXuluGridFile, meta);
+		} catch (XuluGridFileException e) {
+			throw new IOException ("Could not write WorldFile");
+		}
+        return new XuluGridFile(outputXuluGridFile,"rw");
+    }
+
+    /**
+     *copied unmodified form superclass (had to be copied, because the geotools method was private)
+     */
+    private double readCell(StreamTokenizer st, int x, int y)
+        throws IOException {
+        double d = 0;
+
+        // read a token, expected: a number
+        switch (st.ttype) {
+        case StreamTokenizer.TT_NUMBER:
+            d = (float) st.nval;
+
+            break;
+
+        case StreamTokenizer.TT_EOF:
+            throw new IOException("Unexpected EOF at " + x + "," + y);
+
+        default:
+            throw new IOException("Unknown token " + st.ttype);
+        }
+
+        // read another. May be an exponent of this number.
+        // If its not an exponent, its the next number. Fall through
+        // and token is prefetched for next loop...
+        switch (st.nextToken()) {
+        case 'e':
+        case 'E':
+
+            // now read the exponent
+            st.nextToken();
+
+            if (st.ttype != StreamTokenizer.TT_NUMBER) {
+                throw new IOException("Expected exponent at " + x + "," + y);
+            }
+
+            // calculate
+            d = d * Math.pow(10.0, st.nval);
+
+            // prefetch for next loop
+            st.nextToken();
+
+            break;
+
+        case StreamTokenizer.TT_NUMBER:
+        case StreamTokenizer.TT_EOF:
+            break;
+
+        default:
+            throw new IOException("Expected Number or EOF");
+        }
+
+        return d;
+    }
+
+   /** You can use this method to manually convert datatypes
+ * @param args
+ */
+public static void main(String[] args) {
+	   int type=DataBuffer.TYPE_FLOAT;
+	   if((args.length!=2 && args.length!=3)){
+		   parameterMessage();
+	   return;
+	   }
+	   if(!args[1].endsWith(".xgrid")){
+		   parameterMessage();
+		   return;
+	   }
+	   if(args.length==3){
+			if(args[2].equals("INT"))
+				type=DataBuffer.TYPE_INT;
+	   		if(args[2].equals("DOUBLE"))
+	   			type = DataBuffer.TYPE_DOUBLE;
+   		}
+		XuluGridFileConverter converter;
+		try {
+			converter = new XuluGridFileConverter(new File(args[0]),new File(args[1]));
+			converter.convertArcInfoToXuluGridFile(type);
+		} catch (FileNotFoundException e) {
+			System.out.println("Could not find file " + args[0]);
+		} catch (IOException e) {
+			System.out.println("IOException while converting: " + e.getMessage());
+		} catch (XuluGridFileException e) {
+			System.out.println("XuluGridFileException while converting: " + e.getMessage());
+		}
+
+
+   }
+   public static void parameterMessage(){
+   System.out.println("Syntax: XuluGridFileConverter Source Target [type], where \n" +
+   		"Source = a raster in the ArcInfo_ASCII format \n" +
+   		"Target = the new XuluGridFile with the extension .xgrid \n" +
+   		"[type] = (optional) the type of the XuluGridFile. Possible Values: INT,FLOAT,DOUBLE\n" +
+   		" default type is FLOAT");
+   }
+}
+

Added: trunk/src/appl/parallel/data/xulugridfile/XuluGridFileException.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/XuluGridFileException.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/XuluGridFileException.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,14 @@
+package appl.parallel.data.xulugridfile;
+
+/**
+ * Is thrown if an error inside the XuluGridFile occours.
+ * 
+ * @author Dominik Appl
+ */
+public class XuluGridFileException extends Exception {
+
+    public XuluGridFileException(String message) {
+       super(message);// TODO Auto-generated constructor stub
+    }
+
+}

Added: trunk/src/appl/parallel/data/xulugridfile/XuluGridSharedFileSystemLoader.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/XuluGridSharedFileSystemLoader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/XuluGridSharedFileSystemLoader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,133 @@
+package appl.parallel.data.xulugridfile;
+
+import java.awt.Rectangle;
+import java.io.File;
+import java.rmi.RemoteException;
+
+import appl.data.LoadingException;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.data.AbstractDataHandler;
+import appl.parallel.data.PartitionDataHandler;
+import appl.parallel.spmd.split.DataPartition;
+
+/**
+ * This is a loader for use with shared file systems like ocfs2 or gfs. It only
+ * works in conjunction with the {@link XuluWritableGridFile} and supports
+ * loading data from and into this file format. That means reading and writing
+ * is done directly into the file. The Xulu GUI won't notice changes if you do not
+ * reload the XuluWritableGrid!
+ * 
+ * @see XuluGridFile
+ * @see XuluWritableGridFile
+ * @see PartitionDataHandler
+ * 
+ * @author Dominik Appl
+ */
+public class XuluGridSharedFileSystemLoader extends AbstractDataHandler{
+	
+	private String gridFileName;
+	private transient XuluWritableGridFile xuluWritableGridFile;
+	
+	/**
+	 * constructs a new {@link XuluGridSharedFileSystemLoader}. 
+	 * 
+	 * @param rootID
+	 *            the id of the data
+	 * @param client
+	 *            a spmd client which may be used to get metainformation on
+	 *            client side before transfering the loader to its destination
+	 * @param partitionBounds
+	 *            the bounds of the partition to be retrieved on server side
+	 * @param unloadBounds
+	 *            the bounds of the partition which is to be uploaded to the
+	 *            client after calculation (may only be the calculation area)
+	 */
+	public XuluGridSharedFileSystemLoader(int rootID, ClientDataServer client, Rectangle partitionBounds, Rectangle unloadBounds) {
+		super(rootID, client, partitionBounds, unloadBounds);
+		DataPartition partition;
+		try {
+			partition = client.getData(rootID);
+			if (partition instanceof XuluWritableGridFile) {
+				XuluWritableGridFile xwg = (XuluWritableGridFile) partition;
+				gridFileName = xwg.getGridFileName();
+			}
+			else throw new UnsupportedOperationException("This Dataloader can only be used XuluGridFiles");
+		} catch (RemoteException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	
+	/**
+	 * only used by {@link #clone()}
+	 */
+	private XuluGridSharedFileSystemLoader(int rootID, ClientDataServer spmdClient, Rectangle partitionBounds, Rectangle unloadBounds, String gridFileName) {
+		super(rootID, null, partitionBounds, unloadBounds);
+		this.gridFileName=gridFileName;
+	}
+
+	/**
+	 * Used for deserialization. Do not use for other purposes
+	 */
+	public XuluGridSharedFileSystemLoader() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.data.AbstractDataHandler#newInstance(int, appl.parallel.client.SPMDClient, java.awt.Rectangle, java.awt.Rectangle)
+	 */
+	public PartitionDataHandler newInstance(int rootID, ClientDataServer client, Rectangle partitionBounds, Rectangle unloadBounds) {
+		// TODO Auto-generated method stub
+		return new XuluGridSharedFileSystemLoader(rootID, client, partitionBounds, unloadBounds);
+	}
+	
+	/* (non-Javadoc)
+	 * @see appl.data.AbstractDataHandler#getLoadInfo()
+	 */
+	@Override
+	public String getLoadInfo() {
+		return "Trying to load " + gridFileName;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.data.AbstractDataHandler#getUnloadInfo()
+	 */
+	@Override
+	public String getUnloadInfo() {
+		return "Trying to unload " + gridFileName;
+	}
+
+	/** loads the data directly from the gridfile 
+	 * @see appl.parallel.data.AbstractDataHandler#load()
+	 */
+	@Override
+	public DataPartition load() throws LoadingException {
+		//load from the gridfile
+		if(xuluWritableGridFile==null)
+			xuluWritableGridFile = new XuluWritableGridFile(new File(gridFileName));
+		data =  xuluWritableGridFile.getPartition(partitionBounds);
+		return data;
+	}
+
+	/** unloads into the file! not into the Xulu-Client or anything!
+	 */
+	@Override
+	public void unload() {
+		//unload to the local file
+		if(xuluWritableGridFile==null)
+			xuluWritableGridFile = new XuluWritableGridFile(new File(gridFileName));
+//		 construct return grid only if necessary
+		DataPartition returnPartition = null;
+		if (unloadBounds.equals(data.getPartitionBounds()))
+			returnPartition = data;
+		else
+			returnPartition = data.getPartition(unloadBounds);
+		xuluWritableGridFile.setPartition(returnPartition, unloadBounds);
+	}
+	
+	public PartitionDataHandler clone() {
+		return new XuluGridSharedFileSystemLoader(rootID, spmdClient, this.partitionBounds,
+				this.unloadBounds, this.gridFileName);
+	}
+}

Added: trunk/src/appl/parallel/data/xulugridfile/XuluWritableGridFile.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/XuluWritableGridFile.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/XuluWritableGridFile.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,271 @@
+package appl.parallel.data.xulugridfile;
+
+import java.awt.Rectangle;
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import schmitzm.data.WritableGrid;
+
+import edu.bonn.xulu.appl.XuluRegistry;
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+import appl.data.DataLoader;
+import appl.data.WritableGridArrayLoader;
+import appl.data.WritableGridLLProxy;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.SplittableGrid;
+import appl.parallel.spmd.split.SplittableResource;
+import appl.util.RasterMetaData;
+
+/**
+ * An implementation of a WritableGrid based on a {@link XuluGridFile}.
+ * 
+ * @author Dominik Appl
+ */
+public class XuluWritableGridFile extends WritableGridLLProxy implements SplittableGrid{
+	
+	private XuluGridFile gridFile;
+	private boolean wasWriteAccessed = false;
+	private final String directory;
+	private int rootID = this.hashCode();
+	private final File baseFile;
+
+	/**
+	 * Opens the GridFile at the given destination
+	 * @param gridfileName the filename of the XuluGridfile
+	 * 
+	 */
+	public XuluWritableGridFile(File gridfileName) {
+		super(null);
+		this.baseFile = gridfileName;
+		try {
+			gridFile = new XuluGridFile(gridfileName);
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (XuluGridFileException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		this.metaData = gridFile.metaData;
+		this.intialDataLoader = new GridFileDataLoader(gridFile);
+		this.dataLoader = new GridFileDataLoader(gridFile);
+		directory = null;
+	}
+	
+	
+	/**
+	 * Creates NEW a GridFile in the given directory with the given metadata-sample
+	 * 
+	 * @param metaData the metadata
+	 */
+	public XuluWritableGridFile(RasterMetaData metaData, String directory) {
+		super(metaData);
+		this.directory = directory;
+		baseFile = new File(directory + File.separatorChar + "xulugridFile"+ this.hashCode() + ".xgrid");
+		try {
+			gridFile = new XuluGridFile(baseFile,metaData);
+			this.intialDataLoader = new GridFileDataLoader(gridFile);
+			this.dataLoader = new GridFileDataLoader(gridFile);
+		} catch (XuluGridFileException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+			LOG.error(e);
+		
+		}
+		
+	}
+	
+	/** creates a instance out of a {@link XuluGridFile} */
+	public XuluWritableGridFile(XuluGridFile xuluGridFile) {
+		super(xuluGridFile.getMetaData());
+		baseFile = xuluGridFile.getOutputFile();
+		gridFile = xuluGridFile;
+		this.metaData = xuluGridFile.getMetaData();
+		this.intialDataLoader = new GridFileDataLoader(gridFile);
+		this.dataLoader = new GridFileDataLoader(gridFile);
+		// TODO Auto-generated constructor stub
+		this.directory=null;
+	}
+
+
+	/**
+	 * Creates a new XuluWritableGridFile in the specified directory, with the given metadata. 
+	 * The ID given in this constuctor will be the RootID of this Grid (used e.g. for 
+	 * identification in remoteComputing) 
+	 * 
+	 * @param newID the to be set as the new RootID (permanent)
+	 * @param metaData the metadata is used for creation of the bounds and the type of the new {@link XuluGridFile}
+	 * @param directory the directory in which the file should be created
+	 * @see SplittableResource#getRootID()
+	 */
+	public XuluWritableGridFile(int newID, RasterMetaData metaData, String directory) {
+		this(metaData,directory);
+		this.rootID  = newID;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplittableResource#getLocalLoader()
+	 */
+	public DataLoader getLocalLoader() {
+		throw new UnsupportedOperationException("Feature not yet supported!");
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplittableResource#getRootID()
+	 */
+	public int getRootID() {
+		return rootID;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplittableResource#getSplitHeight()
+	 */
+	public int getSplitHeight() {
+		return metaData.getHeight();
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplittableResource#getSplitWidth()
+	 */
+	public int getSplitWidth() {
+		return metaData.getWidth();
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.DataPartition#getEmpty(int)
+	 */
+	public DataPartition getEmpty(int newID) {
+		if(directory==null)
+		   throw new UnsupportedOperationException("Directory == null. Cant create a empty grid!");
+		return new XuluWritableGridFile(newID,this.metaData,this.directory);
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.DataPartition#getPartition(java.awt.Rectangle)
+	 */
+	public DataPartition getPartition(Rectangle partitionBounds) {
+		try {
+			return gridFile.getPartitialGrid2D(partitionBounds);
+		} catch (XuluGridFileException e) {
+			e.printStackTrace();
+			LOG.error("Could not retrieve partition from underlaying gridfile");
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.DataPartition#getPartitionBounds()
+	 */
+	public Rectangle getPartitionBounds() {
+		return new Rectangle(0,0,getWidth(),getHeight());
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.DataPartition#setPartition(appl.parallel.spmd.split.DataPartition, java.awt.Rectangle)
+	 */
+	public void setPartition(DataPartition partition, Rectangle partitionBounds) {
+		try {
+			gridFile.setPartition((WritableGrid) partition, partitionBounds);
+		} catch (XuluGridFileException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.data.WritableGridLLProxy#setGridSample(java.lang.Object, double[])
+	 */
+	@Override
+	public void setGridSample(Object value, double... coord) {
+		throw new UnsupportedOperationException("Writing on cell level is not yet supported. Use setPartition(..) to write to the Grid");
+		//wasWriteAccessed =true;
+//		super.setGridSample(value, coord);
+	}
+	
+	 /* (non-Javadoc)
+	 * @see appl.data.WritableGridLLProxy#setRasterSample(java.lang.Object, int[])
+	 */
+	public void setRasterSample(Object value, int... cell) {
+		 throw new UnsupportedOperationException("Writing on cell level is not yet supported. Use setPartition(..) to write to the Grid");
+
+	 }
+
+
+	/* (non-Javadoc)
+	 * @see appl.data.WritableGridLLProxy#getGridSample(double[])
+	 */
+	@Override
+	public Object getGridSample(double... coord) {
+		 throw new UnsupportedOperationException("Reading on cell level is not yet supported. Use getPartition(..) to read from the to the Grid");
+	}
+
+
+	/* (non-Javadoc)
+	 * @see appl.data.WritableGridLLProxy#getGridSampleAsByte(double[])
+	 */
+	@Override
+	public byte getGridSampleAsByte(double... coord) {
+		throw new UnsupportedOperationException("Reading on cell level is not yet supported. Use getPartition(..) to read from the to the Grid");
+	}
+
+
+	/* (non-Javadoc)
+	 * @see appl.data.WritableGridLLProxy#getGridSampleAsDouble(double[])
+	 */
+	@Override
+	public double getGridSampleAsDouble(double... coord) {
+		throw new UnsupportedOperationException("Reading on cell level is not yet supported. Use getPartition(..) to read from the to the Grid");
+	}
+
+
+	/* (non-Javadoc)
+	 * @see appl.data.WritableGridLLProxy#getGridSampleAsFloat(double[])
+	 */
+	@Override
+	public float getGridSampleAsFloat(double... coord) {
+		throw new UnsupportedOperationException("Reading on cell level is not yet supported. Use getPartition(..) to read from the to the Grid");
+	}
+
+
+	/* (non-Javadoc)
+	 * @see appl.data.WritableGridLLProxy#getGridSampleAsInt(double[])
+	 */
+	@Override
+	public int getGridSampleAsInt(double... coord) {
+		throw new UnsupportedOperationException("Reading on cell level is not yet supported. Use getPartition(..) to read from the to the Grid");
+	}
+
+
+	/* (non-Javadoc)
+	 * @see appl.data.WritableGridLLProxy#getGridSampleAsLong(double[])
+	 */
+	@Override
+	public long getGridSampleAsLong(double... coord) {
+		throw new UnsupportedOperationException("Reading on cell level is not yet supported. Use getPartition(..) to read from the to the Grid");
+	}
+
+
+	/* (non-Javadoc)
+	 * @see appl.data.WritableGridLLProxy#getGridSampleAsShort(double[])
+	 */
+	@Override
+	public short getGridSampleAsShort(double... coord) {
+		throw new UnsupportedOperationException("Reading on cell level is not yet supported. Use getPartition(..) to read from the to the Grid");
+	}
+	/**
+	 * unloading is not necessary (method does nothing
+	 * 
+	 * @see appl.data.LateLoadingProxy#unloadData()
+	 */
+	@Override
+	public synchronized void unloadData() {
+	}
+
+
+	public String getGridFileName() {
+		return baseFile.getPath();
+	}
+}

Added: trunk/src/appl/parallel/data/xulugridfile/factories/GridListFactory.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/factories/GridListFactory.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/factories/GridListFactory.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,25 @@
+package appl.parallel.data.xulugridfile.factories;
+
+import edu.bonn.xulu.io.InstantiationFactory;
+
+// nur fuer Doku
+import schmitzm.data.WritableGrid;
+import edu.bonn.xulu.plugin.data.grid.GridList;
+
+/**
+ * Diese Factory erzeugt Standard-Instanzen von {@link GridList} mit
+ * durch die Factory {@link XuluGridFactory} erzeugten (auf Standard-Arrays
+ * basierenden) {@link WritableGrid}-Instanzen als Inhalt.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class GridListFactory extends edu.bonn.xulu.plugin.io.grid.awt.GridListFactory {
+  /**
+   * Liefert eine Instanz von {@link XuluGridFactory}, die auf
+   * Standard-Arrays basierende Instanzen von {@link WritableGrid} erzeugt. Mit diesen
+   * Instanzen wird die GridList gefuellt.
+   */
+  protected InstantiationFactory getWritableGridFactory() {
+    return new XuluGridFactory();
+  }
+}

Added: trunk/src/appl/parallel/data/xulugridfile/factories/GridListFactory_ArcInfoAsciiGrid.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/factories/GridListFactory_ArcInfoAsciiGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/factories/GridListFactory_ArcInfoAsciiGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,180 @@
+package appl.parallel.data.xulugridfile.factories;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import appl.data.DataProxy;
+import appl.data.WritableGridLLProxy;
+import appl.ext.XuluConfig;
+import appl.parallel.data.xulugridfile.XuluGridFile;
+import appl.parallel.data.xulugridfile.XuluGridFileConverter;
+import appl.parallel.data.xulugridfile.XuluWritableGridFile;
+import appl.util.RasterUtil;
+
+import schmitzm.io.IOUtil;
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ListPropertyReadAccess;
+
+import edu.bonn.xulu.io.Factory;
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.io.InstantiationFactory;
+import edu.bonn.xulu.io.ExportFactory;
+import edu.bonn.xulu.io.AbstractFactory;
+import edu.bonn.xulu.appl.XuluRegistry;
+
+import edu.bonn.xulu.plugin.data.grid.GridList;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory_ArcInfoAsciiGrid;
+
+/**
+ * Diese Factory importiert und exportiert Instanzen des Datentyps
+ * {@link GridList} aus/in Dateien im ArcInfo-ASCII-Grid-Format.
+ * Beim Import liefert die Factory eine Standard-Arrays basierendes Raster-Liste
+ * ({@link WritableGridArray}).
+ * Entsprechend koennen beim Export nur {@link GridList GridLists}
+ * verarbeitet werden, die {@link WritableGridArray}-Instanzen in ihrer
+ * Raster-Property besitzen.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class GridListFactory_ArcInfoAsciiGrid extends AbstractFactory implements ImportFactory,ExportFactory {
+ private static final ImportFactory importFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+ private static final ExportFactory exportFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ImportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Liefert den Datentyp, den die Factory erzeugt.
+   * @return immer {@link GridList GridList.class}
+   */
+  public Class getImportType() {
+    return GridList.class;
+  }
+
+  /**
+   * Liefert den Datentyp, den die Factory als Import-Quelle benoetigt.
+   * @return immer {@link File File[].class}
+   */
+  public Class getImportSourceType() {
+     return File[].class;
+  }
+
+  /**
+   * Importiert Raster aus Dateien im ArcInfoAsciiGrid-Format
+   * und fuegt diese in einer {@link GridList} zusammen.
+   * @param input Eingabe-Quelle (muss ein {@link File File[]} sein!)
+   * @param reg   Instanz der Xulu-Registry, ueber die eine Factory ermittelt
+   *              wird, die eine Standard-Instanz von {@link GridList} erzeugt, in
+   *              die das Objekt importiert wird
+   * @exception UnsupportedOperationException falls als Eingabe-Quelle keine
+   *            Dateien angegeben werden
+   */
+  public GridList importObject(Object input, XuluRegistry reg) throws Exception {
+    AbstractFactory.checkImportSourceObject(this,input,getImportSourceType(),true);
+    InstantiationFactory instFac = AbstractFactory.getInstantiationFactoryFromRegistry(reg,getImportType(),true);
+    GridList sg = (GridList)instFac.newInstance(false);
+    // Raster importieren und in GridList einfuegen
+    for (int i=0; i<((Object[])input).length; i++){
+    	//take the first File
+    	File inputFile = (File) ((Object[]) input)[i];
+        File outputFile = new File(inputFile.getAbsoluteFile()+".xgrid");
+        //check if already a gridFile (should not be..)
+        XuluGridFile xuluGridFile;
+        if(inputFile.getAbsolutePath().endsWith(".xgrid"))
+        	xuluGridFile = new XuluGridFile(inputFile);
+        else
+        {	
+        //check if a the import should be converted even if a xulugridfile with the same name exists
+        boolean alwaysreload = XuluConfig.getXuluConfig().getBooleanProperty("Datatypes.xulugrid.alwaysconvert");		
+        //only convert if nessecary
+        if(alwaysreload || (!outputFile.exists())){
+        	 //the ArcInfoGrid must be converted to XuluGridFile
+            XuluGridFileConverter converter = new XuluGridFileConverter(inputFile,outputFile);
+            int dataType = RasterUtil.getRasterMetaData_from_ArcGridASCII_File(inputFile).getDataType();
+            xuluGridFile = converter.convertArcInfoToXuluGridFile(dataType);
+        }
+        else
+        	xuluGridFile = new XuluGridFile(outputFile);
+        }
+        WritableGrid grid = new XuluWritableGridFile(xuluGridFile);
+    sg.addGrid(grid);
+    }
+    //    // Dateinamen in die Bezeichnung aufnehmen
+//    sg.setDescription(sg.getDescription().concat(" [").concat(((File)input).getName()).concat("]"));
+    return sg;
+  }
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ExportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Prueft, ob ein Objekt exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um eine {@link GridList} handelt, die nur Instanzen
+   * von {@link WritableGridArray} als Elemente enthaelt.
+   * @param obj zu pruefendes Objekt
+   */
+  public boolean isExportable(Object obj) {
+    if ( obj==null || !(obj instanceof GridList) )
+      return false;
+    GridList list = (GridList)obj;
+    for (int i=0; i<list.getGridCount(); i++)
+      if ( !(list.getGrid(i) instanceof WritableGridLLProxy) )
+        return false;
+    return true;
+  }
+
+  /**
+   * Prueft, ob ein Objekttyp exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um {@link GridList} (oder eine Unterklasse)
+   * handelt.
+   * @param c zu pruefender Objekttyp
+   */
+  public boolean isExportable(Class c) {
+    return GridList.class.isAssignableFrom(c);
+  }
+
+  /**
+   * Liefert den Objekt-Typ, den die Factory als Ziel zum Exportieren
+   * benoetigt. Dabei handelt es sich um eine <b>einzelne Datei</b>, da
+   * die die letztendlichen Export-Dateien automatisch durchnummeriert werden!!
+   * @return immer {@link File File.class}
+   */
+  public Class getExportDestinationType() {
+    return File.class;
+  }
+
+  /**
+   * Exportiert eine Instanz von {@link GridList} in Dateien des
+   * ArcInfoAsciiGrid-Formats.<br>
+   * <b>Beachte:</b><br>
+   * Als Ausgabe-Objekt ist eine <b>einzelne</b> Datei anzugeben, kein
+   * Array! Die Dateien werden ausgehend von dem angegebenen Dateinamen
+   * durchnummeriert!!
+   * @param object zu exportiertende Raster (muss eine {@link GridList} sein
+   * @param output Export-Ziel (muss ein einzelner {@link File} sein!)
+   * @exception UnsupportedOperationException falls als Export-Ziel keine
+   *            einzelne Datei angegeben wird
+   * @exception IllegalArgumentException falls es sich bei dem angegeben Objekt
+   *            nicht um eine {@link GridList} handelt
+   */
+  public void exportObject(Object object, Object output) throws Exception {
+    AbstractFactory.checkExportDestinationObject(this,output,getExportDestinationType(),true);
+    if ( !isExportable(object) )
+      throw new IllegalArgumentException(getClass().getName().concat(" can not export instances of ").concat(object.getClass().getName()));
+
+    // Dateinamen-Teile ermitteln
+    String fileName = IOUtil.getBaseFileName((File)output);
+    String fileExt  = IOUtil.getFileExt((File)output);
+
+    // Grids in der Liste einzeln exportieren
+    ListPropertyReadAccess listAccess = ((ListProperty) (((GridList)object).getProperty(GridList.PROP_GRIDS))).getReadAccess(this);
+    for (int i=0; i<listAccess.getCount(); i++) {
+      File outFile = new File( fileName.concat("_"+i).concat(fileExt) );
+      exportFac.exportObject( ((DataProxy)listAccess.getValue(i)).getProxiedObject() ,new FileOutputStream(outFile) );
+    }
+    listAccess.release();
+
+  }
+}

Added: trunk/src/appl/parallel/data/xulugridfile/factories/MultiGridFactory.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/factories/MultiGridFactory.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/factories/MultiGridFactory.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,25 @@
+package appl.parallel.data.xulugridfile.factories;
+
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+// nur fuer Doku
+import schmitzm.data.WritableGrid;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+/**
+ * Diese Factory erzeugt Standard-Instanzen von {@link MultiGrid} mit
+ * durch die Factory {@link XuluGridFactory} erzeugten (auf Standard-Arrays
+ * basierenden) {@link WritableGrid}-Instanzen als Inhalt.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class MultiGridFactory extends edu.bonn.xulu.plugin.io.grid.awt.MultiGridFactory {
+  /**
+   * Liefert eine Instanz von {@link XuluGridFactory}, die auf Standard-Arrays
+   * basierende Instanzen von {@link WritableGrid} erzeugt. Mit diesen
+   * Instanzen wird die GridList gefuellt.
+   */
+  protected WritableGridFactory getWritableGridFactory() {
+    return new XuluGridFactory();
+  }
+
+}

Added: trunk/src/appl/parallel/data/xulugridfile/factories/MultiGridFactory_ArcInfoAsciiGrid.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/factories/MultiGridFactory_ArcInfoAsciiGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/factories/MultiGridFactory_ArcInfoAsciiGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,114 @@
+package appl.parallel.data.xulugridfile.factories;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import appl.data.WritableGridLLProxy;
+import appl.ext.XuluConfig;
+import appl.parallel.data.xulugridfile.XuluGridFile;
+import appl.parallel.data.xulugridfile.XuluGridFileConverter;
+import appl.parallel.data.xulugridfile.XuluWritableGridFile;
+import appl.util.RasterUtil;
+
+import schmitzm.data.WritableGrid;
+
+import edu.bonn.xulu.appl.XuluRegistry;
+import edu.bonn.xulu.io.AbstractFactory;
+import edu.bonn.xulu.io.ImportFactory;
+
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+import edu.bonn.xulu.plugin.data.grid.GridList;
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory_ArcInfoAsciiGrid;
+//import edu.bonn.xulu.plugin.io.grid.gt.GridListFactory_ArcInfoAsciiGrid;
+
+// nur fuer Doku
+import schmitzm.data.WritableGridArray;
+import edu.bonn.xulu.io.InstantiationFactory;
+
+/**
+ * Diese Factory importiert und exportiert Instanzen des Datentyps
+ * {@link MultiGrid} aus/in Dateien im ArcInfo-ASCII-Grid-Format.
+ * Beim Import liefert die Factory eine Standard-Arrays basierendes Raster-Liste
+ * ({@link WritableGridArray}).
+ * Entsprechend koennen beim Export nur {@link MultiGrid MultiGrids}
+ * verarbeitet werden, die {@link WritableGridArray}-Instanzen in ihrer
+ * Raster-Property besitzen.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class MultiGridFactory_ArcInfoAsciiGrid extends GridListFactory_ArcInfoAsciiGrid {
+  private static final ImportFactory importFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ImportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Liefert den Datentyp, den die Factory erzeugt.
+   * @return immer {@link MultiGrid MultiGrid.class}
+   */
+  public Class getImportType() {
+    return MultiGrid.class;
+  }
+
+  /**
+   * Importiert Raster aus Dateien im ArcInfoAsciiGrid-Format
+   * und fuegt diese in einem {@link MultiGrid} zusammen.
+   * @param input Eingabe-Quelle (muss ein {@link File File[]} sein!)
+   * @param reg   Instanz der Xulu-Registry, ueber die eine Factory ermittelt
+   *              wird, die eine Standard-Instanz von {@link MultiGrid} erzeugt, in
+   *              die das Objekt importiert wird
+   * @exception UnsupportedOperationException falls als Eingabe-Quelle keine
+   *            Dateien angegeben werden
+   */
+  public MultiGrid importObject(Object input, XuluRegistry reg) throws Exception {
+    AbstractFactory.checkImportSourceObject(this,input,getImportSourceType(),true);
+
+    // MultiGrid erst erzeugen, wenn ein Beispiel-Raster vorliegt
+    MultiGrid mg = null;
+    // Raster importieren und in GridList einfuegen
+    for (int i=0; i<((Object[])input).length; i++) {
+    	File inputFile = (File) ((Object[]) input)[i];
+        File outputFile = new File(inputFile.getAbsoluteFile()+".xgrid");
+        //check if already a gridFile (should not be..)
+        XuluGridFile xuluGridFile;
+        if(inputFile.getAbsolutePath().endsWith(".xgrid"))
+        	xuluGridFile = new XuluGridFile(inputFile);
+        else
+        {	
+        //check if a the import should be converted even if a xulugridfile with the same name exists
+        boolean alwaysreload = XuluConfig.getXuluConfig().getBooleanProperty("Datatypes.xulugrid.alwaysconvert");		
+        //only convert if nessecary
+        if(alwaysreload || (!outputFile.exists())){
+        	 //the ArcInfoGrid must be converted to XuluGridFile
+            XuluGridFileConverter converter = new XuluGridFileConverter(inputFile,outputFile);
+            int dataType = RasterUtil.getRasterMetaData_from_ArcGridASCII_File(inputFile).getDataType();
+            xuluGridFile = converter.convertArcInfoToXuluGridFile(dataType);
+        }
+        else
+        	xuluGridFile = new XuluGridFile(outputFile);
+        }
+        WritableGrid grid = new XuluWritableGridFile(xuluGridFile);
+    	
+    	
+    	
+    	
+      // das erste Grid dient dem MultiGrid als Vorlage
+      if ( mg == null )
+        mg = new MultiGrid(grid,getWritableGridFactory());
+
+      mg.addGrid(grid);
+    }
+    return mg;
+  }
+
+  /**
+   * Liefert eine Instanz von {@link XuluGridFactory}, die auf Standard-Arrays
+   * basierende Instanzen von {@link WritableGrid} erzeugt. Mit diesen
+   * Instanzen wird das SingleGrid gefuellt.
+   */
+  protected WritableGridFactory getWritableGridFactory() {
+    return new XuluGridFactory();
+  }
+
+}

Added: trunk/src/appl/parallel/data/xulugridfile/factories/SingleGridFactory.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/factories/SingleGridFactory.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/factories/SingleGridFactory.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,23 @@
+package appl.parallel.data.xulugridfile.factories;
+
+import edu.bonn.xulu.io.InstantiationFactory;
+// nur fuer Doku
+import schmitzm.data.WritableGrid;
+import edu.bonn.xulu.plugin.data.grid.SingleGrid;
+
+/**
+ * Diese Factory erzeugt Standard-Instanzen von {@link SingleGrid} mit einem
+ * durch die Factory {@link XuluGridFactory} erzeugten {@link WritableGrid}.
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class SingleGridFactory extends edu.bonn.xulu.plugin.io.grid.awt.SingleGridFactory{
+
+  /**
+   * Liefert eine Instanz von {@link XuluGridFactory}. Mit diesen
+   * Instanzen wird das SingleGrid gefuellt.
+   */
+  protected InstantiationFactory getWritableGridFactory() {
+    return new XuluGridFactory();
+  }
+}

Added: trunk/src/appl/parallel/data/xulugridfile/factories/SingleGridFactory_ArcInfoAsciiGrid.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/factories/SingleGridFactory_ArcInfoAsciiGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/factories/SingleGridFactory_ArcInfoAsciiGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,152 @@
+package appl.parallel.data.xulugridfile.factories;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import appl.data.DataProxy;
+import appl.data.WritableGridLLProxy;
+import appl.ext.XuluConfig;
+import appl.parallel.data.xulugridfile.XuluGridFile;
+import appl.parallel.data.xulugridfile.XuluGridFileConverter;
+import appl.parallel.data.xulugridfile.XuluWritableGridFile;
+import appl.util.RasterMetaData;
+import appl.util.RasterUtil;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.io.InstantiationFactory;
+import edu.bonn.xulu.io.ExportFactory;
+import edu.bonn.xulu.io.AbstractFactory;
+import edu.bonn.xulu.appl.XuluRegistry;
+
+import edu.bonn.xulu.plugin.data.grid.SingleGrid;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory_ArcInfoAsciiGrid;
+
+// nur fuer Doku
+
+/**
+ * Diese Factory importiert und exportiert Instanzen des Datentyps
+ * {@link SingleGrid} aus/in das ArcInfo-ASCII-Grid-Format.
+
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class SingleGridFactory_ArcInfoAsciiGrid extends AbstractFactory implements ImportFactory, ExportFactory {
+  private static final ImportFactory importFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+  private static final ExportFactory exportFac = new WritableGridArrayFactory_ArcInfoAsciiGrid();
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ImportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Liefert den Datentyp, den die Factory erzeugt.
+   * @return immer {@link SingleGrid SingleGrid.class}
+   */
+  public Class getImportType() {
+    return SingleGrid.class;
+  }
+
+  /**
+   * Liefert den Datentyp, den die Factory als Import-Quelle benoetigt.
+   * @return immer {@link File File.class}
+   */
+  public Class getImportSourceType() {
+    return File.class;
+  }
+
+  /**
+   * Importiert eine Instanz von {@link SingleGrid} aus einer Datei im
+   * ArcInfoAsciiGrid-Format.
+   * @param input Eingabe-Quelle (muss ein {@link File} sein!)
+   * @param reg   Instanz der Xulu-Registry, ueber die eine Factory ermittelt
+   *              wird, die eine Standard-Instanz von {@link SingleGrid} erzeugt, in
+   *              die das Raster importiert wird
+   * @exception UnsupportedOperationException falls als Eingabe-Quelle keine
+   *            Datei angegeben wird
+   */
+  public SingleGrid importObject(Object input, XuluRegistry reg) throws Exception {
+    AbstractFactory.checkImportSourceObject(this,input,getImportSourceType(),true);
+    // Aus Registry die passende Factory fuer SingleGrid suchen
+    InstantiationFactory instFac = AbstractFactory.getInstantiationFactoryFromRegistry(reg,getImportType(),true);
+    // Raster importieren und in ein SingleGrid einfuegen
+    SingleGrid sg = (SingleGrid)instFac.newInstance(false);
+    File inputFile = (File) input;
+    File outputFile = new File(inputFile.getAbsoluteFile()+".xgrid");
+    //check if already a gridFile (should not be..)
+    XuluGridFile xuluGridFile;
+    if(((File)input).getAbsolutePath().endsWith(".xgrid"))
+    	xuluGridFile = new XuluGridFile((File)input);
+    else
+    {	
+    //check if a the import should be converted even if a xulugridfile with the same name exists
+    boolean alwaysreload = XuluConfig.getXuluConfig().getBooleanProperty("Datatypes.xulugrid.alwaysconvert");		
+    //only convert if nessecary
+    if(alwaysreload || (!outputFile.exists())){
+    	 //the ArcInfoGrid must be converted to XuluGridFile
+        XuluGridFileConverter converter = new XuluGridFileConverter(inputFile,outputFile);
+        int dataType = RasterUtil.getRasterMetaData_from_ArcGridASCII_File((File) input).getDataType();
+        xuluGridFile = converter.convertArcInfoToXuluGridFile(dataType);
+    }
+    else
+    	xuluGridFile = new XuluGridFile(outputFile);
+    }
+    WritableGrid grid = new XuluWritableGridFile(xuluGridFile);
+    sg.setGrid(grid);
+    // Dateinamen in die Bezeichnung aufnehmen
+    sg.setDescription(sg.getDescription().concat(" [").concat(((File)input).getName()).concat("]"));
+    return sg;
+  }
+
+  ////////////////////////////////////////////////////////////////////////
+  ///////////////     Implementierung von ExportFactory     //////////////
+  ////////////////////////////////////////////////////////////////////////
+  /**
+   * Prueft, ob ein Objekt exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um ein {@link SingleGrid} handelt, das ein
+   * {@link WritableGridArray} in seiner Raster-Eigenschaft besitzt.
+   * @param obj zu pruefendes Objekt
+   */
+  public boolean isExportable(Object obj) {
+    return obj!=null &&
+           obj instanceof SingleGrid &&
+           ((SingleGrid)obj).getGrid() instanceof XuluWritableGridFile;
+  }
+
+  /**
+   * Prueft, ob ein Objekttyp exportiert werden kann. Dies ist der
+   * Fall, wenn es sich um {@link SingleGrid} (oder eine Unterklasse)
+   * handelt.
+   * @param c zu pruefender Objekttyp
+   */
+  public boolean isExportable(Class c) {
+    return SingleGrid.class.isAssignableFrom(c);
+  }
+
+  /**
+   * Liefert den Objekt-Typ, den die Factory als Ziel zum Exportieren
+   * benoetigt.
+   * @return immer {@link File File.class}
+   */
+  public Class getExportDestinationType() {
+    return File.class;
+  }
+
+  /**
+   * Exportiert eine Instanz von {@link SingleGrid} in eine ArcInfoAsciiGrid-Datei.
+   * @param grid zu exportiertendes Raster (muss ein {@link SingleGrid} sein
+   * @param output Export-Ziel (muss ein {@link File} sein!)
+   * @exception UnsupportedOperationException falls als Export-Ziel keine
+   *            Datei angegeben wird
+   * @exception IllegalArgumentException falls es sich bei dem angegeben Raster
+   *            nicht um ein {@link SingleGrid} handelt
+   */
+  public void exportObject(Object grid, Object output) throws Exception {
+    AbstractFactory.checkExportDestinationObject(this,output,getExportDestinationType(),true);
+    if ( !isExportable(grid) )
+      throw new IllegalArgumentException(getClass().getName().concat(" can not export instances of ").concat(grid.getClass().getName()));
+    exportFac.exportObject( ((DataProxy)((SingleGrid)grid).getGrid()).getProxiedObject(), new FileOutputStream((File)output) );
+  }
+
+}

Added: trunk/src/appl/parallel/data/xulugridfile/factories/XuluGridFactory.java
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/factories/XuluGridFactory.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/factories/XuluGridFactory.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,65 @@
+package appl.parallel.data.xulugridfile.factories;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.DataBuffer;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import appl.data.WritableGridLLProxy;
+import appl.ext.XuluConfig;
+import appl.parallel.data.xulugridfile.XuluGridFile;
+import appl.parallel.data.xulugridfile.XuluWritableGridFile;
+import appl.util.RasterMetaData;
+import schmitzm.data.WritableGrid;
+import edu.bonn.xulu.plugin.io.grid.WritableGridFactory;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory;
+
+// nur fuer Doku
+import edu.bonn.xulu.data.XuluObject;
+import edu.bonn.xulu.io.Factory;
+import edu.bonn.xulu.plugin.data.grid.SingleGrid;
+
+/**
+ *Creates instances of the memory saving data type {@link XuluGridFile} for the use in the Xulu
+ *Plattform.
+ *
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class XuluGridFactory extends WritableGridFactory {
+
+	/**
+	 * Liefert den Datentyp, den die Factory erzeugt.
+	 * @return immer {@link XuluWritableGridFile XuluWritableGridFile.class}
+	 */
+	public Class getInstanceType() {
+		return XuluWritableGridFile.class;
+	}
+
+	/**
+	 * Creates a new grid under the directory given under
+	 * @param type    Datentyp der gespeicherten Objekte
+	 * @param widthc  Breite in Zellen
+	 * @param heightc Hoehe in Zellen
+	 * @param minX    Index der ersten Zelle in X-Richtung
+	 * @param minY    Index der ersten Zelle in Y-Richtung
+	 * @param x       Georeferenz Latitude (Suedliche/Untere Kante)
+	 * @param y       Georeferenz Longitute (Westliche/Linke Kante)
+	 * @param width   Breite
+	 * @param height  Hoehe
+	 */
+	public WritableGridLLProxy newInstance(int type, int widthc, int heightc,
+			int minX, int minY, double x, double y, double width,
+			double height, CoordinateReferenceSystem crs) {
+
+		String directory = XuluConfig.getXuluConfig().getProperty(
+				"Datatypes.xulugrid.creationFolder");
+		if (directory == null)
+			directory = "Temp";
+
+		return new XuluWritableGridFile(new RasterMetaData(type, widthc,
+				heightc, minX, minY, x, y, width, height, crs), directory);
+	}
+}

Added: trunk/src/appl/parallel/data/xulugridfile/factories/package.html
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/factories/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/factories/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	The factories needed for loading the xuluWritableGridFile-Datatype into the xulu-plattform.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/data/xulugridfile/package.html
===================================================================
--- trunk/src/appl/parallel/data/xulugridfile/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/data/xulugridfile/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,8 @@
+<html>
+<body>
+	Contains classes related to the xulugridfile format. The XuluGridFile format is a special
+	file format which stores all values of a grid in a binary format that allows random access.
+	It allows the retrieval of partitions of itself without loading the whole file
+	into memory.  
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/event/CommEvent.java
===================================================================
--- trunk/src/appl/parallel/event/CommEvent.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/CommEvent.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,117 @@
+package appl.parallel.event;
+
+/**
+ * A {@link CommEvent} is a {@link RemoteEvent}. It gives Information about
+ * Events related to Communication.
+ * 
+ * @author Dominik Appl
+ */
+public class CommEvent extends RemoteEvent {
+
+	/**
+	 * The target of the event
+	 */
+	protected final String target;
+
+	/**
+	 * The source of the event
+	 */
+	protected final String src;
+
+	/**
+	 * the type of the event
+	 */
+	protected final CommType type;
+
+	/**
+	 * @author Dominik Appl
+	 */
+	public enum CommType {
+		/**
+		 * A not further specified type
+		 */
+		UNDEFINED,
+		/**
+		 * A Server has made an update from a source (possibly another server)
+		 */
+		REMOTE_UPDATE,
+		/**
+		 * A Server has executed a task (without client-server communication)
+		 */
+		REMOTE_EXECUTION,
+		/**
+		 * A Client has executed a Task (including communication)
+		 */
+		CLIENT_EXECUTION,
+		/**
+		 * A client has invoked an update
+		 */
+		CLIENT_UPDATE,
+		/**
+		 * A client has invoked a merge
+		 */
+		CLIENT_MERGE,
+		/**
+		 * Parameters were transfered
+		 */
+		TRANSFER_PARAMETERS,
+		/**
+		 * meta data was transfered
+		 */
+		TRANSFER_METADATA,
+		/**
+		 * data was transfered
+		 */
+		TRANSFER_DATA,
+		/**
+		 * Connection to servers were made
+		 */
+		CONNECT,
+		/**
+		 * The client disconnects from the servers
+		 */
+		DISCONNECT,
+	}
+
+	/**
+	 * A new CommEvent
+	 * 
+	 * @param src
+	 *            the source of the event
+	 * @param target
+	 *            the target
+	 * @param type
+	 *            the type
+	 */
+	CommEvent(String src, String target, CommType type) {
+		this.target = (target == null) ? "" : target;
+		this.src = (src == null) ? "" : src;
+		this.type = (type == null) ? CommType.UNDEFINED : type;
+	}
+
+	/**
+	 * @return the target
+	 */
+	public String getTarget() {
+		return target;
+	}
+
+	/**
+	 * @return the source
+	 */
+	public String getSrc() {
+		return src;
+	}
+
+	/**
+	 * @return the type
+	 */
+	public CommType getType() {
+		return type;
+	}
+
+	public String typeName() {
+		return type.toString();
+	}
+
+}
\ No newline at end of file

Added: trunk/src/appl/parallel/event/CommEventSink.java
===================================================================
--- trunk/src/appl/parallel/event/CommEventSink.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/CommEventSink.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,32 @@
+package appl.parallel.event;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+//doc
+import appl.parallel.client.RemoteEventHandler;
+import appl.parallel.services.RemoteEventProxy;
+
+
+/**
+ * A event sink for communication events receives {@link TimeEvent}s and {@link TransferEvent}s 
+ * and processes them. 
+ * 
+ * @see RemoteEventHandler
+ * @see RemoteEventProxy
+ * @author Dominik Appl
+ */
+public interface CommEventSink extends Remote, RemoteEventSink {
+
+	
+	/**
+	 * @return true if the service is running and time monitoring is enabled
+	 */
+	public boolean isTimeMonitoringEnabled() throws RemoteException;
+
+	/**
+	 * @return true if the service is running and transfer monitoring is enabled
+	 */
+	public boolean isTransferMonitoringEnabled() throws RemoteException;
+	
+}

Added: trunk/src/appl/parallel/event/RemoteEvent.java
===================================================================
--- trunk/src/appl/parallel/event/RemoteEvent.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/RemoteEvent.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,12 @@
+package appl.parallel.event;
+
+import java.io.Serializable;
+
+/**
+ * A event which may be thrown over a network
+ * 
+ * @author Dominik Appl
+ */
+public class RemoteEvent implements Serializable {
+
+}

Added: trunk/src/appl/parallel/event/RemoteEventSink.java
===================================================================
--- trunk/src/appl/parallel/event/RemoteEventSink.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/RemoteEventSink.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,18 @@
+package appl.parallel.event;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * A EventSink fires {@link RemoteEvent}s from a possibly remote source and
+ * processes them. May be an EventHandler.
+ * 
+ * @author Dominik Appl
+ */
+public interface RemoteEventSink extends Remote {
+
+	public void fireRemoteEvent(RemoteEvent e) throws RemoteException;
+
+	public void fireRemoteEvents(RemoteEvent[] e) throws RemoteException;
+
+}

Added: trunk/src/appl/parallel/event/SimpleConsoleMonitor.java
===================================================================
--- trunk/src/appl/parallel/event/SimpleConsoleMonitor.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/SimpleConsoleMonitor.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,80 @@
+package appl.parallel.event;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.parallel.client.RemoteEventHandler;
+import appl.parallel.client.RemoteExecutionController;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.appl.AbstractXuluPlugin;
+import edu.bonn.xulu.appl.XuluPlugin;
+
+/**
+ * A simple {@link XuluPlugin} that outputs received {@link TimeEvent}s 
+ * and {@link TransferEvent}s to the console.
+ * 
+ * @author Dominik Appl
+ */
+public class SimpleConsoleMonitor extends AbstractXuluPlugin implements
+		TimeMonitor, TransferMonitor {
+
+	protected final Logger LOG = LogManager
+			.getLogger(this.getClass().getName());
+
+	RemoteEventHandler eventProxy;
+
+	public SimpleConsoleMonitor() {
+		super(false);
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.event.TimeMonitor#receiveTimeEvent(appl.parallel.event.TimeEvent)
+	 */
+	public void receiveTimeEvent(TimeEvent t) {
+		System.out.println(t);
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.event.TransferMonitor#receiveTransferEvent(appl.parallel.event.TransferEvent)
+	 */
+	public void receiveTransferEvent(TransferEvent t) {
+		System.out.println(t);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see edu.bonn.xulu.appl.XuluPlugin#execute(edu.bonn.xulu.XuluModellingPlatform)
+	 */
+	public void execute(XuluModellingPlatform appl) {
+		super.execute(appl);
+		RemoteExecutionController controller = RemoteExecutionController
+				.getRemoteExecutionController(appl);
+		if (controller == null) {
+			LOG
+					.error("Could not find RemoteExecutionController! -> Could not start SimpleConsoleMonitor");
+			return;
+		}
+		eventProxy = controller.getEventProxy();
+		eventProxy.addTimeEventListener(this);
+		eventProxy.addTransferEventListener(this);
+		started = true;
+	}
+
+	@Override
+	public void stop() {
+		eventProxy.removeTimeMonitor(this);
+		eventProxy.removeTransferMonitor(this);
+		// TODO Auto-generated method stub
+		super.stop();
+	}
+}

Added: trunk/src/appl/parallel/event/TimeEvent.java
===================================================================
--- trunk/src/appl/parallel/event/TimeEvent.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/TimeEvent.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,50 @@
+package appl.parallel.event;
+
+/**
+ * A {@link TimeEvent} is a {@link CommEvent} which is associated with a 
+ * execution time of a operation. 
+ * 
+ * @author Dominik Appl
+ */
+public class TimeEvent extends CommEvent {
+
+	private final long time;
+
+	/**
+	 * @param timeNanos
+	 *            the execution time to be associated with this event in nano
+	 *            seconds
+	 * @param src
+	 *            the source of the event
+	 * @param target
+	 *            the target of the event
+	 * @param type
+	 *            the type of the event
+	 * @see System#nanoTime()
+	 */
+	public TimeEvent(long timeNanos, String src, String target, CommType type) {
+		super(src, target, type);
+		this.time = timeNanos;
+	}
+
+	/**
+	 * @return the execution time
+	 */
+	public long getTime() {
+		return time;
+	}
+
+	public String toString() {
+		StringBuffer returnString = new StringBuffer();
+		returnString.append(type.toString());
+		returnString.append(" execution time: ").append((time) / 1000000f)
+				.append(" ms");
+		if (!src.equals(""))
+			returnString.append(" source: ").append(src);
+		if (!target.equals(""))
+			returnString.append(" target: ").append(target);
+
+		return returnString.toString();
+	}
+
+}

Added: trunk/src/appl/parallel/event/TimeMonitor.java
===================================================================
--- trunk/src/appl/parallel/event/TimeMonitor.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/TimeMonitor.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,17 @@
+package appl.parallel.event;
+
+/**
+ * A monitor, that receives {@link TimeEvent}s
+ * @author Dominik Appl
+ */
+public interface TimeMonitor{
+	
+	/**
+	 * Receive a event
+	 * 
+	 * @param t
+	 *            the event
+	 */
+	public void receiveTimeEvent(TimeEvent t);
+
+}

Added: trunk/src/appl/parallel/event/TransferEvent.java
===================================================================
--- trunk/src/appl/parallel/event/TransferEvent.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/TransferEvent.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,89 @@
+/**
+ * 
+ */
+package appl.parallel.event;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+/**
+ * A TransferEvent is event which is associated with the size of a data transfer
+ * in bytes. It is measured by serializing the data into byte stream. This is
+ * very slow! So use this events carefully. You should check if monitoring for
+ * this event type is enabled, before generating it! See {@link CommEventSink}
+ * for details.
+ * 
+ * @author Dominik Appl
+ */
+public class TransferEvent extends CommEvent {
+
+	int size = 0;
+
+	/**
+	 * @param src
+	 *            the source of the event
+	 * @param target
+	 *            the target of the event
+	 * @param type
+	 *            the type of the event
+	 * @param toTransferObjects
+	 *            the objects transfered (Warning: the size will be measured by
+	 *            serializing the object. This is slow!)
+	 * @see #getObjectSize(Object)
+	 */
+	public TransferEvent(String src, String target, CommType type,
+			Object... toTransferObjects) {
+		super(src, target, type);
+		for (Object object : toTransferObjects) {
+			size += getObjectSize(object);
+		}
+	}
+
+	/**
+	 * Determines the object size in a very primitive way (serializing to a byte
+	 * array and returning the byteSize) I do not have to mention here
+	 * explicitly that this is slow, do I? There is no real alternative, because
+	 * in java exists. no function like <code>sizeOf</code> in C++
+	 * 
+	 * @param object
+	 *            a {@link Serializable} object
+	 * @return the size in bytes
+	 */
+	protected int getObjectSize(Object object) {
+		if (object == null)
+			return 0;
+
+		byte[] byteArray = null;
+		try {
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+			ObjectOutputStream oos = new ObjectOutputStream(baos);
+			oos.writeObject(object);
+			oos.close();
+			byteArray = baos.toByteArray();
+			baos.close();
+		} catch (IOException e) {
+			e.printStackTrace();
+			return 0;
+		}
+		return byteArray.length;
+	}
+
+	public int getSize() {
+		return size;
+	}
+
+	public String toString() {
+		StringBuffer returnString = new StringBuffer();
+		returnString.append(type.toString());
+		returnString.append(" Transfer size: ").append(size).append(" bytes");
+		if (!src.equals(""))
+			returnString.append(" source: ").append(src);
+		if (!target.equals(""))
+			returnString.append(" target: ").append(target);
+
+		return returnString.toString();
+	}
+
+}

Added: trunk/src/appl/parallel/event/TransferMonitor.java
===================================================================
--- trunk/src/appl/parallel/event/TransferMonitor.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/TransferMonitor.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,15 @@
+package appl.parallel.event;
+
+/**
+ * A Monitor that receives {@link TransferEvent}s
+ * @author Dominik Appl
+ */
+public interface TransferMonitor {
+
+	/**
+	 * Receive a event
+	 * @param t the event
+	 */
+	public void receiveTransferEvent(TransferEvent t);
+
+}

Added: trunk/src/appl/parallel/event/package.html
===================================================================
--- trunk/src/appl/parallel/event/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/event/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains classes related event handling. Especially remote events are progressed with this classes.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/gui/ModelControlContainer_parallel.java
===================================================================
--- trunk/src/appl/parallel/gui/ModelControlContainer_parallel.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/gui/ModelControlContainer_parallel.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,56 @@
+package appl.parallel.gui;
+
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.client.RemoteExecutionController;
+import appl.parallel.model.AbstractParallelStepModel;
+import appl.parallel.model.ParallelStepModel;
+import appl.parallel.spmd.SPMDClientInterface;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.gui.ModelControlContainer;
+
+/**
+ * This class extends the functionality of the container to support the execution
+ * of a {@link ParallelStepModel}. It retrieves the {@link RemoteExecutionController}
+ * and uses it to prepare the model for parallel execution.
+ * 
+ * @author Dominik Appl
+ */
+public class ModelControlContainer_parallel extends ModelControlContainer {
+
+	private final XuluModellingPlatform appl;
+
+	private final ParallelControlPanelEngine pcpEngine;
+
+	/**
+	 * A new instance
+	 * @param model the XuluModel which should be executed
+	 * @param pcpEngine the controlling engine for parallel execution
+	 * @param appl the Xulu application
+	 */
+	public ModelControlContainer_parallel(XuluModel model,
+			ParallelControlPanelEngine pcpEngine, XuluModellingPlatform appl) {
+		super(model);
+		this.pcpEngine = pcpEngine;
+		// TODO Auto-generated constructor stub
+		this.appl = appl;
+	}
+
+	@Override
+	protected void createNewThread() {
+		if (model instanceof ParallelStepModel) {
+			// create the ClientController
+			RemoteExecutionController remoteController = RemoteExecutionController
+					.getRemoteExecutionController(appl);
+			if (remoteController == null)
+				throw new UnsupportedOperationException(
+						"You must load the RemoteExecutionController-Plugin to execute parallel Models!");
+			remoteController.prepareModelForSPMDExecution(
+					(ParallelStepModel) model, pcpEngine
+							.getSelectedResourceContainers());
+
+		}
+		super.createNewThread();
+	}
+}

Added: trunk/src/appl/parallel/gui/ModelControlFrame_Tabbed.java
===================================================================
--- trunk/src/appl/parallel/gui/ModelControlFrame_Tabbed.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/gui/ModelControlFrame_Tabbed.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,75 @@
+package appl.parallel.gui;
+
+import java.awt.CardLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.BoxLayout;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.appl.XuluConstants;
+
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.gui.ModelControlFrame_Basic;
+import edu.bonn.xulu.gui.ModelContentManagerContainer;
+
+/**
+ * This class introduces tab functionality into the ModelControlFrame
+ * 
+ * @author Dominik Appl
+ * @version 1.0
+ */
+public class ModelControlFrame_Tabbed extends ModelControlFrame_Basic implements
+		XuluConstants {
+
+	protected JTabbedPane tabbedPane;
+
+	/**
+	 * Creates a new controlling window
+	 * 
+	 * @param appl
+	 *            application in which the model is executed
+	 * @param model
+	 *            the model to be controlled through the frame
+	 */
+	public ModelControlFrame_Tabbed(XuluModellingPlatform appl, XuluModel model) {
+		super(appl, model);
+		this.pack();
+	}
+
+	/**
+	 * inits the content pane as tabbed pane with one tab (the resource mapping)
+	 * 
+	 * @see edu.bonn.xulu.plugin.gui.ModelControlFrame_Basic#initContentPane()
+	 */
+	@Override
+	protected void initContentPane() {
+
+		// ####### Daten-Komponente #######
+		contentContainer = new ModelContentManagerContainer(model
+				.getContentManager(), appl.getDataPool());
+		tabbedPane = new JTabbedPane(JTabbedPane.TOP);
+		tabbedPane.setPreferredSize(new Dimension((int) contentContainer
+				.getPreferredSize().getWidth() + 5, (int) contentContainer
+				.getPreferredSize().getHeight() + 25));
+		JPanel panel = new JPanel(new GridBagLayout());
+
+		panel.add(contentContainer, new GridBagConstraints(0, 1, 2, 1, 1.0,
+				0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
+				new Insets(5, 5, 5, 5), 0, 25));
+
+		tabbedPane.addTab("Resource Mapping", panel);
+		contentPane.add(tabbedPane, new GridBagConstraints(0, 1, 2, 1, 1.0,
+				0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
+				new Insets(0, 0, 0, 0), 0, 0));
+	}
+
+	@Override
+	protected ModelControlFrame_Tabbed newInstance(XuluModel newModel) {
+		return new ModelControlFrame_Tabbed(appl, newModel);
+	}
+
+}

Added: trunk/src/appl/parallel/gui/ModelControlFrame_parallel.java
===================================================================
--- trunk/src/appl/parallel/gui/ModelControlFrame_parallel.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/gui/ModelControlFrame_parallel.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,123 @@
+package appl.parallel.gui;
+
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JPanel;
+
+import schmitzm.lang.WorkingThread;
+import schmitzm.lang.WorkingThreadAdapter;
+
+import appl.parallel.client.RemoteExecutionController;
+import appl.parallel.model.AbstractParallelStepModel;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.gui.ModelControlContainer;
+import edu.bonn.xulu.plugin.gui.ModelControlFrame_Basic;
+
+/**
+ * Introduces a new TAB into the {@link ModelControlFrame_Basic}
+ * for controlling the parallel execution
+ *
+ * @author Dominik Appl
+ */
+public class ModelControlFrame_parallel extends ModelControlFrame_Tabbed {
+
+	protected ParallelControlPanelEngine spcEngine;
+
+	private boolean parallelPaneInitalized;
+
+	/**
+	 * @param appl
+	 * @param model
+	 */
+	public ModelControlFrame_parallel(XuluModellingPlatform appl,
+			XuluModel model) {
+		super(appl, model);
+		this.pack();
+	}
+
+	/**
+	 * does basically the same as
+	 * {@link ModelControlFrame_Basic#initControlContainer()}
+	 */
+	protected void initControlContainer() {
+		spcEngine = new ParallelControlPanelEngine(appl);
+		// ####### Initialize controlcomponent #######
+		controlContainer = new ModelControlContainer_parallel(model, spcEngine,
+				appl);
+
+		// ******************** COPIED FROM SUPERCLASS
+		// **************************
+
+		// Bei Init-Aktion muessen zunaechst die Modell-Ressourcen mit den
+		// ausgewaehlten
+		// Datenpool-Objekten verknuepft werden; bevor das Modell initialisiert
+		// wird
+		controlContainer.addButtonActionListener(
+				ModelControlContainer.BUTTON_INIT, new ActionListener() {
+					public void actionPerformed(ActionEvent e) {
+						setModelResources();
+					}
+				});
+		// Waehrend das Modell laeuft, soll nichts an den Ressourcen veraendet
+		// werden
+		controlContainer.addThreadListener(new WorkingThreadAdapter() {
+			public void threadStarted(WorkingThread thread) {
+				contentContainer.setEnabled(false);
+				reloadButton.setEnabled(false);
+			}
+
+			public void threadStopped(WorkingThread thread) {
+				contentContainer.setEnabled(true);
+				reloadButton.setEnabled(true);
+			}
+		});
+		contentPane.add(controlContainer, new GridBagConstraints(0, 0, 1, 1,
+				1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
+				new Insets(5, 5, 5, 5), 0, 0));
+	}
+
+	@Override
+	protected void initContentPane() {
+		super.initContentPane();
+//		System.out.println(model.getClass().getName());
+		if (model instanceof AbstractParallelStepModel) {
+			initializeParallelPane();
+		} else
+			parallelPaneInitalized = false;
+	}
+
+	private boolean isParallelPaneInitalized() {
+		return parallelPaneInitalized;
+	}
+
+	@Override
+	protected ModelControlFrame_parallel newInstance(XuluModel newModel) {
+		ModelControlFrame_parallel frame_parallel = new ModelControlFrame_parallel(
+				appl, newModel);
+		// initialize the parallel pane if it was initialized before
+		if (this.isParallelPaneInitalized()
+				&& !frame_parallel.isParallelPaneInitalized()) {
+			if (newModel.getClass().getName()
+					.equals(model.getClass().getName())) {
+				frame_parallel.initializeParallelPane();
+			}
+		}
+		return frame_parallel;
+	}
+
+	private void initializeParallelPane() {
+		super.tabbedPane.addTab("Parallel Control", spcEngine.getPanel());
+		// The boolean parallelPaneInitalized is required because after
+		// reloading
+		// with a custom classloader, like the preferred classloader, the
+		// 'instanceof' will no longer work properly with the reloaded class.
+		// (instanceof will return false)
+		parallelPaneInitalized = true;
+	}
+
+}

Added: trunk/src/appl/parallel/gui/ParallelControlPanel.java
===================================================================
--- trunk/src/appl/parallel/gui/ParallelControlPanel.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/gui/ParallelControlPanel.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,246 @@
+package appl.parallel.gui;
+
+import javax.swing.JPanel;
+import java.awt.GridBagLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.BoxLayout;
+import javax.swing.ListSelectionModel;
+import java.awt.Insets;
+import javax.swing.border.SoftBevelBorder;
+import javax.swing.table.DefaultTableModel;
+import edu.bonn.xulu.XuluModellingPlatform;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+
+import java.awt.Rectangle;
+
+/**
+ * The GUI for the ParallelControlPanel . All the interesting 
+ * stuff happens in the {@link ParallelControlPanelEngine}.
+ * This GUI was created with the Visual Editor plugin for eclipse. 
+ * Editing with another VE may be a bad idea.
+ *  
+ * @author Dominik Appl
+ */
+public class ParallelControlPanel extends JPanel {
+
+	static final long serialVersionUID = 1L;
+
+	JPanel executionPanel = null;
+
+	JLabel Steps = null;
+
+	JTable computingResourcesList = null;
+
+	JScrollPane jScrollPane1 = null;
+
+	JPanel jPanel = null;
+
+	JScrollPane jScrollPane = null;
+
+	SimplePropertyTable propertyTable = null;
+
+	JButton refreshButton = null;
+
+	JButton selectAllButton = null;
+
+	JPanel buttonPanel = null;
+
+	/**
+	 * This is the default constructor. It should be only used be the eclipse VE
+	 */
+	public ParallelControlPanel() {
+		super();
+		initialize();
+	}
+
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+		this.setSize(578, 268);
+		this.add(getExecutionPanel(), null);
+		this.add(getJPanel(), null);
+	}
+
+	/**
+	 * This method initializes executionPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getExecutionPanel() {
+		if (executionPanel == null) {
+			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
+			gridBagConstraints12.gridx = 1;
+			gridBagConstraints12.gridy = 2;
+			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
+			gridBagConstraints11.fill = GridBagConstraints.BOTH;
+			gridBagConstraints11.weighty = 1.0;
+			gridBagConstraints11.gridx = 0;
+			gridBagConstraints11.gridy = 1;
+			gridBagConstraints11.ipadx = 0;
+			gridBagConstraints11.insets = new Insets(5, 5, 5, 5);
+			gridBagConstraints11.gridwidth = 2;
+			gridBagConstraints11.weightx = 1.0;
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.insets = new Insets(0, 0, 0, 0);
+			gridBagConstraints.gridy = 0;
+			gridBagConstraints.anchor = GridBagConstraints.NORTH;
+			gridBagConstraints.gridheight = 1;
+			gridBagConstraints.gridwidth = 2;
+			gridBagConstraints.gridx = 0;
+			Steps = new JLabel();
+			Steps.setText("Computing resources:");
+			Steps.setName("Steps");
+			executionPanel = new JPanel();
+			executionPanel.setLayout(new GridBagLayout());
+			executionPanel.setBorder(new SoftBevelBorder(
+					SoftBevelBorder.LOWERED));
+			executionPanel.setVisible(true);
+			executionPanel.add(Steps, gridBagConstraints);
+			executionPanel.add(getJScrollPane1(), gridBagConstraints11);
+			executionPanel.add(getButtonPanel(), gridBagConstraints12);
+		}
+		return executionPanel;
+	}
+
+	/**
+	 * This method initializes computingResourcesList	
+	 * 	
+	 * @return javax.swing.JList	
+	 */
+	private JTable getComputingResourcesList() {
+		if (computingResourcesList == null) {
+			computingResourcesList = new JTable();
+			computingResourcesList.setShowHorizontalLines(false);
+			computingResourcesList
+					.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		}
+		return computingResourcesList;
+	}
+
+	/**
+	 * This method initializes jScrollPane1	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */
+	private JScrollPane getJScrollPane1() {
+		if (jScrollPane1 == null) {
+			jScrollPane1 = new JScrollPane();
+			jScrollPane1.setName("jScrollPane1");
+			jScrollPane1.setViewportView(getComputingResourcesList());
+			jScrollPane1.setPreferredSize(new Dimension(200, 250));
+		}
+		return jScrollPane1;
+	}
+
+	/**
+	 * This method initializes jPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+			gridBagConstraints1.fill = GridBagConstraints.BOTH;
+			gridBagConstraints1.gridy = 0;
+			gridBagConstraints1.weightx = 1.0;
+			gridBagConstraints1.weighty = 1.0;
+			gridBagConstraints1.gridx = 0;
+			jPanel = new JPanel();
+			jPanel.setLayout(new GridBagLayout());
+			jPanel.add(getJScrollPane(), gridBagConstraints1);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes jScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setViewportView(getPropertyTable());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes propertyTable	
+	 * 	
+	 * @return javax.swing.JTable	
+	 */
+	private JTable getPropertyTable() {
+		if (propertyTable == null) {
+			propertyTable = new SimplePropertyTable();
+		}
+		return propertyTable;
+	}
+
+	/**
+	 * This method initializes refreshButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getRefreshButton() {
+		if (refreshButton == null) {
+			refreshButton = new JButton();
+			refreshButton.setName("refreshButton");
+			refreshButton.setText("Refresh");
+		}
+		return refreshButton;
+	}
+
+	/**
+	 * This method initializes selectAllButton	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getSelectAllButton() {
+		if (selectAllButton == null) {
+			selectAllButton = new JButton();
+			selectAllButton.setText("Select available");
+		}
+		return selectAllButton;
+	}
+
+	/**
+	 * This method initializes buttonPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	protected JPanel getButtonPanel() {
+		if (buttonPanel == null) {
+			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
+			gridBagConstraints3.anchor = GridBagConstraints.SOUTHEAST;
+			gridBagConstraints3.gridy = -1;
+			gridBagConstraints3.gridx = -1;
+			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
+			gridBagConstraints2.anchor = GridBagConstraints.CENTER;
+			gridBagConstraints2.insets = new Insets(0, 0, 0, 0);
+			gridBagConstraints2.gridheight = 1;
+			gridBagConstraints2.gridwidth = 1;
+			gridBagConstraints2.gridx = -1;
+			gridBagConstraints2.gridy = -1;
+			gridBagConstraints2.ipadx = 0;
+			gridBagConstraints2.ipady = 0;
+			gridBagConstraints2.weightx = 0.5;
+			gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
+			buttonPanel = new JPanel();
+			buttonPanel.setLayout(new GridBagLayout());
+			buttonPanel.add(getRefreshButton(), gridBagConstraints2);
+			buttonPanel.add(getSelectAllButton(), gridBagConstraints3);
+		}
+		return buttonPanel;
+	}
+
+} //  @jve:decl-index=0:visual-constraint="10,10"

Added: trunk/src/appl/parallel/gui/ParallelControlPanelEngine.java
===================================================================
--- trunk/src/appl/parallel/gui/ParallelControlPanelEngine.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/gui/ParallelControlPanelEngine.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,304 @@
+package appl.parallel.gui;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.swing.JOptionPane;
+import javax.swing.JTable;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableModel;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.ext.XuluConfig;
+import appl.parallel.ComputingResource;
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.ComputingResourceProperties;
+import appl.parallel.client.RemoteExecutionController;
+import appl.parallel.client.ResourceChangeListener;
+import appl.util.NonEditableTableModel;
+import schmitzm.data.event.ObjectEvent;
+import schmitzm.data.event.ObjectListener;
+
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.appl.ModelControlManager;
+import edu.bonn.xulu.appl.XuluPlugin;
+import edu.bonn.xulu.data.XuluDataException;
+import edu.bonn.xulu.gui.ModelContentManagerContainer;
+import edu.bonn.xulu.gui.ModelControlFrame;
+import edu.bonn.xulu.gui.XuluGUIMessages;
+import edu.bonn.xulu.model.ModelContentManager;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.plugin.gui.ModelControlContainer;
+import edu.bonn.xulu.plugin.gui.ModelControlFrame_Basic;
+
+/**
+ * This class controls the {@link ParallelControlPanel}.
+ *
+ * @author Dominik Appl
+ */
+public class ParallelControlPanelEngine implements ActionListener,
+		ListSelectionListener, TableModelListener, ResourceChangeListener {
+
+	ParallelControlPanel panel;
+
+	XuluModellingPlatform xulu;
+
+	// get logger for this class
+	protected final Logger LOG = LogManager
+			.getLogger(this.getClass().getName());
+
+	private DefaultTableModel resTableModel;
+
+	private JTable resTable;
+
+	private Vector<ComputingResourceContainer> resources;
+
+	private RemoteExecutionController remoteExecutionController;
+
+	/**
+	 * @param xulu
+	 *            the active modeling platform
+	 */
+	public ParallelControlPanelEngine(XuluModellingPlatform xulu) {
+		this.xulu = xulu;
+		this.panel = new ParallelControlPanel();
+		init();
+	}
+
+	/**
+	 * @param xulu
+	 *            the active modeling platform
+	 * @param panel
+	 *            the panel to integrate
+	 */
+	public ParallelControlPanelEngine(XuluModellingPlatform xulu,
+			ParallelControlPanel panel) {
+		this.xulu = xulu;
+		this.panel = panel;
+		init();
+	}
+
+	/**
+	 * The init method must be called after all Components of the GUI are
+	 * initialized.
+	 */
+	void init() {
+		remoteExecutionController = RemoteExecutionController
+				.getRemoteExecutionController(xulu);
+		if (remoteExecutionController != null)
+			remoteExecutionController.addResourceChangeListener(this);
+		resTable = panel.computingResourcesList;
+
+		// add listeners
+		resTable.getSelectionModel().addListSelectionListener(this);
+		panel.refreshButton.addActionListener(this);
+		panel.selectAllButton.addActionListener(this);
+
+		resTableModel = new NonEditableTableModel(new Object[] { "Name",
+				"Rating" }, new boolean[] { false, true }, 1);
+		resTable.setModel(resTableModel);
+		resTable.getModel().addTableModelListener(this);
+		selectAvailableResources();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+	 */
+	public void actionPerformed(ActionEvent e) {
+		// the source of the event.
+		Object src = e.getSource();
+		if (src == panel.refreshButton) {
+			handleRefresh();
+		} else if (src == panel.selectAllButton) {
+			selectAvailableResources();
+		}
+
+	}
+
+	/**
+	 * handles the refresh button
+	 */
+	private void handleRefresh() {
+		if (remoteExecutionController != null)
+			remoteExecutionController.refreshResources();
+		else
+			JOptionPane
+					.showMessageDialog(
+							getPanel(),
+							"Error: no discovery possible. The RemoteExecutionController-Plugin can " +
+							"not be found. The plugin is required for parallel " +
+							"computation","Error",JOptionPane.ERROR_MESSAGE);
+	}
+
+	private Vector<String> getVectorOfSelectedNames() {
+
+		Object[] selectedComputingResources = getSelectedResourceContainers();
+
+		// write selected names in vector
+		Vector<String> names = new Vector<String>();
+		for (int i = 0; i < selectedComputingResources.length; i++) {
+			names
+					.add(((ComputingResourceContainer) selectedComputingResources[i])
+							.getInformation().getName());
+		}
+		return names;
+	}
+
+	private void setSelectedElements(Vector<String> names) {
+		for (int i = 0; i < resTableModel.getRowCount(); i++) {
+			ComputingResourceContainer container = (ComputingResourceContainer) resTableModel
+					.getValueAt(i, 0);
+			if (container == null)
+				return;
+			String name = ((ComputingResourceContainer) resTableModel
+					.getValueAt(i, 0)).getInformation().getName();
+			if (names.contains(name))
+				resTable.getSelectionModel().addSelectionInterval(i, i);
+		}
+	}
+
+	private void selectAvailableResources() {
+		// write available selected names in vector
+		Vector<String> names = new Vector<String>();
+		for (int i = 0; i < resTableModel.getRowCount(); i++) {
+			ComputingResourceContainer container = ((ComputingResourceContainer) resTableModel
+					.getValueAt(i, 0));
+			if (container == null)
+				return;
+			ComputingResourceProperties info = container.getInformation();
+			if (info.isAvailable())
+				names.add(info.getName());
+
+		}
+		setSelectedElements(names);
+	}
+
+	/**
+	 * @returns the first current selected ComputingResourceContainer from the
+	 *          resouce list
+	 */
+	private ComputingResourceContainer getSelectedResourceContainer() {
+		int selectedRow = resTable.getSelectedRow();
+		if (selectedRow == -1)
+			return null;
+		return (ComputingResourceContainer) resTableModel.getValueAt(
+				selectedRow, 0);
+	}
+
+	/**
+	 * @return all current selected ComputingResourceContainer from the resouce
+	 *         list
+	 */
+	ComputingResourceContainer[] getSelectedResourceContainers() {
+		int[] selRows = panel.computingResourcesList.getSelectedRows();
+		Object[] selectedValues = new Object[selRows.length];
+		for (int i = 0; i < selRows.length; i++) {
+			selectedValues[i] = resTableModel.getValueAt(selRows[i], 0);
+			if (selectedValues[i] == null)
+				return new ComputingResourceContainer[0];
+		}
+		ComputingResourceContainer[] selectedContainers = new ComputingResourceContainer[selectedValues.length];
+		for (int i = 0; i < selectedValues.length; i++)
+			selectedContainers[i] = (ComputingResourceContainer) selectedValues[i];
+		return selectedContainers;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
+	 */
+	public void valueChanged(ListSelectionEvent e) {
+		Object src = e.getSource();
+		if (src == resTable.getSelectionModel()) {
+			ComputingResourceContainer selValue = getSelectedResourceContainer();
+			if (selValue == null)
+				return;
+			panel.propertyTable.setPropertyData(selValue.getInformation()
+					.getProperties());
+		}
+	}
+
+	/**
+	 * Listens for user changes of the rating
+	 *
+	 * @see javax.swing.event.TableModelListener#tableChanged(javax.swing.event.TableModelEvent)
+	 */
+	public void tableChanged(TableModelEvent e) {
+		// enter the new rating information to the configuration
+		XuluConfig config = XuluConfig.getXuluConfig();
+		if (e.getType() == TableModelEvent.UPDATE) {
+			int changedRow = e.getFirstRow();
+			// only the 2nd col is editable
+			String newRating = resTableModel.getValueAt(changedRow, 1)
+					.toString();
+			try {
+				int rating = Integer.valueOf(newRating);
+				if (rating < 0) {
+					resTableModel.setValueAt(0, changedRow, 1);
+					throw new UnsupportedOperationException(
+							"Rating must be > 0");
+				}
+
+			} catch (Exception f) {
+				resTableModel.setValueAt(0, changedRow, 1);
+				throw new UnsupportedOperationException(
+						"Rating must be an integer!");
+			}
+			String computerName = resTableModel.getValueAt(changedRow, 0)
+					.toString();
+			String prefix = "PerformanceRating";
+			String key = prefix + "." + computerName;
+			config.setProperty(key, newRating);
+		}
+	}
+
+	/**
+	 * @return the panel
+	 */
+	public ParallelControlPanel getPanel() {
+		return this.panel;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.client.ResourceChangeListener#updateResources(java.util.Vector)
+	 */
+	public void updateResources(
+			Vector<ComputingResourceContainer> currentResources) {
+		// get the selected values (and restore the selection after list
+		// initializing)
+		Vector names = getVectorOfSelectedNames();
+
+		// clear list
+		resTableModel.setRowCount(0);
+		for (ComputingResourceContainer res : currentResources) {
+			// init the rating from the configuration
+			XuluConfig config = XuluConfig.getXuluConfig();
+			String computerName = res.getInformation().getName();
+			String prefix = "PerformanceRating";
+			String key = prefix + "." + computerName;
+			String rating = config.getProperty(key, false);
+			// if no rating found use the selfrating of the machine
+			if (rating == null || rating.equals("0"))
+				rating = res.getInformation().getProperty("Rating");
+			if (rating == null)
+				rating = "0"; // '0' means average
+			resTableModel.addRow(new Object[] { res, rating });
+		}
+
+		// restore selection
+		this.setSelectedElements(names);
+	}
+}

Added: trunk/src/appl/parallel/gui/SimplePropertyTable.java
===================================================================
--- trunk/src/appl/parallel/gui/SimplePropertyTable.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/gui/SimplePropertyTable.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,46 @@
+package appl.parallel.gui;
+
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+
+/**
+ * Just a simple 2 column Property Table
+ * 
+ * @author Dominik Appl
+ */
+public class SimplePropertyTable extends JTable {
+
+	private final String colname1;
+
+	private final String colname2;
+
+	public SimplePropertyTable(String colname1, String colname2) {
+		super(1, 2);
+		this.colname1 = colname1;
+		this.colname2 = colname2;
+
+	}
+
+	public SimplePropertyTable() {
+		this("Property", "Value");
+	}
+
+	public void setPropertyData(Properties propdata) {
+		Enumeration keys = propdata.keys();
+		// Create array
+		String[][] data = new String[propdata.size()][2];
+		int i = 0;
+		while (keys.hasMoreElements()) {
+			data[i][0] = (String) keys.nextElement();
+			data[i][1] = (String) propdata.getProperty(data[i][0]);
+			i++;
+		}
+		setModel(new DefaultTableModel(data,
+				new String[] { colname1, colname2 }));
+	}
+
+}

Added: trunk/src/appl/parallel/gui/package.html
===================================================================
--- trunk/src/appl/parallel/gui/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/gui/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains classes related to the GUI for the parallelization functionality of XULU.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/model/AbstractParallelStepModel.java
===================================================================
--- trunk/src/appl/parallel/model/AbstractParallelStepModel.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/model/AbstractParallelStepModel.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,57 @@
+package appl.parallel.model;
+
+import appl.parallel.spmd.AdvancedSPMDClientController;
+import appl.parallel.spmd.AdvancedSPMDClientInterface;
+import appl.parallel.spmd.SPMDClientInterface;
+import edu.bonn.xulu.model.AbstractStepModel;
+import edu.bonn.xulu.model.ModelContentManager;
+import edu.bonn.xulu.model.event.ModelStepFinishedEvent;
+import edu.bonn.xulu.model.event.ModelStepStartedEvent;
+
+/**
+ * This class is used instead of the {@link AbstractStepModel} for implementation
+ * of parallel algorithms. It provides access to the {@link SPMDClientInterface}.
+ * 
+ * @author Dominik Appl
+ */
+public abstract class AbstractParallelStepModel extends AbstractStepModel
+		implements ParallelStepModel {
+
+	SPMDClientInterface SPMDController;
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.model.ParallelStepModel#getSPMDController()
+	 */
+	public SPMDClientInterface getSPMDController() {
+		if (SPMDController == null) {
+			throw new UnsupportedOperationException(
+					"SPMDController is null!"
+							+ "You cannot use the SPMDController before the performInit-method");
+		}
+		return SPMDController;
+	}
+
+	/**
+	 * @return the Advanced SPMD controller which provides access to advanced parallel functionality
+	 * like preloading or multithreading
+	 */
+	public AdvancedSPMDClientInterface getAdvancedSPMDController() {
+		return (AdvancedSPMDClientController) getSPMDController();
+	}
+
+	/**
+	 * A new instance. See {@link AbstractStepModel#AbstractStepModel(ModelContentManager)} for details
+	 * 
+	 */
+	public AbstractParallelStepModel(ModelContentManager contentManager) {
+		super(contentManager);
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.model.ParallelStepModel#setSPMDController(appl.parallel.spmd.SPMDClientController)
+	 */
+	public void setSPMDController(SPMDClientInterface controller) {
+		this.SPMDController = controller;
+	}
+
+}

Added: trunk/src/appl/parallel/model/ParallelStepModel.java
===================================================================
--- trunk/src/appl/parallel/model/ParallelStepModel.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/model/ParallelStepModel.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,30 @@
+package appl.parallel.model;
+
+import java.io.Serializable;
+
+import edu.bonn.xulu.model.StepModel;
+import appl.parallel.spmd.SPMDClientInterface;
+
+/**
+ * This class extends the functionality of a Xulu-StepModel. It provides
+ * access to the {@link SPMDClientInterface} for parallel access. For implementation
+ * it is recommended to subclass {@link AbstractParallelStepModel}.
+ * 
+ * @see AbstractParallelStepModel
+ * 
+ * @author Dominik Appl
+ */
+public interface ParallelStepModel extends StepModel, Serializable {
+
+	/**
+	 * @return the SPMD client controller which provides access to the parallelization control
+	 */
+	public SPMDClientInterface getSPMDController();
+
+	/**
+	 * Sets the SPMD Controller
+	 * @param controller the controller to set
+	 */
+	public void setSPMDController(SPMDClientInterface controller);
+
+}
\ No newline at end of file

Added: trunk/src/appl/parallel/model/package.html
===================================================================
--- trunk/src/appl/parallel/model/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/model/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains classes which are used for integration of parallel models into the XuluModelling-Platform.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/package.html
===================================================================
--- trunk/src/appl/parallel/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains some general classes used for parallelization.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitor.java
===================================================================
--- trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitor.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitor.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,289 @@
+package appl.parallel.plugin.event;
+
+import javax.swing.SwingUtilities;
+import java.awt.BorderLayout;
+import javax.swing.JPanel;
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JToggleButton;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import javax.swing.JCheckBox;
+import javax.swing.BoxLayout;
+
+import edu.bonn.xulu.gui.XuluInternalFrame;
+
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import javax.swing.JTabbedPane;
+import java.awt.Dimension;
+import java.awt.Button;
+import java.awt.CardLayout;
+import javax.swing.JLabel;
+import java.awt.Insets;
+import javax.swing.JTextPane;
+import javax.swing.text.html.HTMLDocument;
+import javax.swing.text.DefaultStyledDocument;
+
+/**
+ * Provides a GUI for the {@link SimpleCommEventMonitorEngine}
+ * 
+ * @author Dominik Appl
+ */
+public class SimpleCommEventMonitor extends XuluInternalFrame {
+
+	private static final long serialVersionUID = 1L;
+
+	JPanel jContentPane = null;
+
+	JScrollPane jScrollPane = null;
+
+	JTable timeEventTable = null;
+
+	JPanel optionsPanel = null;
+
+	JCheckBox timeEventEnabled = null;
+
+	JCheckBox transferEventEnabled = null;
+
+	SimpleCommEventMonitorEngine engine;
+
+	JTabbedPane jTabbedPane = null;
+
+	Button clearButton = null;
+
+	JScrollPane jScrollPane1 = null;
+
+	JTable transferEventTable = null;
+
+	private JTextPane jTextPane = null;
+
+	/**
+	 * This method initializes jScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setViewportView(getTimeEventTable());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes timeEventTable	
+	 * 	
+	 * @return javax.swing.JTable	
+	 */
+	private JTable getTimeEventTable() {
+		if (timeEventTable == null) {
+			timeEventTable = new JTable();
+			timeEventTable.setDoubleBuffered(true);
+		}
+		return timeEventTable;
+	}
+
+	/**
+	 * This method initializes optionsPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getOptionsPanel() {
+		if (optionsPanel == null) {
+			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
+			gridBagConstraints8.fill = GridBagConstraints.BOTH;
+			gridBagConstraints8.gridy = 0;
+			gridBagConstraints8.weightx = 1.0;
+			gridBagConstraints8.weighty = 0.0;
+			gridBagConstraints8.gridwidth = 1;
+			gridBagConstraints8.gridheight = 1;
+			gridBagConstraints8.anchor = GridBagConstraints.EAST;
+			gridBagConstraints8.insets = new Insets(0, 0, 0, 0);
+			gridBagConstraints8.ipadx = 1;
+			gridBagConstraints8.ipady = 0;
+			gridBagConstraints8.gridx = 9;
+			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
+			gridBagConstraints6.insets = new Insets(5, 5, 5, 5);
+			gridBagConstraints6.gridy = 0;
+			gridBagConstraints6.anchor = GridBagConstraints.WEST;
+			gridBagConstraints6.fill = GridBagConstraints.HORIZONTAL;
+			gridBagConstraints6.gridx = 8;
+			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
+			gridBagConstraints5.insets = new Insets(5, 5, 5, 2);
+			gridBagConstraints5.gridy = 0;
+			gridBagConstraints5.anchor = GridBagConstraints.WEST;
+			gridBagConstraints5.fill = GridBagConstraints.NONE;
+			gridBagConstraints5.gridwidth = 1;
+			gridBagConstraints5.gridx = 7;
+			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
+			gridBagConstraints4.insets = new Insets(5, 5, 5, 5);
+			gridBagConstraints4.gridy = 0;
+			gridBagConstraints4.anchor = GridBagConstraints.WEST;
+			gridBagConstraints4.gridwidth = 1;
+			gridBagConstraints4.gridheight = 1;
+			gridBagConstraints4.gridx = 1;
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.gridx = 0;
+			gridBagConstraints.gridy = 0;
+			optionsPanel = new JPanel();
+			optionsPanel.setLayout(new GridBagLayout());
+			optionsPanel.add(getTimeEventEnabled(), gridBagConstraints4);
+			optionsPanel.add(getTransferEventEnabled(), gridBagConstraints5);
+			optionsPanel.add(getClearButton(), gridBagConstraints6);
+			optionsPanel.add(getJTextPane(), gridBagConstraints8);
+		}
+		return optionsPanel;
+	}
+
+	/**
+	 * This method initializes timeEventEnabled	
+	 * 	
+	 * @return javax.swing.JCheckBox	
+	 */
+	private JCheckBox getTimeEventEnabled() {
+		if (timeEventEnabled == null) {
+			timeEventEnabled = new JCheckBox();
+			timeEventEnabled.setText("log time events");
+			timeEventEnabled.setName("timeEventEnabled");
+			timeEventEnabled.addActionListener(engine);
+		}
+		return timeEventEnabled;
+	}
+
+	/**
+	 * This method initializes transferEventEnabled	
+	 * 	
+	 * @return javax.swing.JCheckBox	
+	 */
+	private JCheckBox getTransferEventEnabled() {
+		if (transferEventEnabled == null) {
+			transferEventEnabled = new JCheckBox();
+			transferEventEnabled.setText("log transferEvents");
+			transferEventEnabled.setName("transferEventEnabled");
+			transferEventEnabled.addActionListener(engine);
+		}
+		return transferEventEnabled;
+	}
+
+	/**
+	 * This is the default constructor
+	 * @param engine the engine responsible for event handling
+	 */
+	public SimpleCommEventMonitor(SimpleCommEventMonitorEngine engine) {
+		super("Simple Communication Event Monitor");
+		this.setClosable(true);
+		this.setDefaultCloseOperation(HIDE_ON_CLOSE);
+		this.engine = engine;
+		initialize();
+	}
+
+	/**
+	 * This method initializes this class
+	 * 
+	 */
+	private void initialize() {
+		this.setSize(608, 326);
+		this.setContentPane(getJContentPane());
+		this.setTitle("Communication Monitor");
+	}
+
+	/**
+	 * This method initializes jContentPane
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJContentPane() {
+		if (jContentPane == null) {
+			jContentPane = new JPanel();
+			jContentPane.setLayout(new BoxLayout(getJContentPane(),
+					BoxLayout.Y_AXIS));
+			jContentPane.add(getJTabbedPane(), null);
+			jContentPane.add(getOptionsPanel(), null);
+		}
+		return jContentPane;
+	}
+
+	/* (non-Javadoc)
+	 * @see edu.bonn.xulu.gui.XuluInternalFrame#refresh()
+	 */
+	@Override
+	public void refresh() {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * This method initializes jTabbedPane	
+	 * 	
+	 * @return javax.swing.JTabbedPane	
+	 */
+	private JTabbedPane getJTabbedPane() {
+		if (jTabbedPane == null) {
+			jTabbedPane = new JTabbedPane();
+			jTabbedPane.addTab("Time Events", null, getJScrollPane(), null);
+			jTabbedPane
+					.addTab("Transfer Events", null, getJScrollPane1(), null);
+		}
+		return jTabbedPane;
+	}
+
+	/**
+	 * This method initializes clearButton	
+	 * 	
+	 * @return java.awt.Button	
+	 */
+	private Button getClearButton() {
+		if (clearButton == null) {
+			clearButton = new Button();
+			clearButton.setLabel("Clear all");
+			clearButton.setMinimumSize(new Dimension(100, 20));
+			clearButton.setName("clearButton");
+			clearButton.addActionListener(engine);
+		}
+		return clearButton;
+	}
+
+	/**
+	 * This method initializes jScrollPane1	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */
+	private JScrollPane getJScrollPane1() {
+		if (jScrollPane1 == null) {
+			jScrollPane1 = new JScrollPane();
+			jScrollPane1.setViewportView(getTransferEventTable());
+		}
+		return jScrollPane1;
+	}
+
+	/**
+	 * This method initializes transferEventTable	
+	 * 	
+	 * @return javax.swing.JTable	
+	 */
+	private JTable getTransferEventTable() {
+		if (transferEventTable == null) {
+			transferEventTable = new JTable();
+			transferEventTable.setDoubleBuffered(true);
+		}
+		return transferEventTable;
+	}
+
+	/**
+	 * This method initializes jTextPane	
+	 * 	
+	 * @return javax.swing.JTextPane	
+	 */
+	private JTextPane getJTextPane() {
+		if (jTextPane == null) {
+			jTextPane = new JTextPane();
+			jTextPane
+					.setText("Hint: Hold CTRL while clicking on a table header for secondary sorting");
+			jTextPane.setMaximumSize(new Dimension(100, 50));
+		}
+		return jTextPane;
+	}
+
+} //  @jve:decl-index=0:visual-constraint="10,10"

Added: trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitorEngine.java
===================================================================
--- trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitorEngine.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitorEngine.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,197 @@
+package appl.parallel.plugin.event;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.GregorianCalendar;
+
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
+
+import appl.ext.XuluConfig;
+import appl.parallel.client.RemoteEventHandler;
+import appl.parallel.event.TimeEvent;
+import appl.parallel.event.TimeMonitor;
+import appl.parallel.event.TransferEvent;
+import appl.parallel.event.TransferMonitor;
+
+/**
+ * Controls the {@link SimpleCommEventMonitorPlugin}
+ * 
+ * @author Dominik Appl
+ */
+public class SimpleCommEventMonitorEngine implements TimeMonitor,
+		TransferMonitor, ActionListener {
+
+	private XuluConfig config;
+
+	private boolean timeMonitoring;
+
+	private boolean transferMonitoring;
+
+	private SimpleCommEventMonitor monitor;
+
+	private final RemoteEventHandler eventProxy;
+
+	private DefaultTableModel timeEventModel;
+
+	private DefaultTableModel transferEventModel;
+
+	public SimpleCommEventMonitorEngine(RemoteEventHandler eventProxy) {
+		this.eventProxy = eventProxy;
+		config = XuluConfig.getXuluConfig();
+
+	}
+
+	/**
+	 * @return the GUI for the monitor
+	 */
+	public SimpleCommEventMonitor getMonitor() {
+		if (monitor == null) {
+			monitor = new SimpleCommEventMonitor(this);
+			initGUI();
+		}
+		return monitor;
+	}
+
+	/**
+	 * inits the {@link SimpleCommEventMonitor}
+	 */
+	public void initGUI() {
+		// get Data from XuluConfig:
+		timeMonitoring = config
+				.getBooleanProperty("SimpleCommEventMonitor.timemonitoring");
+		transferMonitoring = config
+				.getBooleanProperty("SimpleCommEventMonitor.transfermonitoring");
+		// registers itself as timeEvent receiver
+		if (timeMonitoring)
+			eventProxy.addTimeEventListener(this);
+		if (transferMonitoring)
+			eventProxy.addTransferEventListener(this);
+		initTimeEventTable();
+		initTransferEventTable();
+		monitor.timeEventEnabled.setSelected(timeMonitoring);
+		monitor.transferEventEnabled.setSelected(transferMonitoring);
+	}
+
+	/**
+	 * 
+	 */
+	private void initTimeEventTable() {
+		JTable table = monitor.timeEventTable;
+
+		timeEventModel = new DefaultTableModel(
+				new Object[] { "Receive Time", "Event type", "Event Source",
+						"Event target", "Exec time (ms)" }, 0);
+		TableRowSorter sorter = new TableRowSorter<TableModel>(timeEventModel);
+		sorter.setComparator(4, LONG_COMPARATOR);
+		table.setModel(timeEventModel);
+		table.setRowSorter(sorter);
+
+	}
+
+	private void initTransferEventTable() {
+		JTable table = monitor.transferEventTable;
+		transferEventModel = new DefaultTableModel(new Object[] {
+				"Receive Time", "Event type", "Event Source", "Event target",
+				"Size (kb)" }, 0);
+		TableRowSorter sorter = new TableRowSorter(transferEventModel);
+		sorter.setComparator(4, LONG_COMPARATOR);
+		table.setModel(transferEventModel);
+		table.setRowSorter(sorter);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.event.TimeMonitor#receiveTimeEvent(appl.parallel.event.TimeEvent)
+	 */
+	public synchronized void receiveTimeEvent(TimeEvent t) {
+		timeEventModel.addRow(new Object[] { getCurrentTimeString(),
+				t.getType(), t.getSrc(), t.getTarget(),
+				(long) (t.getTime() / 1000000) });
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.event.TransferMonitor#receiveTransferEvent(appl.parallel.event.TransferEvent)
+	 */
+	public void receiveTransferEvent(TransferEvent t) {
+		transferEventModel.addRow(new Object[] { getCurrentTimeString(),
+				t.getType(), t.getSrc(), t.getTarget(),
+				(long) (t.getSize() / 1024) });
+	}
+
+	public String getCurrentTimeString() {
+		Calendar cal = new GregorianCalendar();
+		String hour = String.valueOf(cal.get(Calendar.HOUR_OF_DAY));
+		while (hour.length() < 2)
+			hour = "0" + hour;
+		String min = String.valueOf(cal.get(Calendar.MINUTE));
+		while (min.length() < 2)
+			min = "0" + min;
+		String sec = String.valueOf(cal.get(Calendar.SECOND));
+		while (sec.length() < 2)
+			sec = "0" + sec;
+		String ms = String.valueOf(cal.get(Calendar.MILLISECOND));
+		while (ms.length() < 3)
+			ms = "0" + ms;
+		String time = hour + ":" + min + ":" + sec + ":" + ms;
+		return time;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+	 */
+	public void actionPerformed(ActionEvent e) {
+		Object src = e.getSource();
+		if (src == monitor.transferEventEnabled) {
+			eventProxy.removeTransferMonitor(this);
+			if (monitor.transferEventEnabled.isSelected()) {
+				eventProxy.addTransferEventListener(this);
+				config.setBooleanProperty(
+						"SimpleCommEventMonitor.transfermonitoring", true);
+			} else
+				config.setBooleanProperty(
+						"SimpleCommEventMonitor.transfermonitoring", false);
+		}
+		if (src == monitor.timeEventEnabled) {
+			eventProxy.removeTimeMonitor(this);
+			if (monitor.timeEventEnabled.isSelected()) {
+				eventProxy.addTimeEventListener(this);
+				config.setBooleanProperty(
+						"SimpleCommEventMonitor.timemonitoring", true);
+			} else
+				config.setBooleanProperty(
+						"SimpleCommEventMonitor.timemonitoring", false);
+		}
+		if (src == monitor.clearButton) {
+			initTimeEventTable();
+			initTransferEventTable();
+		}
+	}
+
+	/**
+	 * stops the execution
+	 */
+	public void stop() {
+		eventProxy.removeTimeMonitor(this);
+		eventProxy.removeTransferMonitor(this);
+	}
+
+	/**
+	 * The comparator is used for sorting the values in the {@link JTable}
+	 */
+	public static final Comparator LONG_COMPARATOR = new Comparator() {
+		public int compare(Object o1, Object o2) {
+			return ((Long) o1).compareTo((Long) o2);
+		}
+	};
+
+}

Added: trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitorPlugin.java
===================================================================
--- trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitorPlugin.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/plugin/event/SimpleCommEventMonitorPlugin.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,73 @@
+package appl.parallel.plugin.event;
+
+import javax.swing.JMenuItem;
+import javax.swing.JTable;
+
+import appl.parallel.client.RemoteExecutionController;
+import appl.parallel.event.TimeEvent;
+import appl.parallel.event.TransferEvent;
+
+import edu.bonn.xulu.appl.XuluPlugin;
+import edu.bonn.xulu.gui.XuluInternalFrame;
+import edu.bonn.xulu.plugin.appl.AbstractMenuPlugin;
+
+/**
+ * The {@link XuluPlugin} logs {@link TransferEvent}s and {@link TimeEvent}s.
+ * The Events are displayed in a sortable {@link JTable}.
+ * 
+ * @author Dominik Appl
+ */
+public class SimpleCommEventMonitorPlugin extends AbstractMenuPlugin {
+
+	/**
+	 * Creates a new plugin
+	 */
+	public SimpleCommEventMonitorPlugin() {
+		super(4, "Xulu/V Communication Monitor");
+		// TODO Auto-generated constructor stub
+	}
+
+	/**
+	 * Creates a new plugin
+	 * 
+	 * @param xuluMenuNo
+	 *            the position of the menu in the menubar
+	 * @param menuItem
+	 *            the menu to insert
+	 */
+	public SimpleCommEventMonitorPlugin(int xuluMenuNo, JMenuItem menuItem) {
+		super(xuluMenuNo, menuItem);
+		// TODO Auto-generated constructor stub
+	}
+
+	/**
+	 * Creates a new plugin
+	 * 
+	 * @param xuluMenuNo
+	 *            the position of the menu in the menubar
+	 * @param menuItemName
+	 *            the name of the entry to insert
+	 */
+	public SimpleCommEventMonitorPlugin(int xuluMenuNo, String menuItemName) {
+		super(xuluMenuNo, menuItemName);
+		// TODO Auto-generated constructor stub
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see edu.bonn.xulu.plugin.appl.AbstractMenuPlugin#createPluginApplication()
+	 */
+	@Override
+	protected XuluInternalFrame createPluginApplication() throws Exception {
+		RemoteExecutionController controller = RemoteExecutionController
+				.getRemoteExecutionController(appl);
+		if (controller == null)
+			throw new UnsupportedOperationException(
+					"Remote Execution Monitor plugin not found!");
+		SimpleCommEventMonitorEngine engine = new SimpleCommEventMonitorEngine(
+				controller.getEventProxy());
+		return engine.getMonitor();
+	}
+
+}

Added: trunk/src/appl/parallel/plugin/event/package.html
===================================================================
--- trunk/src/appl/parallel/plugin/event/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/plugin/event/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,6 @@
+<html>
+<body>
+	The Plugin can monitor the parallelization, especially the execution time of remote commands
+	and the size of transfered data.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/server/MasterSlaveResource.java
===================================================================
--- trunk/src/appl/parallel/server/MasterSlaveResource.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/server/MasterSlaveResource.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,10 @@
+package appl.parallel.server;
+
+/**
+ * A resource for Master / Slave Computing (indicator for now)
+ * 
+ * @author Dominik Appl
+ */
+public interface MasterSlaveResource {
+
+}

Added: trunk/src/appl/parallel/server/PartitionDataManager.java
===================================================================
--- trunk/src/appl/parallel/server/PartitionDataManager.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/server/PartitionDataManager.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,696 @@
+package appl.parallel.server;
+
+import java.awt.Rectangle;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.rmi.Naming;
+import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.data.LoadingException;
+import appl.parallel.client.DataServer;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.data.PartitionDataHandler;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.event.TimeEvent;
+import appl.parallel.event.TransferEvent;
+import appl.parallel.event.CommEvent.CommType;
+import appl.parallel.services.RemoteEventProxy;
+import appl.parallel.spmd.MultiDataInfo;
+import appl.parallel.spmd.MultiDataPartitionObject;
+import appl.parallel.spmd.SPMDClientController;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.PartitionInfo;
+import appl.parallel.spmd.split.SinglePartitionInfo;
+import appl.parallel.spmd.split.SplitMap;
+import appl.parallel.thread.DataServerThread;
+
+/**
+ * Manages the all data for the {@link XuluServer}. This includes retrieval of
+ * partitions from connected resources like the {@link DataServer} or, as part
+ * of the update of neighborhood regions, from other
+ * {@link XuluServer XuluServers}.
+ *
+ * @author Dominik Appl
+ */
+public class PartitionDataManager extends UnicastRemoteObject implements
+		PartitionDataServer {
+
+	/**
+	 * The Thread is used for updating the partitions neighborhood region from
+	 * the other servers.
+	 *
+	 * @author Dominik Appl
+	 */
+	class UpdateThread extends DataServerThread {
+
+		private final DataPartition thisPartition;
+
+		private final Rectangle updateBounds;
+
+		private final int id;
+
+		private final String hostname;
+
+		public UpdateThread(PartitionDataServer dataServer,
+				String ipOrHostname, DataPartition thisPartition,
+				Rectangle updateBounds, int id, CommEventSink sink) {
+			super(dataServer, null, null, CommType.REMOTE_UPDATE, sink);
+			hostname = ipOrHostname;
+			// TODO Auto-generated constructor stub
+			this.thisPartition = thisPartition;
+			this.updateBounds = updateBounds;
+			this.id = id;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see appl.parallel.thread.ExecutionThread#fireTimeEvents(long,
+		 *      java.lang.Object)
+		 */
+		@Override
+		protected void fireTimeEvents(long execTime, Object result) {
+			try {
+				eventSink.fireRemoteEvent(new TimeEvent(execTime,
+						dataServerName, hostname, commType));
+			} catch (RemoteException e) {
+				e.printStackTrace();
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see appl.parallel.thread.ExecutionThread#fireTransferEvent(java.lang.Object)
+		 */
+		@Override
+		protected void fireTransferEvent(Object result) {
+			try {
+				eventSink.fireRemoteEvent(new TransferEvent(dataServerName,
+						hostname, commType, new Object[] { result }));
+			} catch (RemoteException e) {
+				e.printStackTrace();
+			}
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see appl.parallel.thread.ExecutionThread#run()
+		 */
+		@Override
+		protected Object run() throws Exception {
+			try {
+				DataPartition updateData = getServer().getPartition(id,
+						updateBounds);
+				// apply update:
+				this.thisPartition.setPartition(updateData, updateBounds);
+				return updateData;
+			} catch (Exception e) {
+				LOG.error("Error while retrieving partition " + updateBounds
+						+ "from PartitionDataServer with ip " + hostname);
+			}
+			return null;
+		}
+	}
+
+	private final String bindingName = "PartitionDataServer";
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	/**
+	 * all partition data. The key is the id. Is an Hashtable instead of
+	 * HashMasp for thread-safty.
+	 */
+	private Hashtable<Integer, DataPartition> data = new Hashtable<Integer, DataPartition>(
+			15);
+
+	/**
+	 * the names of the data objects
+	 */
+	private HashMap<String, Integer> NameToIDMapping = new HashMap<String, Integer>(
+			15);
+
+	private HashMap<Integer, SinglePartitionInfo> infos = new HashMap<Integer, SinglePartitionInfo>(
+			10);
+
+	private HashMap<String, Object> baseParameters = new HashMap<String, Object>(
+			10);
+
+	private final PartitionDataServer[] dataServers;
+
+	private final ExecutorService executor;
+
+	private final String[] IPs;
+
+	private boolean dataServersInitialized = false;
+
+	private HashMap<String, MultiDataInfo> multiDataInfos = new HashMap<String, MultiDataInfo>(
+			10);
+
+	private final String dataServerName;
+
+	private final CommEventSink remoteEventReceiver;
+
+	private String[] hostnames;
+
+	private ClientDataServer localSPMDClient;
+
+	private final int registryPort;
+
+	/**
+	 * Creates and inits a new PartitionDataserver.
+	 *
+	 * @param IPs
+	 *            the IPs of participating Servers for neighborhood updates(may
+	 *            include port specification)
+	 * @param remoteEventReceiver
+	 *            generated events are forwarded to the receiver
+	 * @param registryPort
+	 *            port of the registry to which the {@link PartitionDataManager}
+	 *            should be bound
+	 * @throws RemoteException
+	 *             if a connection to a participating server fails
+	 */
+	public PartitionDataManager(String[] IPs,
+			CommEventSink remoteEventReceiver, int registryPort)
+			throws RemoteException {
+		// create NameToID and IdToInfo-Mapping
+		this.IPs = IPs;
+		this.remoteEventReceiver = remoteEventReceiver;
+		this.registryPort = registryPort;
+
+		dataServers = new PartitionDataServer[IPs.length];
+		startTheServer();
+
+		// start Thread service
+		executor = Executors.newCachedThreadPool();
+		String name = "unknown PartitionDataServer";
+		try {
+			name = InetAddress.getLocalHost().getHostName();
+		} catch (UnknownHostException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		dataServerName = name;
+		// try to get the hostnames
+		hostnames = new String[IPs.length];
+		for (int i = 0; i < IPs.length; i++) {
+			// try {
+			hostnames[i] = IPs[i];
+			// hostnames[i] = InetAddress.getByName(IPs[i]).getHostName();
+			// } catch (UnknownHostException e) {
+			// LOG.warn("Exception while retrivieving hostname of address: " +
+			// IPs[i]);
+			// }
+		}
+	}
+
+	/**
+	 * Same as {@link #PartitionDataManager(String[], CommEventSink, int)}, but uses
+	 * a local SPMDClient. <br>
+	 * This is used when a Server is running inside the Xulu-Client. It has
+	 * performance advantages (direct access - no TCP/IP)
+	 *
+	 * @param IPs
+	 *            the IPs of participating Servers for neighborhood updates(may
+	 *            include port specification)
+	 * @param remoteEventReceiver
+	 *            generated events are forwarded to the receiver
+	 * @param registryport
+	 *            port of the registry to which the {@link PartitionDataManager}
+	 *            should be bound
+	 * @param localSPMDClient
+	 *            a {@link ClientDataServer} for fast local access
+	 * @throws RemoteException
+	 */
+	public PartitionDataManager(String[] IPs,
+			RemoteEventProxy remoteEventReceiver, int registryport,
+			ClientDataServer localSPMDClient) throws RemoteException {
+		this(IPs, remoteEventReceiver, registryport);
+		this.localSPMDClient = localSPMDClient;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.client.DataServer#addData(appl.parallel.spmd.split.DataPartition)
+	 */
+	public void addData(DataPartition partition) throws RemoteException {
+		if (partition == null) {
+			LOG.warn("To add partition was null - no data added");
+			return;
+		}
+		data.put(partition.getRootID(), partition);
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#addMultiDataInfos(java.util.HashMap)
+	 */
+	public void addMultiDataInfos(
+			HashMap<String, MultiDataInfo> newMultiDataInfos)
+			throws RemoteException {
+		this.multiDataInfos.putAll(newMultiDataInfos);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#addPartitionInfos(java.util.Vector)
+	 */
+	public void addPartitionInfos(
+			Vector<SinglePartitionInfo> singlePartitionInfos)
+			throws RemoteException {
+		for (SinglePartitionInfo singlePartitionInfo : singlePartitionInfos) {
+			NameToIDMapping.put(singlePartitionInfo.getBaseResourceName(),
+					singlePartitionInfo.getBaseResourceID());
+			infos.put(singlePartitionInfo.getBaseResourceID(),
+					singlePartitionInfo);
+		}
+	}
+
+	/**
+	 * @param name
+	 * @param idx
+	 */
+	public void destroyMultiPartition(String name, int idx) {
+
+	}
+
+	/**
+	 * returns the baseParameter by name
+	 *
+	 * @param name
+	 *            the name of the parameter
+	 * @return the parameter
+	 */
+	public Object getBaseParameter(String name) {
+		return baseParameters.get(name);
+	}
+
+	/**
+	 * Returns a a (remote) PartitionDataServer for an IP-Address. Looks up the
+	 * PartitionDataServer in the registry
+	 */
+	private PartitionDataServer getConnection(String ip) {
+		PartitionDataServer server;
+		// lookup server
+		try {
+			server = (PartitionDataServer) Naming.lookup("rmi://" + ip + "/"
+					+ bindingName);
+		} catch (Exception e) {
+			LOG.error("bindig of " + ip + " failed" + e.getMessage(), e);
+			e.printStackTrace();
+			return null;
+		}
+		return server;
+	}
+
+	/**
+	 * Returns the {@link DataPartition} associated with the given ID
+	 *
+	 * @param id
+	 *            the id of the data
+	 * @return the data
+	 */
+	public synchronized DataPartition getData(int id) throws RemoteException {
+		// check if in hashtable already
+		DataPartition partition = data.get(id);
+		if (partition != null)
+			return partition;
+		// if not in hashtable:
+		// load the data and put it into hash
+		// find the element with the ID:
+		SinglePartitionInfo info = infos.get(id);
+
+		if (info == null) {
+			LOG.warn("No partition with id " + id + " found!");
+			return null;
+		}
+		// retrieve data from client or other location
+		try {
+			// if there is a local server try to get the local partition
+			PartitionDataHandler partitionDataHandler = info
+					.getPartitionDataHandler();
+			if (localSPMDClient != null)
+				partitionDataHandler.setSPMDClient(localSPMDClient);
+			partition = partitionDataHandler.load();
+		} catch (LoadingException e) {
+			// TODO Auto-generated catch block
+			LOG.error("Loading of partition with id '" + id
+					+ "' failed. Null returned!");
+			e.printStackTrace();
+			return null;
+		}
+		if (partition == null) {
+			LOG.error("Loading of partition with id '" + id
+					+ "' failed. Null returned!");
+			return null;
+		}
+
+		// enter data in partition table
+		data.put(id, partition);
+		return partition;
+	}
+
+	/**
+	 * Gets a partition by name
+	 *
+	 * @param name
+	 *            the name of the resource (probably given by the programmer)
+	 * @return the partition or null if not found
+	 */
+	public DataPartition getData(String name) {
+		Integer id = NameToIDMapping.get(name);
+		if (id == null) {
+			LOG.warn("No data for name " + name + " found! Returning null");
+			return null;
+		}
+		try {
+			return getData(id);
+		} catch (RemoteException e) {
+			// should never be reached (because the method call is local
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the partition info with the specified id
+	 *
+	 * @param id
+	 *            the id of the partition
+	 * @return the info
+	 */
+	public PartitionInfo getInfo(int id) {
+		return infos.get(id);
+	}
+
+	/**
+	 * Gets a partition of a multi-data element. NOTE THAT ALL PARTITIONS OF THE
+	 * MULTIGRID WILL BE LOADED (watch out for loading performance!).
+	 *
+	 * @param name
+	 *            the name of the resource (probably given by the programmer)
+	 * @return the partition
+	 * @see SPMDClientController#addToMultiDataSplitControl(Object[], String)
+	 */
+	public DataPartition[] getMultiData(String name) {
+		// fill an array with the partitions
+		DataPartition[] partitions = new DataPartition[multiDataInfos.get(name)
+				.getCount()];
+		for (int i = 0; i < partitions.length; i++) {
+			partitions[i] = getMultiData(name, i);
+		}
+		return partitions;
+	}
+
+	/**
+	 * Gets a partition of a multi-data element. Only the resource at the given
+	 * position will be loaded.
+	 *
+	 * @param name
+	 *            the name of the resource (probably given by the programmer)
+	 * @param pos
+	 *            the index of the requested element
+	 * @return the partition
+	 * @see SPMDClientController#addToMultiDataSplitControl(Object[], String)
+	 */
+	public DataPartition getMultiData(String name, int pos) {
+		try {
+			return getData(multiDataInfos.get(name).getMultiID(pos));
+		} catch (RemoteException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#getMultiDataInfo(java.lang.String)
+	 */
+	public MultiDataInfo getMultiDataInfo(String name) throws RemoteException {
+		return multiDataInfos.get(name);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#getMultiDataObject(java.lang.String)
+	 */
+	public MultiDataPartitionObject getMultiDataObject(String name)
+			throws RemoteException {
+		return new MultiDataPartitionObject(multiDataInfos.get(name), this);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#getPartition(int,
+	 *      java.awt.Rectangle)
+	 */
+	public synchronized DataPartition getPartition(int id, Rectangle bounds)
+			throws RemoteException {
+		DataPartition thisPartition = (DataPartition) data.get(id);
+		if (thisPartition == null && LOG.isDebugEnabled()) {
+			LOG.error("Partition with id " + id + " and bounds " + bounds
+					+ "was requested but not found on DataManager");
+			return null;
+		}
+
+		if (LOG.isDebugEnabled())
+			LOG.debug("Data retrieved from DataManager: ID:" + id
+					+ " partition: " + bounds);
+		return thisPartition.getPartition(bounds);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#getPartitionInfo(int)
+	 */
+	public SinglePartitionInfo getPartitionInfo(int rootID)
+			throws RemoteException {
+		return infos.get(rootID);
+	}
+
+	/**
+	 * other dataservers may not be initialized on creation of this object.
+	 * Therefore the dataServers must be looked up later
+	 */
+	private void initializeDataServers() {
+		if (dataServersInitialized == true)
+			return;
+		for (int i = 0; i < dataServers.length; i++) {
+			dataServers[i] = getConnection(IPs[i]);
+		}
+		dataServersInitialized = true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.client.DataServer#removeData(int)
+	 */
+	public void removeData(int id) {
+		data.remove(id);
+
+	}
+
+	/**
+	 * Removes the partition from the database
+	 *
+	 * @param name
+	 *            the name of the partition to remove
+	 */
+	public void removeData(String name) {
+		data.remove(NameToIDMapping.get(name));
+	}
+
+	/**
+	 * Removes the partition from the database
+	 *
+	 * @param partition
+	 *            the Partition to remove
+	 */
+	public void removePartition(DataPartition partition) {
+		data.remove(partition.getRootID());
+	}
+
+	/**
+	 * binds the server to the registry
+	 */
+	private void startTheServer() throws RemoteException {
+		Registry registry = LocateRegistry.getRegistry(registryPort);
+		registry.rebind(bindingName, (PartitionDataServer) this);
+		LOG.info("PartitionDataServer bound to port " + registryPort
+				+ " and running....");
+	}
+
+	/**
+	 * unbinds the server from the registry, removes all data and runs the
+	 * garbage collector
+	 */
+	public void stop() {
+		data.clear();
+		NameToIDMapping.clear();
+		infos.clear();
+
+		Registry registry;
+		try {
+			registry = LocateRegistry.getRegistry();
+			registry.unbind(bindingName);
+			LOG.debug("Sucessfully removed " + bindingName + " from reggie");
+		} catch (RemoteException e) {
+			LOG.warn("tried to unbind " + bindingName
+					+ " from reggie, but an exception occured: "
+					+ e.getMessage());
+		} catch (NotBoundException e) {
+			LOG.warn("tried to unbind " + bindingName
+					+ " from reggie, but the name was not bound "
+					+ e.getMessage());
+		}
+		System.gc();
+	}
+
+	/**
+	 * @param rootID
+	 */
+	public void unloadToSource(int rootID) throws RemoteException {
+		SinglePartitionInfo info = infos.get(rootID);
+		if (info == null) {
+			LOG.error("Could not unload partition with id " + rootID
+					+ ". The partitioninfo was not found!");
+			return;
+		}
+		// start unloading
+		info.getPartitionDataHandler().setBasePartition(this.getData(rootID));
+		info.getPartitionDataHandler().unload();
+		// // remove data from memory and run garbage collection
+		// data.remove(rootID);
+		// System.gc();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#updateBaseParameter(java.lang.Object[],
+	 *      java.lang.String[])
+	 */
+	public void updateBaseParameter(HashMap<String, Object> newParameters)
+			throws RemoteException {
+		// update the mapping. Old values are replaced automaticly
+		baseParameters.putAll(newParameters);
+	}
+
+	/**
+	 * Updates the specified partition. For this the the neighborhood partitions
+	 * are updated from remote DataServers using the {@link SplitMap} of the
+	 * {@link SinglePartitionInfo}.
+	 *
+	 * @param id
+	 */
+	public void updateFromNeighbors(int id) {
+		initializeDataServers();
+		// get the data to be updated:
+		DataPartition thisPartition = data.get(id);
+		PartitionInfo info = infos.get(id);
+		if (thisPartition == null || info == null) {
+			LOG.error("Update with id " + id
+					+ " failed, because no data was found with this id");
+			return;
+		}
+
+		// get some other needed infos
+		SplitMap map = info.getSplitMap();
+		int mapPosition = info.getSplitMapPos();
+		// check if something to do
+		if (map.getNeighborhoodRange() == 0) {
+			LOG.debug("Update has nothing to do (neighborhoodrange is 0)");
+			return;
+		}
+
+		// calculate (for each neighbor) the needed partitions and get
+		// the updates (implemented using Threads)
+		int[] neighbors = map.getNeighborsForPosition(mapPosition);
+		Future futures[] = new Future[neighbors.length];
+		for (int j = 0; j < neighbors.length; j++) {
+			int neighborIdx = neighbors[j];
+			// get the overlap of the neighborhood area of the current partion
+			// with the calcultation area of the remote partition
+			Rectangle updateBounds = map.getPartitionNeighborhoodBounds(
+					mapPosition).intersection(
+					map.getPartitionCalculationBounds(neighborIdx));
+			// Get the partition from remote server:
+			DataPartition updateData;
+			futures[j] = executor.submit(new UpdateThread(
+					dataServers[neighborIdx], hostnames[neighborIdx],
+					thisPartition, updateBounds, id, remoteEventReceiver));
+		}
+
+		for (Future future : futures) {
+			try {
+				future.get();
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			} catch (ExecutionException e) {
+				LOG.error("The Remote update of a partition failed", e);
+			}
+		}
+
+	}
+
+	/**
+	 * Does the same as {@link #updateFromNeighbors(int)}
+	 *
+	 * @param name
+	 *            the name of the resource
+	 */
+	public void updateFromNeighbors(String name) {
+		// get by ID
+		updateFromNeighbors(NameToIDMapping.get(name));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.PartitionDataServer#setPartition(int,
+	 *      appl.parallel.spmd.split.DataPartition, java.awt.Rectangle)
+	 */
+	public synchronized void updatePartition(int id, DataPartition partition,
+			Rectangle bounds) throws RemoteException {
+		DataPartition thisPartition = (DataPartition) data.get(id);
+		if (thisPartition == null && LOG.isDebugEnabled()) {
+			LOG
+					.error("Partition of data with id " + id + " and bounds "
+							+ bounds
+							+ "should be set but was not found in DataManager");
+			return;
+		}
+		thisPartition.setPartition(partition, bounds);
+		if (LOG.isDebugEnabled())
+			LOG.debug("Partition of data set on DataManager with id " + id
+					+ " and partition bounds: " + bounds);
+
+	}
+
+}

Added: trunk/src/appl/parallel/server/PartitionDataServer.java
===================================================================
--- trunk/src/appl/parallel/server/PartitionDataServer.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/server/PartitionDataServer.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,123 @@
+package appl.parallel.server;
+
+import java.awt.Rectangle;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.Vector;
+
+import appl.parallel.client.DataServer;
+import appl.parallel.spmd.MultiDataInfo;
+import appl.parallel.spmd.MultiDataObject;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.PartitionInfo;
+import appl.parallel.spmd.split.SinglePartitionInfo;
+import appl.parallel.spmd.split.SplittableResource;
+
+/**
+ * Manages data and partitions on servers. The method descriptions for details.
+ * 
+ * @see PartitionDataManager
+ *
+ * @author Dominik Appl
+ */
+public interface PartitionDataServer extends Remote, DataServer {
+
+	/**
+	 * gets the data with the id of a SplittableRessource
+	 *
+	 * @param id
+	 *            the {@link SplittableResource#getRootID() ID} of a the base data
+	 * @param bounds
+	 *            the bounds of the partition to retrieve (using global
+	 *            coordinates)
+	 * @return the partition
+	 * @throws RemoteException
+	 */
+	public DataPartition getPartition(int id, Rectangle bounds)
+			throws RemoteException;
+
+	/**
+	 * sets the data with the id of a SplittableRessource
+	 *
+	 * @param id
+	 *            the {@link SplittableResource#getRootID() ID} of a the base data
+	 * @param bounds
+	 *            the locatition where the partition is to be updated (using
+	 *            global coordinates)
+	 * @param updateData
+	 *            the updateData (which may only a partitial update, depending
+	 *            on the bounds set with the last parameter)
+	 * @throws RemoteException
+	 */
+	public void updatePartition(int id, DataPartition updateData,
+			Rectangle bounds) throws RemoteException;
+
+	/**
+	 * Unloads the specified resource to the source it was loaded from
+	 *
+	 * @param rootID
+	 *            the id of the resource
+	 */
+	public void unloadToSource(int rootID) throws RemoteException;
+
+	/**
+	 * requests an update for the neighborhood region for the given resource
+	 *
+	 * @param rootID
+	 */
+	public void updateFromNeighbors(int rootID) throws RemoteException;
+
+	/**
+	 * Adds or updates BaseParameters
+	 */
+	public void updateBaseParameter(HashMap<String, Object> newParameters)
+			throws RemoteException;
+
+	/**
+	 * Adds {@link PartitionInfo}s to the server. They are submitted in a
+	 * vector to avoid multiple remote calls.
+	 *
+	 * @param singlePartitionInfos
+	 * @throws RemoteException
+	 */
+	public void addPartitionInfos(
+			Vector<SinglePartitionInfo> singlePartitionInfos)
+			throws RemoteException;
+
+	/**
+	 * Adds {@link MultiDataInfo}s to the server.
+	 *
+	 * @param toTransferMultiDataObjects
+	 */
+	public void addMultiDataInfos(
+			HashMap<String, MultiDataInfo> toTransferMultiDataObjects)
+			throws RemoteException;
+
+	/**
+	 * @param name
+	 *            the name of the associated multi data
+	 * @return the {@link MultiDataInfo} info
+	 * @throws RemoteException
+	 */
+	public MultiDataInfo getMultiDataInfo(String name) throws RemoteException;
+
+	/**
+	 * @param name
+	 *            the name of the multiDataObject
+	 * @return the MultiDataObject associated with that name
+	 * @throws RemoteException
+	 */
+	public MultiDataObject getMultiDataObject(String name)
+			throws RemoteException;
+
+	/**
+	 * @param rootID
+	 *            the id of the according partition
+	 * @return the the {@link PartitionInfo}
+	 * @throws RemoteException
+	 */
+	public SinglePartitionInfo getPartitionInfo(int rootID)
+			throws RemoteException;
+
+}

Added: trunk/src/appl/parallel/server/SPMDResource.java
===================================================================
--- trunk/src/appl/parallel/server/SPMDResource.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/server/SPMDResource.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,51 @@
+package appl.parallel.server;
+
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.Vector;
+
+import appl.parallel.ComputingResource;
+import appl.parallel.spmd.SPMDClientController;
+import appl.parallel.spmd.SPMDTask;
+import appl.parallel.spmd.split.SinglePartitionInfo;
+import appl.parallel.spmd.split.SplitMap;
+
+/**
+ * The resources participating in a SPMD computation need to implement this
+ * interface.
+ * 
+ * @author Dominik Appl
+ */
+public interface SPMDResource extends ComputingResource {
+
+	/**
+	 * Executes the given Task.
+	 * 
+	 * @param SPMDTaskName
+	 *            name of the taskclass to be executed
+	 * @param referenceID
+	 *            the ID of the Grid which should be the reference resource
+	 * @param parameters
+	 *            parameters for the given Task
+	 * @return an object array containing the results for possibly multiple
+	 *         executions (when using multithreading with multi-core cpus)
+	 * @throws RemoteException
+	 *             if the connection fails
+	 * @see SPMDClientController#setReferenceResource(Object)
+	 */
+
+	public Object[] runSPMDModelTask(String SPMDTaskName, int referenceID,
+			Object... parameters) throws RemoteException;
+
+	/**
+	 * @param IPs
+	 *            the IP addresses of all other participating servers. They MUST
+	 *            have the same index as their according partition in the
+	 *            {@link SplitMap} has.
+	 * @return creates a new {@link PartitionDataServer} on this resource and
+	 *         returns it
+	 */
+	public PartitionDataServer createDataServer(String[] IPs)
+			throws RemoteException;
+
+}

Added: trunk/src/appl/parallel/server/ServerMulticastReceiver.java
===================================================================
--- trunk/src/appl/parallel/server/ServerMulticastReceiver.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/server/ServerMulticastReceiver.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,99 @@
+package appl.parallel.server;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.SocketException;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.ext.XuluConfig;
+import appl.parallel.services.MulticastDiscoveryService;
+
+/**
+ * Waits for multicast messages from clients and responds properly.
+ * 
+ * @see MulticastDiscoveryService
+ * @author Dominik Appl
+ */
+public class ServerMulticastReceiver extends Thread {
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	private static final String helloFromXuluMessage = "Hello Servers";
+
+	private static final String helloFromServerMessage = "Hello Xulu from XuluServer";
+
+	boolean exit = false;
+
+	MulticastSocket socket;
+
+	int multicastPort = XuluConfig.getXuluConfig().getIntProperty(
+			"XuluServer.multicastport");
+
+	/**
+	 * @param socket
+	 *            Socket which is used for listening. Set a timeout for the
+	 *            socket via {@link MulticastSocket#setSoTimeout(int)} so that
+	 *            the thread can be stopped (because of the blocked reading)
+	 */
+	public ServerMulticastReceiver(MulticastSocket socket) {
+		this.socket = socket;
+		// try {
+		// socket.setSoTimeout(5000);
+		// } catch (SocketException e) {
+		// //do not printout the timeout
+		// }
+	}
+
+	/**
+	 * Safe method to stop the Thread. Use this method instead of {@link Thread}
+	 */
+	public void stopThread() {
+		exit = true;
+	}
+
+	public void run() {
+		System.out.println("Listening on port " + socket.getLocalPort()
+				+ " for Xulu hello messages!");
+		while (!exit) {
+			try {
+				// receive buffer
+				byte[] buffer = new byte[256];
+				DatagramPacket datagram = new DatagramPacket(buffer,
+						buffer.length);
+				socket.receive(datagram);
+
+				// get right message format (cut out null bytes)
+				byte[] result = new byte[datagram.getLength()];
+				System.arraycopy(datagram.getData(), 0, result, 0, datagram
+						.getLength());
+
+				// check message:
+				if (new String(result).equals(helloFromXuluMessage)) {
+					// LOG.info("received hello from Client " +
+					// datagram.getAddress());
+					LOG.info("received hello from Client "
+							+ datagram.getAddress());
+
+					// get the IP again and send the answer
+					String IP = XuluConfig.getXuluConfig().getProperty(
+							"XuluServer.multicastgroup");
+					DatagramPacket answer = new DatagramPacket(
+							helloFromServerMessage.getBytes(),
+							helloFromServerMessage.length(), InetAddress
+									.getByName(IP), multicastPort);
+					socket.send(answer);
+				}
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (Exception e) {
+				if (!(e instanceof InterruptedException))
+					e.printStackTrace();
+			}
+		}
+	}
+}

Added: trunk/src/appl/parallel/server/XuluServer.java
===================================================================
--- trunk/src/appl/parallel/server/XuluServer.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/server/XuluServer.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,1034 @@
+package appl.parallel.server;
+
+import java.awt.Rectangle;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.MulticastSocket;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.rmi.MarshalledObject;
+import java.rmi.Naming;
+import java.rmi.NotBoundException;
+import java.rmi.RMISecurityManager;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.activation.Activatable;
+import java.rmi.activation.ActivationID;
+import java.rmi.server.ServerNotActiveException;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.HashMap;
+import java.util.Vector;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import net.jini.loader.pref.PreferredClassLoader;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+import org.apache.log4j.net.SocketAppender;
+
+import appl.ext.XuluConfig;
+import appl.parallel.ComputingResourceProperties;
+import appl.parallel.client.DataServer;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.event.TimeEvent;
+import appl.parallel.event.CommEvent.CommType;
+import appl.parallel.services.RemoteEventProxy;
+import appl.parallel.spmd.AdvancedSPMDServerController;
+import appl.parallel.spmd.AdvancedSPMDServerInterface;
+import appl.parallel.spmd.SPMDServerController;
+import appl.parallel.spmd.SPMDServerInterface;
+import appl.parallel.spmd.SPMDTask;
+import appl.parallel.spmd.split.SinglePartitionInfo;
+import appl.parallel.spmd.split.SplitMap;
+import appl.parallel.spmd.split.SplitMap1DVertical;
+import appl.parallel.spmd.split.AbstractSplitMap.NeighborhoodBoxingMode;
+import appl.parallel.thread.OneMethodThread;
+import appl.parallel.util.Helper;
+import appl.util.benchmark.Benchmark;
+
+/**
+ * The Server manages the remote execution of program code. It may be started
+ * using the {@link #main(String[])} method.<br>
+ * The Server reads the following properties from {@link XuluConfig} - the
+ * values given should be the defaults.<br>
+ * <table border="1">
+ * <tr>
+ * <th>Property</th>
+ * <th>Default</th>
+ * <th>Desc</th>
+ * </tr>
+ * <tr>
+ * <td>XuluServer.useCodeDownloading</td>
+ * <td>false</td>
+ * <td>if true, the server tries to download task class files from a
+ * HTTP-server at the client-url</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServer.registryPort</td>
+ * <td>1099</td>
+ * <td>The port at which a new registry is created, if no running registry was
+ * found</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServer.multicastgroup</td>
+ * <td>239.1.1.1</td>
+ * <td>The default multicast group</td>
+ * </tr>
+ * <tr>
+ * <td> XuluServer.multicastport</td>
+ * <td>10000</td>
+ * <td>The default multicast port</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServer.eventDelay</td>
+ * <td>50</td>
+ * <td>Events generated on server side may be delayed to collect multiple
+ * Events and send them at once (this saves communication time).Time is given in
+ * milliseconds</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServer.log4j.logLevel</td>
+ * <td>info</td>
+ * <td>the level can be '<i>debug</i>','<i>info</i>','<i>warn</i>','<i>error</i>'
+ * or '<i>fatal</i>' and can be overridden by commandline - Parameters<br>
+ * <br>
+ * </td>
+ * </tr>
+ * <td>XuluServer.log4j.mode</td>
+ * <td>console</td>
+ * <td>the mode can be '<i>file</i>','<i>chainsaw</i>' or '<i>console</i>'.
+ * File means that the configurationfile xuluserverlog4j.cfg is read. <br>
+ * <i>'chainsaw'</i> means that the server tries to configure the logger each
+ * time a new client for a chainsaw instance running at the client ip
+ * (standardports) <br>
+ * </td>
+ * </tr>
+ * <td>XuluServer.benchmarkclass</td>
+ * <td>appl.util.benchmark.SimpleBenchmark</td>
+ * <td>The Benchmark to get a rating for this machine. Notice that you can
+ * override the rating with the -rating parameter</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServer.useThreads</td>
+ * <td>max</td>
+ * <td>The number of threads to be used by the server for tasks that support
+ * multi-threading. Per default one thread is created for every available
+ * Processors (value='max'). More threads than processors may be useful for
+ * testing tasks which support multihreading or for processors which support
+ * hyperthreading.</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServer.runbench</td>
+ * <td>true</td>
+ * <td>the benchmark is run automatically</td>
+ * </tr>
+ * </table> <br>
+ * <b>Multicasting:</b> <br>
+ * If multicasting does not work, try to disable your firewall or configure it
+ * to allow multicast UDP packages. Notice also, that multicasting may not work
+ * in virtual machines like VMWare or MS Virtual PC 2004/7. <br>
+ * <br>
+ * <b>Assumptions</b> 
+ * Only one client is connected to the server (and can run Tasks) <br>
+  *<br>
+  * See {@link #main(String[])} for details about command line parameters
+ * @see ServerMulticastReceiver
+ * @author Dominik Appl
+ */
+public class XuluServer extends UnicastRemoteObject implements SPMDResource {
+
+	/**
+	 * This Thread is used when multiple threads should be executed simultaneous during multithreading
+	 *
+	 * @author Dominik Appl
+	 */
+	class SimpleCallThread implements Callable {
+
+		private final SPMDTask task;
+
+		private final Object[] parameters;
+
+		/**
+		 * @param task the task to be executed
+		 * @param parameters the parameters for the run method of the task
+		 */
+		public SimpleCallThread(SPMDTask task, Object... parameters) {
+			this.task = task;
+			this.parameters = parameters;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see java.util.concurrent.Callable#call()
+		 */
+		public Object call() throws Exception {
+			return task.run(parameters);
+		}
+	}
+
+	private static final Logger LOG = LogManager
+			.getLogger("appl.parallel.server.XuluServer");
+
+	private static String bindingName = "XuluServer";
+
+	private static final String helloFromServerMessage = "Hello Xulu from XuluServer";
+
+	private static String log4jfilename = "xuluserverlog4j.cfg";
+
+	private static boolean chainsaw = false;
+
+	private static SocketAppender chainsawAppender;
+
+	/**
+	 * @param mode the mode of the execution
+	 */
+	private static void log4jConfig(String mode) {
+		if (mode.equals("chainsaw")) {
+			BasicConfigurator.resetConfiguration();
+			chainsawAppender = new SocketAppender();
+			BasicConfigurator.configure(chainsawAppender);
+			System.out.println("Server configured for chainsaw.");
+			chainsaw = true;
+		} else if (mode.equals("file")) {
+			BasicConfigurator.resetConfiguration();
+			PropertyConfigurator.configure(log4jfilename);
+		} else if (mode.equals("console")) {
+			BasicConfigurator.resetConfiguration();
+			BasicConfigurator.configure();
+		} else {
+			System.err.println("Invalid log4j-Config parameter found: " + mode);
+			printInfoMessage();
+			System.exit(0);
+		}
+	}
+
+	/**
+	 * configures the log4j level
+	 *
+	 * @see #main(String[])
+	 */
+	private static void log4jLevel(String level) {
+		if (level.equals("info")) {
+			LOG.setLevel(Level.INFO);
+		} else if (level.equals("debug")) {
+			LOG.setLevel(Level.DEBUG);
+		} else if (level.equals("error")) {
+			LOG.setLevel(Level.ERROR);
+		} else if (level.equals("fatal")) {
+			LOG.setLevel(Level.FATAL);
+		} else if (level.equals("warn")) {
+			LOG.setLevel(Level.WARN);
+		} else if (level.equals("off")) {
+			LOG.setLevel(Level.OFF);
+		} else {
+			System.err.println("Invalid log4j-Level found: " + level);
+			printInfoMessage();
+			System.exit(0);
+		}
+		System.out.println("Setting logLevel to " + level);
+	}
+
+	/**
+	 * Starts the server.
+	 *
+	 * @param args
+	 * The following parameters are valid: <br>
+	 * <br>
+	 * -loglevel:<code>LEVEL</code> - where <code>LEVEL</code> is '<i>debug</i>','<i>info</i>'
+	 * (DEFAULT),'<i>warn</i>','<i>error</i>' or '<i>fatal</i>' <br>
+	 * <br>
+	 * -logconfig:<code>CONFIG</code> - where <code>CONFIG</code> is '<i>file</i>','<i>chainsaw</i>' or '<i>console</i>'
+	 * <li>'chainsaw' means that the server tries to configure the logger each time a
+	 * new client for a chainsaw instance running at the client ip
+	 * (standardports) </li><br>
+	 * <li>'<i>file</i>' means that the file '<i>xuluserverlog4j.cfg</i>'
+	 * in the home-directory is used for configuration <br> </li>
+	 * <li>'<i>console</i>'
+	 * means of course, that the console is used for output <br> </li>
+	 * <br>
+	 * -port:PORTNUMBER - binds the server to the specified port (default 1099)
+	 *
+
+	 */
+	public static void main(String[] args) {
+		// parse arguments
+		int serverPort = 0;
+		for (String arg : args) {
+			if (arg.toLowerCase().startsWith("-loglevel:"))
+				log4jLevel(arg.substring(10).toLowerCase());
+			else if (arg.toLowerCase().startsWith("-logconfig:"))
+				log4jConfig(arg.substring(11).toLowerCase());
+			else if (arg.toLowerCase().startsWith("-port:"))
+				serverPort = Integer.valueOf(arg.substring(6));
+			else {
+				System.err.println("Invalid Argument found: " + arg);
+				printInfoMessage();
+				System.exit(0);
+			}
+		}
+
+		if (System.getSecurityManager() == null) {
+			System.setSecurityManager(new RMISecurityManager());
+		}
+		Remote server;
+		try {
+			server = new XuluServer(serverPort);
+			System.out.println("Xulu Server is up and running!");
+		} catch (RemoteException e) {
+			System.err.println("Xulu Server could not start!");
+			e.printStackTrace();
+		}
+	}
+
+	private static void printInfoMessage() {
+		System.out
+				.println("The following arguments are valid: \n"
+						+ "-loglevel:<LEVEL> \n"
+						+ "   where <LEVEL> is 'off','debug','info' (DEFAULT),'warn','error' or 'fatal'\n\n"
+						+ "-logconfig:<CONFIG> \n"
+						+ "   where <CONFIG> is 'file','chainsaw' or 'console'(DEFAULT) \n"
+						+ "   'chainsaw' means that the server tries to configure the logger each\n"
+						+ "   time a new client for a chainsaw instance running at the client ip\n"
+						+ "   (standardports) \n"
+						+ "   'file' means that the file 'xuluserverlog4j.cfg' in the home-directory "
+						+ "         is used for configuration \n"
+						+ "   'console' means of course, that the console is used for output"
+						+ "-port:<portnumber> \n"
+						+ "   The Server is bound to the specified port");
+	}
+
+	private static void unbind() {
+		Helper.unbind(bindingName);
+	}
+
+	/**
+	 * The {@link Class} objects of the currently active connection. Every time
+	 * {@link #runSPMDModelTask(String, int, Object[])} is called the
+	 * newest class is loaded from the client. For performance reasons this will
+	 * happen only one time per connection. In this map the current active
+	 * classes are stored.
+	 */
+	private HashMap<String, SPMDTask[]> spmdTaskInstances;
+
+	/* standard is should be 1099 */
+	private int registryPort = 1099;
+
+	private int multicastPort;
+
+	private String multiCastIP;
+
+	ServerMulticastReceiver multicastThread;
+
+	InetAddress multiCastGroup;
+
+	// says whether a client is connected
+	private boolean connected = false;
+
+	private long starttime = System.currentTimeMillis();
+
+	private String connectedClient;
+
+	private PartitionDataManager dataManager;
+
+	private RemoteEventProxy remoteEventReceiver;
+
+	// User specified name of the Server or hostname
+	private String serverName;
+
+	private int machineRating = 0;
+
+	private final boolean loggingEnabled;
+
+	private int taskPriority = Thread.NORM_PRIORITY;
+
+	private int availableProcessors = 1;
+
+	private int toUseThreads = 1;
+
+	private final boolean isInternalServer;
+
+	private ClientDataServer localSPMDClient;
+
+	private boolean useCodeDownloading;
+
+	private ExecutorService executor;
+
+	// used for execution results
+	private Future[] resultCalls;
+
+	/**
+	 * Creates a new instance at the standard port
+	 *
+	 * @throws RemoteException
+	 */
+	public XuluServer() throws RemoteException {
+		this(true, false, 0);
+	}
+
+	/**
+	 * @param configLogging
+	 *            enable or disable logging
+	 * @param isInternalServer
+	 *            set to true if you want to make method calls purely local.
+	 *            This is for performance reasons (see
+	 *            {@link UnicastRemoteObject#getClientHost()}
+	 * @param port
+	 *            port the server is bound to (0 for default)
+	 * @throws RemoteException
+	 */
+	public XuluServer(boolean configLogging, boolean isInternalServer, int port)
+			throws RemoteException {
+		super();
+		loggingEnabled = configLogging;
+		this.isInternalServer = isInternalServer;
+		initConfiguration();
+		//the executor is used for multithreading
+		executor = Executors.newCachedThreadPool();
+		spmdTaskInstances = new HashMap<String, SPMDTask[]>(10);
+		if (port != 0)
+			this.registryPort = port;
+		bind();
+
+		initializeMultiCasting();
+		serverName = "unknown server";
+		try {
+			if (isInternalServer)
+				serverName = "internal Server";
+			else
+				serverName = InetAddress.getLocalHost().getHostName();
+		} catch (UnknownHostException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		if (port != 0)
+			serverName = serverName + " (port " + registryPort + ")";
+		runBenchmark();
+	}
+
+	/**
+	 * <br>
+	 * This is used when a Server is running inside the Xulu-Client. It has
+	 * performance advantages (direct access - no TCP/IP)
+	 *
+	 * @param configLogging
+	 *            enable or disable logging
+	 * @param clientDataServer a local client for faster access
+	 * @throws RemoteException
+	 */
+	public XuluServer(boolean configLogging, ClientDataServer clientDataServer)
+			throws RemoteException {
+		this(configLogging, true, 0);
+		this.localSPMDClient = clientDataServer;
+	}
+
+	/**
+	 * @param port
+	 *            the port to which the Server is bound
+	 * @throws RemoteException
+	 */
+	public XuluServer(int port) throws RemoteException {
+		this(true, false, port);
+	}
+
+	/**
+	 * Bind the remote object's stub in the registry. Creates a registry if no
+	 * running registry is found.
+	 */
+	private void bind() throws RemoteException {
+		String name = bindingName;
+		Helper.bind(name, this, registryPort);
+	}
+
+	private boolean checkConnected(String callingHost) {
+
+		if (callingHost.equals(connectedClient))
+			return true;
+		LOG
+				.warn(callingHost
+						+ " has tried to execute a critical operation, but was not connected "
+						+ ". Actual connected client: " + connectedClient);
+		return false;
+	}
+
+	/**
+	 * Only a connected client has access to all functionality. When connecting
+	 * or reconnecting, all data of the server and the corresponding
+	 * {@link PartitionDataServer} is reset!
+	 *
+	 * @see appl.parallel.ComputingResource#connect()
+	 */
+	public synchronized boolean connect() throws RemoteException {
+		/**
+		 * determine the calling host. Internal Server requires special
+		 * handling: notice that this happens very often in this class, but can
+		 * not externalized due to the behavior of #getClientHost();
+		 */
+		String callingHost = "error";
+		try {
+			callingHost = isInternalServer ? "localhost" : getClientHost();
+		} catch (ServerNotActiveException e) {
+			e.printStackTrace();
+		}
+		/** ********************************************************************** */
+
+		if (connectedClient == null || callingHost.equals(connectedClient)) {
+			if (connectedClient == null)
+				LOG.info("Client " + callingHost + " connected!");
+			else
+				LOG.info("Client " + connectedClient + " reconnected! ");
+			// reset data
+			reset();
+			connectedClient = callingHost;
+			// initalize event system & chainsaw
+			initEventSystem();
+			initChainsaw(connectedClient);
+			return true;
+		} else if (connectedClient != null) {
+			LOG.warn(callingHost + " has tried to "
+					+ "connect to server, but was not connected, "
+					+ "because this server is in use by " + connectedClient);
+		}
+
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.ComputingResource#createDataServer()
+	 */
+	public PartitionDataServer createDataServer(String[] IPs)
+			throws RemoteException {
+		/**
+		 * determine the calling host. Internal Server requires special
+		 * handling: notice that this happens very often in this class, but can
+		 * not externalized due to the behavior of #getClientHost();
+		 */
+		String callingHost = "localhost";
+		try {
+			callingHost = isInternalServer ? "localhost" : getClientHost();
+		} catch (ServerNotActiveException e) {
+			e.printStackTrace();
+		}
+		/** ********************************************************************** */
+		if (checkConnected(callingHost)) {
+			if (isInternalServer)
+				dataManager = new PartitionDataManager(IPs,
+						remoteEventReceiver, getRegistryPort(), localSPMDClient);
+			else
+				dataManager = new PartitionDataManager(IPs,
+						remoteEventReceiver, getRegistryPort());
+			return dataManager;
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.server.ComputingResource#disconnect()
+	 */
+	public synchronized void disconnect() throws RemoteException {
+		/**
+		 * determine the calling host. Internal Server requires special
+		 * handling: notice that this happens very often in this class, but can
+		 * not externalized due to the behavior of #getClientHost();
+		 */
+		String callingHost = "localhost";
+		try {
+			callingHost = isInternalServer ? "localhost" : getClientHost();
+		} catch (ServerNotActiveException e) {
+			e.printStackTrace();
+		}
+		/** ********************************************************************** */
+		if (checkConnected(callingHost)) {
+			reset();
+			LOG.info("Client " + connectedClient
+					+ " successfully disconnected from Server");
+		}
+	}
+
+	/**
+	 * @return a rating for the machine as discovered by the benchmark
+	 */
+	public int getRating() {
+		return machineRating;
+	}
+
+	/**
+	 * @return the registry port the server is bound to
+	 */
+	public int getRegistryPort() {
+		return registryPort;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.XuluServer#getResourceInformation()
+	 */
+	public ComputingResourceProperties getResourceInformation()
+			throws RemoteException {
+		return new XuluServerProperties(this, serverName);
+	}
+
+	/**
+	 * @return the time in s the server is running
+	 */
+	int getUptime() {
+		return (int) (System.currentTimeMillis() - starttime);
+	}
+
+	private void initChainsaw(String connectedClient) {
+		if (chainsaw && connectedClient != null) {
+			chainsawAppender = new SocketAppender(connectedClient, 4445);
+			BasicConfigurator.resetConfiguration();
+			BasicConfigurator.configure(chainsawAppender);
+		}
+	}
+
+	/**
+	 * inits task priority, ports and loglevel
+	 */
+	private void initConfiguration() {
+		XuluConfig config = XuluConfig.getXuluConfig();
+		// a lower priority will run the server more in the background
+		taskPriority = config.getIntProperty("XuluServer.priority");
+
+		switch (taskPriority) {
+		default:
+			taskPriority = Thread.NORM_PRIORITY;
+			break;
+		case 1:
+			taskPriority = Thread.MIN_PRIORITY;
+			break;
+		case 2:
+			taskPriority = Thread.NORM_PRIORITY - 1;
+			break;
+		case 4:
+			taskPriority = Thread.NORM_PRIORITY + 1;
+			break;
+		case 5:
+			taskPriority = Thread.MAX_PRIORITY;
+			break;
+		}
+
+		availableProcessors = Runtime.getRuntime().availableProcessors();
+		// default: try to use one thread per processor
+		toUseThreads = availableProcessors;
+		// check if there is an entry in the XuluConfig saying how many threads
+		// should be created.
+		// (more threads than processors may be useful for the use of
+		// hyperthreading)
+		String configProz = config.getProperty("XuluServer.useThreads");
+		if ((configProz != null) && !configProz.equals("max")) {
+			toUseThreads = config.getIntProperty("XuluServer.useThreads");
+			// error checking:
+			if (toUseThreads < 1 || toUseThreads > 128){
+				toUseThreads = availableProcessors;
+			System.out
+					.println("Error: Number of threads must be between 1 and 128!");
+			}
+		}
+		// init correspondig arrays
+		resultCalls = new Future[toUseThreads];
+
+		int port = config.getIntProperty("XuluServer.registryport");
+		if (port != 0)
+			registryPort = port;
+
+		useCodeDownloading = config
+				.getBooleanProperty("XuluServer.useCodeDownloading");
+		if (useCodeDownloading)
+			System.out.println("Code downloading is enabled");
+		else
+			System.out.println("Code downloading is disabled");
+
+		int multicastport = config.getIntProperty("XuluServer.multicastport");
+		if (multicastport != 0)
+			multicastPort = multicastport;
+		String IP = config.getProperty("XuluServer.multicastgroup");
+		if (IP != null)
+			multiCastIP = IP;
+		try {
+			multiCastGroup = InetAddress.getByName(multiCastIP);
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		}
+		if (loggingEnabled) {
+
+			String mode = config.getProperty("XuluServer.log4j.mode");
+			if (mode != null)
+				log4jConfig(mode);
+		}
+		String level = config.getProperty("XuluServer.log4j.logLevel");
+		if (level != null)
+			log4jLevel(level.toLowerCase());
+		else
+			log4jLevel("info");
+	}
+
+	/**
+	 * Connects to the RemoteEventReceiver at the calling client
+	 */
+	private void initEventSystem() throws RemoteException {
+		String lookupName = "rmi://" + connectedClient + "/RemoteEventReceiver";
+		try {
+			int delay = XuluConfig.getXuluConfig().getIntProperty(
+					"XuluServer.eventDelay");
+			System.out.println("looking up " + lookupName);
+			CommEventSink eventSink = (CommEventSink) Naming.lookup(lookupName);
+			if (remoteEventReceiver != null)
+				remoteEventReceiver.stopService();
+			remoteEventReceiver = new RemoteEventProxy(eventSink, delay);
+			remoteEventReceiver.startService();
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		} catch (NotBoundException e) {
+			LOG.warn("Could not find the remote event receiver at "
+					+ lookupName, e);
+			System.out.println(e.getMessage());
+			remoteEventReceiver = new RemoteEventProxy(null, 0);
+		}
+	}
+
+	/**
+	 * inits the multicast unit
+	 */
+	private void initializeMultiCasting() {
+		try {
+			MulticastSocket s = new MulticastSocket(multicastPort);
+			s.joinGroup(multiCastGroup);
+			// send hello message
+			String IP = XuluConfig.getXuluConfig().getProperty(
+					"XuluServer.multicastgroup");
+			DatagramPacket answer = new DatagramPacket(helloFromServerMessage
+					.getBytes(), helloFromServerMessage.length(), InetAddress
+					.getByName(IP), multicastPort);
+			s.send(answer);
+			// start thread that waits on client messages
+			multicastThread = new ServerMulticastReceiver(s);
+			multicastThread.start();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			LOG.warn("Could not initalize multicasting! Reason was "
+					+ e.getMessage(), e);
+
+		}
+	}
+
+	/**
+	 * @return whether this server is available or in use by another client
+	 * @see appl.parallel.ComputingResource#isAvailable()
+	 */
+	public boolean isAvailable() throws RemoteException {
+		/**
+		 * determine the calling host. Internal Server requires special
+		 * handling: notice that this happens very often in this class, but can
+		 * not externalized due to the behavior of #getClientHost();
+		 */
+		String callingHost = "localhost";
+		try {
+			callingHost = isInternalServer ? "localhost" : getClientHost();
+		} catch (ServerNotActiveException e) {
+			e.printStackTrace();
+		}
+		/** ********************************************************************** */
+		if (callingHost.equals(connectedClient))
+			return true;
+
+		if (connectedClient == null)
+			return true;
+		return false;
+	}
+
+	/**
+	 * @return if a client is connected
+	 */
+	public boolean isClientConnected() {
+		return connected;
+
+	}
+
+	/**
+	 * Loads a {@link SPMDTask} from the specified URL and returns an array of
+	 * instances of this class. There are so many instances, as there are
+	 * available processors on this machine!. This class also makes sure that
+	 * this happens only one time per connection (else this would of course be a
+	 * performance killer in fine grained parallelization).
+	 *
+	 * @param location
+	 *            the URL of the rootDirectory/networkLocation
+	 * @param spmdTaskClassName
+	 *            the name of the SPMDTask for which the newest class should be
+	 *            found
+	 * @return the instance of the class or <code>null</code> if loading fails
+	 */
+	private SPMDTask[] loadSPMDTasksfromURL(String location,
+			String spmdTaskClassName) {
+
+		SPMDTask[] spmdClassInstances = (SPMDTask[]) spmdTaskInstances
+				.get(spmdTaskClassName);
+
+		// if already loaded for this connection simply return the instances
+		if (spmdClassInstances != null)
+			return (SPMDTask[]) spmdClassInstances;
+		spmdClassInstances = new SPMDTask[toUseThreads];
+		Class spmdClass = null;
+		if (useCodeDownloading) {
+			try {
+				// lookup client and make sure that the newest class of the task
+				// is instantiated. Will avoid loading older cached or local
+				// filesystem version
+				URL[] locations = { new URL("http://" + location + "/") };
+				PreferredClassLoader classLoader = new PreferredClassLoader(
+						locations, Thread.currentThread()
+								.getContextClassLoader(), null, false);
+				LOG.debug("Try to load " + spmdTaskClassName + " from "
+						+ location);
+				spmdClass = classLoader.loadClass(spmdTaskClassName);
+			} catch (Exception e) {
+				LOG.error("Could not load class for " + spmdTaskClassName
+						+ " from " + location, e);
+				e.printStackTrace();
+			}
+		}
+		// if retrieval failed for some reason or code downloading disabled
+		// then use the local class
+		try {
+			if (spmdClass == null) {
+				spmdClass = Class.forName(spmdTaskClassName);
+			}
+
+			// instantiate the classes
+			for (int i = 0; i < spmdClassInstances.length; i++) {
+				Object task = spmdClass.newInstance();
+				if (!(task instanceof SPMDTask)) {
+					LOG.fatal(spmdTaskClassName
+							+ " was not an instance of SPMDTask!");
+					throw new UnsupportedOperationException(spmdTaskClassName
+							+ " was not an instance of SPMDTask!");
+				}
+				spmdClassInstances[i] = (SPMDTask) task;
+			}
+
+			spmdTaskInstances.put(spmdTaskClassName, spmdClassInstances);
+			return spmdClassInstances;
+
+		} catch (ClassNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (InstantiationException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		throw new UnsupportedOperationException("Loading of class "
+				+ spmdTaskClassName
+				+ " failed on serverside! Execution canceled");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.server.XuluServer#ping(java.lang.Object[])
+	 */
+	public Object ping(Object... o) throws RemoteException {
+		System.out.println("received ping");
+		return o;
+	}
+
+	/**
+	 * deletes all client-specific data data, so that a newly connected client
+	 * can use a clean system
+	 */
+	private void reset() {
+		if (dataManager != null)
+			dataManager.stop();
+		dataManager = null;
+		connectedClient = null;
+		spmdTaskInstances.clear();
+	}
+
+	/**
+	 * runs the benchmark defined in XuluServer.benchmarkclass
+	 */
+	private void runBenchmark() {
+		// see if the benchmark should be run
+
+		boolean runbench = XuluConfig.getXuluConfig().getBooleanProperty(
+				"XuluServer.runbench");
+		if (runbench) {
+			String classname = XuluConfig.getXuluConfig().getProperty(
+					"XuluServer.benchmarkclass");
+			if (classname != null) {
+				try {
+					// getBenchmarkClass
+					Benchmark bench = (Benchmark) Class.forName(classname)
+							.newInstance();
+					machineRating = bench.bench();
+					System.out
+							.println("Successfully run benchmark. Machine Rating is "
+									+ machineRating);
+				} catch (Exception e) {
+					System.err
+							.println("Could not load Benchmarkclass "
+									+ classname
+									+ ". Setting rating to 0 (which means average).  Reason was: "
+									+ e.getMessage());
+					machineRating = 0;
+				}
+			} else
+				System.out.println("Benchmark disabled");
+		}
+	}
+
+	/**
+	 * Every time {@link #runSPMDModelTask(String, int, Object[])} is called the
+	 * newest class is loaded from the client. For performance reasons this will
+	 * happen only one time per connection.
+	 *
+	 * @see appl.parallel.server.SPMDResource#runSPMDModelTask(String, int,
+	 *      Object[])
+	 */
+	@SuppressWarnings("unchecked")
+	public Object[] runSPMDModelTask(String spmdTaskName, int referenceID,
+			Object... parameters) throws RemoteException {
+		/**
+		 * determine the calling host. Internal Server requires special
+		 * handling: notice that this happens very often in this class, but can
+		 * not externalized due to the behavior of #getClientHost();
+		 */
+		String callingHost = "localhost";
+		try {
+			callingHost = isInternalServer ? "localhost" : getClientHost();
+		} catch (ServerNotActiveException e) {
+			e.printStackTrace();
+		}
+		/** ********************************************************************** */
+		Thread.currentThread().setPriority(taskPriority);
+		String clientIP = "<unknown Client>";
+		long time = System.nanoTime();
+
+		clientIP = callingHost;
+		if (!clientIP.equals(connectedClient)) {
+			LOG.warn(clientIP
+					+ " has tried to run a Task, but was not connected. "
+					+ "This server is in use by " + connectedClient);
+			throw new RemoteException(
+					"Run of SPMDTask failed! This server is in use by "
+							+ connectedClient);
+		}
+		if (LOG.isDebugEnabled())
+			LOG.debug("received task from " + clientIP
+					+ ". Starting evaluation now...");
+		// if no datamanager is found: exit
+		if (dataManager == null)
+			throw new UnsupportedOperationException(
+					"No DataManager found. Create one first using 'createDataManager' on this Server");
+
+		// lookup newest version of the class from the server at the url
+		// (or from local disk if remote class loading is disabled)
+		SPMDTask[] tasks = loadSPMDTasksfromURL(clientIP, spmdTaskName);
+
+		// The number of threads allowed for execution can be different
+		// from the number of user assigned threads
+		// because tasks may not support multithreadeding
+		int allowedThreads = 1;
+		if (tasks[0].supportsMultiThreading())
+			allowedThreads = toUseThreads;
+
+		Object results[] = new Object[allowedThreads];
+
+		// the following loop is only executed the first time a task is used!
+		if (!tasks[0].isInitialized()) {
+			if (LOG.isInfoEnabled())
+				LOG.info("Trying to use " + allowedThreads
+						+ " threads for execution of "
+						+ tasks[0].getClass().getName());
+			// calculate splitting for multiple threads:
+			int splitMapPos = dataManager.getInfo(referenceID).getSplitMapPos();
+			SplitMap splitMap = dataManager.getInfo(referenceID).getSplitMap();
+			SplitMap1DVertical map1DVertical = new SplitMap1DVertical(splitMap
+					.getPartitionCalculationBounds(splitMapPos).width, splitMap
+					.getPartitionCalculationBounds(splitMapPos).height, 0,
+					allowedThreads, NeighborhoodBoxingMode.outBoxing);
+
+			// create controllers and init the tasks
+			for (int i = 0; i < allowedThreads; i++) {
+				AdvancedSPMDServerController serverController = new AdvancedSPMDServerController(
+						dataManager, referenceID);
+				// set first thread as master thread
+				serverController.setMasterThread(i == 0);
+				// now assign the calculation area. Because we have assumed that
+				// the (Thread)-calculation
+				// area begins at (0,0) we must move it relative to the real
+				// local calculation area
+				Rectangle calculationBounds = map1DVertical
+						.getPartitionCalculationBounds(i);
+				int absolutX = (int) (serverController.getLocalCalcMinX() + calculationBounds
+						.getMinX());
+				int absolutY = (int) (serverController.getLocalCalcMinY() + calculationBounds
+						.getMinY());
+				calculationBounds.setLocation(absolutX, absolutY);
+				serverController.setLocalCalculationBounds(calculationBounds);
+				tasks[i].setSPMDServerController(serverController);
+				tasks[i].initialize();
+			}
+		}
+		if (allowedThreads == 1) // only for saving resources: no new thread
+		{ // if only one thread is used
+			Object executionResult = tasks[0].run(parameters);
+			results = new Object[] { executionResult };
+		} else {
+			// for more than 1 processor execute the multiple tasks in separate
+			// threads
+			for (int i = 0; i < allowedThreads; i++) {
+				resultCalls[i] = executor.submit(new SimpleCallThread(tasks[i],
+						parameters));
+			}
+			// wait for the Threads to finish
+			for (int i = 0; i < allowedThreads; i++) {
+				try {
+					results[i] = resultCalls[i].get();
+				} catch (InterruptedException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} catch (ExecutionException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+		// generate a event for the execution
+		if (remoteEventReceiver.isTimeMonitoringEnabled())
+			remoteEventReceiver.fireRemoteEvent(new TimeEvent((System
+					.nanoTime() - time), serverName, "DataServer",
+					CommType.REMOTE_EXECUTION));
+		return results;
+	}
+
+	/**
+	 * This method frees all resources.<br>
+	 * Notice that this method is not remotely accessible!
+	 */
+	public void stopServer() {
+		unbind();
+		if (dataManager != null)
+			dataManager.stop();
+		dataManager = null;
+		if (multicastThread != null)
+			multicastThread.stopThread();
+	}
+}

Added: trunk/src/appl/parallel/server/XuluServerProperties.java
===================================================================
--- trunk/src/appl/parallel/server/XuluServerProperties.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/server/XuluServerProperties.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,57 @@
+package appl.parallel.server;
+
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryUsage;
+import java.lang.management.ThreadMXBean;
+import java.util.List;
+import java.util.Timer;
+
+import org.apache.log4j.lf5.util.Resource;
+
+import appl.parallel.ComputingResourceProperties;
+import appl.parallel.SimpleResourceProperties;
+
+/**
+ * Constructs information out of a XuluServer Object. Unfortunately there is no way
+ * to measure CPU load (for this you would need to have access to the OS core). This could
+ * be done with the use of the JNI, but that is low level programming and would be OS
+ * dependent.
+ *  
+ * Must be invoked on server side (which should be clear, anyway!).<br>
+ * 
+ * Sets the following properties:
+ * <br><br>
+ * Name <br>
+ * isAvailable<br>
+ * Uptime<br><br>
+ * 
+ * and of course the Properties the superclass sets<br>
+ * @author Dominik Appl
+ */
+public class XuluServerProperties extends SimpleResourceProperties implements
+		Serializable {
+
+	public XuluServerProperties(XuluServer server, String name) {
+		super();
+		if (name != null)
+			properties.setProperty("Name", name);
+		properties.setProperty("isAvailable", (!(server.isClientConnected()))
+				+ "");
+
+		//format uptime
+		int uptimeInSeconds = server.getUptime() / 1000;
+		int hours, minutes, seconds;
+		hours = uptimeInSeconds / 3600;
+		uptimeInSeconds = uptimeInSeconds - (hours * 3600);
+		minutes = uptimeInSeconds / 60;
+		uptimeInSeconds = uptimeInSeconds - (minutes * 60);
+		seconds = uptimeInSeconds;
+		String formatedTime = hours + "h " + minutes + "m " + seconds + "s";
+		properties.setProperty("Uptime", formatedTime);
+		properties.setProperty("Rating", server.getRating() + "");
+		properties.setProperty("Port", server.getRegistryPort() + "");
+	}
+
+}
\ No newline at end of file

Added: trunk/src/appl/parallel/server/package.html
===================================================================
--- trunk/src/appl/parallel/server/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/server/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,6 @@
+<html>
+<body>
+	Contains server related classes required for parallelization. Especially it contains the
+	XuluServer itself. 
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/services/DiscoveryService.java
===================================================================
--- trunk/src/appl/parallel/services/DiscoveryService.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/services/DiscoveryService.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,20 @@
+package appl.parallel.services;
+
+import java.util.Vector;
+
+import appl.parallel.ComputingResource;
+import appl.parallel.ComputingResourceContainer;
+
+/**
+ * A discovery service locates {@link ComputingResource ComputingRessouces} in a
+ * network.
+ * 
+ * @author Dominik Appl
+ */
+public interface DiscoveryService extends Service {
+
+	/**
+	 * @return the discovered resources
+	 */
+	Vector<ComputingResourceContainer> getResources();
+}

Added: trunk/src/appl/parallel/services/GlobalDiscoveryService.java
===================================================================
--- trunk/src/appl/parallel/services/GlobalDiscoveryService.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/services/GlobalDiscoveryService.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,146 @@
+package appl.parallel.services;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.ext.XuluConfig;
+import appl.parallel.ComputingResource;
+import appl.parallel.ComputingResourceContainer;
+
+/**
+ * This class is responsible for discovering Resources. For this it first starts
+ * all known {@link DiscoveryService DiscoveryServices} and queries them for
+ * known {@link ComputingResource Computing Resources}. <br>
+ * <br>
+ * This class starts all {@link DiscoveryService}s registered with the following
+ * property in the {@link XuluConfig}: <br>
+ * <br>
+ * DiscoveryServices.activeServices<br>
+ * <br>
+ * Register {@link DiscoveryService DiscoveryServices} with their fully
+ * qualified java name because
+ * {@link java.lang.Class#forName(String)  Class.forName} will be called on that
+ * String.
+ * 
+ * @author Dominik Appl
+ */
+public class GlobalDiscoveryService implements Service {
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	private static GlobalDiscoveryService instance;
+
+	Vector<DiscoveryService> services = new Vector<DiscoveryService>();
+
+	private boolean isRunning;
+
+	/**
+	 * @return all active {@link ComputingResource RemoteResources} in a
+	 *          container class with meta in the a ComputingResourceContainer
+	 *          Object. They are queried from all known Discovery Services. Do
+	 *          not query more than necessary!
+	 */
+	public Vector<ComputingResourceContainer> getRemoteResources() {
+		Vector<ComputingResourceContainer> discResources = new Vector<ComputingResourceContainer>();
+		// query all services for RemoteResources
+		for (DiscoveryService disc : services) {
+			Vector<ComputingResourceContainer> newResources = disc
+					.getResources();
+			// do not add double entrys
+			for (ComputingResourceContainer container : newResources) {
+				if (!(checkAlreadyInside(container, discResources)))
+					discResources.add(container);
+			}
+		}
+		return discResources;
+	}
+
+	/**
+	 * checks if the a remoteResource of a given container is in a Vector of
+	 * RemoteResourceContainers
+	 *
+	 * @param container
+	 * @return
+	 */
+	private boolean checkAlreadyInside(ComputingResourceContainer container,
+			Vector<ComputingResourceContainer> containers) {
+		for (ComputingResourceContainer originalcontainer : containers) {
+			if (originalcontainer.getResource().equals(container.getResource()))
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Looks up all services from the config file, loads them and also starts
+	 * them.
+	 */
+	public GlobalDiscoveryService() {
+		String[] classnames = XuluConfig.getXuluConfig().getMultiProperty(
+				"DiscoveryServices.activeServices");
+		for (String classname : classnames) {
+			Class serviceclass;
+			try {
+				serviceclass = Class.forName(classname);
+				DiscoveryService service = (DiscoveryService) serviceclass
+						.newInstance();
+				services.add(service);
+				service.startService();
+
+			} catch (ClassNotFoundException e) {
+				LOG.error("Class was not found for string" + classname);
+				LOG.error(e.getMessage());
+			} catch (InstantiationException e) {
+				LOG.error("Could not load class " + classname);
+				LOG.error(e.getMessage());
+			} catch (IllegalAccessException e) {
+				LOG.error("Could not load class " + classname);
+				LOG.error(e.getMessage());
+			}
+		}
+		// allow some time for the services to discover Resources
+		try {
+			Thread.currentThread().sleep(200);
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.services.Service#isRunning()
+	 */
+	public boolean isRunning() {
+		return isRunning;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.services.Service#startService()
+	 */
+	public void startService() {
+		isRunning = true;
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.services.Service#stopService()
+	 */
+	public void stopService() {
+		for (DiscoveryService s : services) {
+			s.stopService();
+		}
+		isRunning = false;
+
+	}
+
+}

Added: trunk/src/appl/parallel/services/HostnameDiscoveryService.java
===================================================================
--- trunk/src/appl/parallel/services/HostnameDiscoveryService.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/services/HostnameDiscoveryService.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,254 @@
+package appl.parallel.services;
+
+import java.net.MalformedURLException;
+import java.rmi.ConnectException;
+import java.rmi.Naming;
+import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
+import java.rmi.UnknownHostException;
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.ext.XuluConfig;
+import appl.parallel.ComputingResource;
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.starter.Starter;
+import appl.parallel.starter.client.StarterContainer;
+import appl.parallel.starter.server.XuluServerStarter;
+import appl.parallel.test.PingTestObject;
+
+/**
+ * Very simple Discovery Service that simply looks up hosts from Property <br>
+ * <br>
+ * <code>DiscoveryServices.hostname.hosts</code> <br>
+ * <br>
+ * of the {@link XuluConfig} <br>
+ * <br>
+ * Refreshes the hostlist on every {@link #getResources()}, if <br>
+ * <br>
+ * <code> DiscoveryServices.hostname.refresh</code> <br>
+ * <br>
+ * is set to 1, it gets the ips from Property <br>
+ * <br>
+ * DiscoveryService.hostname.hosts <br>
+ * <br>
+ * in {@link XuluConfig}
+ *
+ * @author Dominik Appl
+ */
+public class HostnameDiscoveryService implements DiscoveryService {
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	Vector<ComputingResource> res = new Vector<ComputingResource>();
+
+	ExecutorService executor = Executors.newCachedThreadPool();
+
+	private String[] lookupStrings;
+
+	private int timeout;
+
+	private boolean firstRefresh = true;
+
+	/** @return true
+	 * @see appl.parallel.services.Service#isRunning()
+	 */
+	public boolean isRunning() {
+		return true;
+	}
+
+	/**
+	 * @see appl.parallel.services.Service#startService()
+	 */
+	public void startService() {
+		executor = Executors.newCachedThreadPool();
+	}
+
+	/**
+	 * stops the service
+	 */
+	public void stopService() {
+		executor.shutdownNow();
+	}
+
+	/**
+	 * tries to (re-)discover every resource in Property <code>HostnameDiscoveryService.hosts</code>
+	 * of {@link XuluConfig}. After the time in ms specified in DiscoveryServices.timeout
+	 *
+	 */
+	@SuppressWarnings("unchecked")
+	public synchronized void refresh() {
+		//get timeout
+		initVariables();
+		res.addAll(getResourcesForLookupStrings());
+	}
+
+	private void initVariables() {
+		timeout = XuluConfig.getXuluConfig().getIntProperty(
+				"DiscoveryServices.timeout");
+		if (timeout == 0) {
+			LOG
+					.warn("DiscoveryServices.timeout was not set or was 0! Setting connect timeout to 500...");
+			timeout = 500;
+		}
+		//get IPs
+		res.clear();
+		String[] ips = XuluConfig.getXuluConfig().getMultiProperty(
+				"DiscoveryServices.hostname.hosts");
+		if (ips.length == 0 || (ips.length == 1 && ips[0].equals(""))) {
+			LOG.warn("No Resources found in DiscoveryServices.hostname.hosts");
+			ips = new String[0];
+		}
+		//generate lookupStrings:
+		lookupStrings = ips;
+	}
+
+	/** gets resources, but pings them first to see if they are alive. Not
+	 * 	reachable resouces are removed.
+	 *
+	 * @see appl.parallel.services.DiscoveryService#getResources()
+	 */
+	public Vector<ComputingResourceContainer> getResources() {
+		if (firstRefresh
+				|| XuluConfig.getXuluConfig().getBooleanProperty(
+						"DiscoveryServices.hostname.refresh") == true)
+			refresh();
+		firstRefresh = false;
+		return appl.parallel.util.Helper.getResourceContainersForVector(res);
+	}
+
+	/**
+	 * @return starterContainers for {@link XuluServerStarter}s
+	 */
+	public Vector<StarterContainer> getStarterContainers() {
+		initVariables();
+		String[] lookupNames = new String[lookupStrings.length];
+		for (int i = 0; i < lookupStrings.length; i++)
+			lookupNames[i] = "rmi://" + lookupStrings[i] + "/XuluServerStarter";
+
+		Vector<Starter> discoveredStarters = new Vector<Starter>();
+		Vector<StarterContainer> containers = new Vector<StarterContainer>();
+		// make a new Thread for each resouce
+		Future[] futures = new Future[lookupStrings.length];
+		for (int i = 0; i < lookupStrings.length; i++) {
+			futures[i] = executor.submit(new LookupCallable(lookupNames[i]));
+		}
+
+		// the time at which the result must be there:
+		long timeoutTime = System.currentTimeMillis() + timeout;
+		for (int i = 0; i < futures.length; i++) {
+			// servers previous in iterations may have caused a delay
+			// so the remaining time is calculated
+			long remainingTime = Math.max(10, timeoutTime
+					- System.currentTimeMillis());
+
+			try {
+				Starter starter = (Starter) futures[i].get(remainingTime,
+						TimeUnit.MILLISECONDS);
+				if (starter != null) {
+					discoveredStarters.add(starter);
+					containers.add(new StarterContainer(starter,
+							lookupStrings[i]));
+					LOG.debug("Discovered Starter: " + lookupNames[i]);
+				}
+			} catch (InterruptedException e) {
+				LOG.error(e);
+				e.printStackTrace();
+			} catch (ExecutionException e) {
+				LOG.error("Error while connecting to " + lookupNames[i]
+						+ " (Connect exception)");
+			} catch (TimeoutException e) {
+				LOG.warn("Could not find Starter " + lookupNames[i]
+						+ ". Timed out after " + timeout + "ms");
+				futures[i].cancel(true);
+			}
+		}
+		return containers;
+	}
+
+	private Vector<ComputingResource> getResourcesForLookupStrings() {
+		initVariables();
+		String[] lookupNames = new String[lookupStrings.length];
+		for (int i = 0; i < lookupStrings.length; i++)
+			lookupNames[i] = "rmi://" + lookupStrings[i] + "/XuluServer";
+
+		Vector<ComputingResource> discoveredResources = new Vector<ComputingResource>(
+				lookupNames.length);
+		// make a new Thread for each resource
+		Future[] futures = new Future[lookupNames.length];
+		for (int i = 0; i < lookupNames.length; i++) {
+			futures[i] = executor.submit(new LookupCallable(lookupNames[i]));
+		}
+
+		// the time at which the result must be there:
+		long timeoutTime = System.currentTimeMillis() + timeout;
+		for (int i = 0; i < futures.length; i++) {
+			// servers previous in iterations may have caused a delay
+			// so the remaining time is calculated
+			long remainingTime = Math.max(0, timeoutTime
+					- System.currentTimeMillis());
+
+			try {
+				ComputingResource server = (ComputingResource) futures[i].get(
+						remainingTime, TimeUnit.MILLISECONDS);
+				discoveredResources.add(server);
+				LOG.debug("Discovered resource: " + lookupNames[i]);
+			} catch (InterruptedException e) {
+				LOG.error(e);
+				e.printStackTrace();
+			} catch (ExecutionException e) {
+				LOG.error("Error while connecting to " + lookupNames[i], e);
+			} catch (TimeoutException e) {
+				LOG.warn("Could not add server " + lookupNames[i]
+						+ ". Timed out after " + timeout + "ms");
+				futures[i].cancel(true);
+			}
+		}
+		return discoveredResources;
+	}
+
+	/**
+	 * This class is used for lookup of remote resources. It handles all errors
+	 * and submits them to the LOG
+	 *
+	 * @author Dominik Appl
+	 */
+	private class LookupCallable implements Callable {
+
+		private final String lookupString;
+
+		private ComputingResource server = null;
+
+		public LookupCallable(String lookupString) {
+			this.lookupString = lookupString;
+
+		}
+
+		/* (non-Javadoc)
+		 * @see java.util.concurrent.Callable#call()
+		 */
+		public Object call() throws Exception {
+			try {
+				return Naming.lookup(lookupString);
+			} catch (UnknownHostException e) {
+				LOG.warn("(Unknown Host) Could not find host " + lookupString);
+			} catch (java.rmi.NotBoundException e) {
+				LOG.warn("(Not Bound) Could not find host " + lookupString);
+			} catch (java.rmi.ConnectException e) {
+				LOG.warn("(No Connection) Could not connect to host "
+						+ lookupString);
+			}
+			return null;
+		}
+	}
+
+}

Added: trunk/src/appl/parallel/services/MulticastDiscoveryService.java
===================================================================
--- trunk/src/appl/parallel/services/MulticastDiscoveryService.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/services/MulticastDiscoveryService.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,439 @@
+package appl.parallel.services;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.UnknownHostException;
+import java.rmi.Naming;
+import java.rmi.RemoteException;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.ext.XuluConfig;
+import appl.parallel.ComputingResource;
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.server.XuluServer;
+import appl.parallel.test.PingTestObject;
+import appl.parallel.util.Helper;
+
+/**
+ * Responsible for discovery of RemoteResources on the network, especially but
+ * not only {@link XuluServer XuluServers}. It listens for the following
+ * messages: <br>
+ * <br>
+ * "Hello Xulu from XuluServer" - sent by RemoteResources like
+ * {@link XuluServer} when starting <br>
+ * "Goodbye Xulu" - sent by RemoteResources like {@link XuluServer} when
+ * stopping <br>
+ * <br>
+ * and sends: <br>
+ * "Hello Servers" - when started If multicasting does not work try to disable
+ * your firewall or better configure it to allow multicast packages. Notice
+ * also, that multicasting may not work in virtual machines like MS Virtual PC
+ * 2004. <Warning><b>THIS CLASS IS STILL FOR DEMONSTRATION ONLY</b></Warning>
+ * 
+ * @author Dominik Appl
+ * @see XuluServer
+ */
+public class MulticastDiscoveryService implements DiscoveryService {
+
+	// the data to send
+	final String sendHello = "Hello Servers";
+
+	// data to receive
+	final String helloFromXuluServers = "Hello Xulu from XuluServer";
+
+	final String recGoodBye = "Goodbye Xulu";
+
+	// the Thread which waits on Server hello/goodbyes
+	volatile ReceiveThread receiveThread;
+
+	// volatile RenewalThread renewalThread;
+
+	// the thread that checks if servers are alive
+	// volatile CheckThread checkThread;
+
+	// the data is read from XuluConfig
+	InetAddress group;
+
+	int port;
+
+	int lease;
+
+	MulticastSocket socket;
+
+	boolean isRunning = false;
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	/**
+	 * Constructs a new service reading port and lease time from
+	 * {@link appl.ext.XuluConfig}
+	 */
+	public MulticastDiscoveryService() {
+		XuluConfig config = XuluConfig.getXuluConfig();
+		port = Integer.valueOf(config
+				.getProperty("DiscoveryServices.multicast.port"));
+		// lease = Integer.valueOf(config
+		// .getProperty("MulticastDiscoveryService.lease"));
+		try {
+			group = InetAddress.getByName(config
+					.getProperty("DiscoveryServices.multicast.group"));
+		} catch (UnknownHostException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Constructs a new service
+	 * 
+	 * @param port
+	 *            port where the multicasting happens
+	 * @param lease
+	 *            timeintervall (in ms) after whi
+	 */
+	public MulticastDiscoveryService(int port, int lease) {
+		this();
+		this.port = port;
+		this.lease = lease;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.Service#startService()
+	 */
+	public void startService() {
+		try {
+			LOG.info("Discoveryservice started");
+			// All Servers must listen on the port specified, in order fo
+			// the socket to receive
+			if (socket == null)
+				socket = new MulticastSocket(port);
+			// open a multicast group and join it
+
+			socket.joinGroup(group);
+
+			socket.setSoTimeout(5000);
+
+			// create and send Hello world
+			DatagramPacket datagram = new DatagramPacket(sendHello.getBytes(),
+					sendHello.length(), group, port);
+			System.out.println(group);
+			LOG.info("Send hello to all listening servers with broadcast IP "
+					+ group);
+
+			socket.send(datagram);
+
+			if (receiveThread == null) {
+				receiveThread = new ReceiveThread(socket, helloFromXuluServers,
+						recGoodBye);
+			}
+			if (!(receiveThread.isAlive()))
+				receiveThread.start();
+
+		} catch (UnknownHostException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.DiscoveryService#getResources()
+	 */
+	public Vector<ComputingResourceContainer> getResources() {
+		return receiveThread.getResources();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.Service#stopService()
+	 */
+	public void stopService() {
+		receiveThread.stopThread();
+		// renewalThread.stopThread();
+		try {
+			Thread.currentThread().sleep(100);
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		socket.close();
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.Service#isRunning()
+	 */
+	public boolean isRunning() {
+		return isRunning;
+	}
+
+	/** waits for incoming calls */
+
+	class ReceiveThread extends Thread {
+
+		// Resources discovered so far
+		Vector<ComputingResource> discoveredResources;
+
+		private volatile Thread receiveThread;
+
+		boolean exit = false;
+
+		MulticastSocket socket;
+
+		private final String recHello2;
+
+		private final String recGoodBye2;
+
+		private boolean discoveryInProgress = false;
+
+		/**
+		 * @returns a Vector of discovered Ressources before return, all values
+		 *          are pinged and only returned if alive
+		 */
+		public Vector<ComputingResourceContainer> getResources() {
+			return Helper.getResourceContainersForVector(discoveredResources);
+		}
+
+		/**
+		 * @param socket2
+		 *            Socket which is used for listening
+		 * @param helloFromXuluServers
+		 *            String that equals the hello message of the server
+		 * @param recGoodBye
+		 *            String that equals the Goordbye message of the server
+		 */
+		public ReceiveThread(MulticastSocket socket, String recHello,
+				String recGoodBye) {
+			recHello2 = recHello;
+			recGoodBye2 = recGoodBye;
+			this.socket = socket;
+			discoveredResources = new Vector<ComputingResource>();
+		}
+
+		/**
+		 * Safe method to stop the Thread. Use this method instead of
+		 * {@link Thread}
+		 */
+		public void stopThread() {
+			if (receiveThread != null) {
+				exit = true;
+				// the only way to stop the Thread is to send a package so that
+				// the receive operation no longer blocks
+				DatagramPacket datagram = new DatagramPacket(
+						"Stopping receive Thread".getBytes(),
+						"Stopping receive Thread".length(), group, port);
+				try {
+					socket.send(datagram);
+					// wait on stop
+					Thread.currentThread().sleep(100);
+				} catch (IOException e) {
+					e.printStackTrace();
+				} catch (InterruptedException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} finally {
+					exit = false;
+				}
+				exit = false;
+
+			}
+
+		}
+
+		public void run() {
+			receiveThread = Thread.currentThread();
+			while (!exit) {
+				try {
+					// receive buffer
+
+					byte[] buffer = new byte[256];
+					DatagramPacket datagram = new DatagramPacket(buffer,
+							buffer.length);
+					socket.receive(datagram);
+					// get the message in the right
+					byte[] result = new byte[datagram.getLength()];
+					System.arraycopy(datagram.getData(), 0, result, 0, datagram
+							.getLength());
+					// check if message is from XuluServer
+					if (new String(result).equals(helloFromXuluServers)) {
+						LOG.debug("received hello from server "
+								+ datagram.getAddress());
+
+						String newname = "rmi:/" + datagram.getAddress()
+								+ "/XuluServer";
+
+						ComputingResource server = (ComputingResource) Naming
+								.lookup(newname);
+						addRessource(server, datagram.getAddress().toString());
+
+					} else if (LOG.isDebugEnabled())
+						LOG.debug("received message |" + new String(result)
+								+ "| from " + datagram.getAddress());
+
+				} catch (java.net.SocketTimeoutException e) {
+					// catch timeout exception
+				}
+
+				catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				} catch (Exception e) {
+					if (!(e instanceof InterruptedException))
+						e.printStackTrace();
+				}
+			}
+			System.out.println("exit Thread " + this.toString());
+		}
+
+		/**
+		 * adds ressource to vector but first looks if its not already added
+		 * 
+		 * @param server
+		 */
+		private void addRessource(ComputingResource server, String IP) {
+			// check for double entries
+			for (ComputingResource s : discoveredResources) {
+				if (s.equals(server)) {
+					LOG.debug("Not adding " + server.toString()
+							+ " to discovered Ressources again!");
+					return;
+				}
+			}
+			LOG.info("Adding Xulu Server: " + IP + "to discovered Ressources");
+			// try {
+			// Thread.currentThread().sleep(2000);
+			// } catch (InterruptedException e) {
+			// // TODO Auto-generated catch block
+			// e.printStackTrace();
+			// }
+			discoveredResources.add(server);
+		}
+
+		/**
+		 * Gets the {@link Resource
+		 */
+		public void pingResources() {
+			PingTestObject po = new PingTestObject(32);
+			// cannot make a for each loop because of
+			// java.util.ConcurrentModificationException
+			int i = discoveredResources.size() - 1;
+			while (i >= 0) {
+				boolean error = true;
+				ComputingResource r = discoveredResources.get(i);
+				if (!(r == null)) {
+
+					try {
+						r.ping();
+						error = false;
+						LOG.debug("Ping to " + r + " was successfull!");
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+					// if not successfull remove object
+					if (error) {
+						LOG.debug("Ping to " + r
+								+ " was NOT successfull! Removing ressource");
+
+						discoveredResources.remove(r);
+					}
+				}
+				i--;
+			}
+		}
+
+	}
+
+	/**
+	 * simple Thread that caused rediscovery of Ressources at a given time
+	 * intervall **
+	 */
+
+	class RenewalThread extends Thread {
+
+		private volatile Thread thisThread;
+
+		boolean exit = false;
+
+		private final long timeintervall;
+
+		private volatile ReceiveThread discoveryToRenew;
+
+		/**
+		 * invokes rediscovery on the given thread at the given time intervall
+		 */
+		public RenewalThread(ReceiveThread discoveryToRenew, long timeintervall) {
+			this.discoveryToRenew = discoveryToRenew;
+			this.timeintervall = timeintervall;
+
+		}
+
+		/**
+		 * Safe method to stop this Thread. Use this method instead of
+		 * {@link Thread}
+		 */
+		public void stopThread() {
+			if (thisThread != null)
+				exit = true;
+		}
+
+		public void run() {
+			thisThread = Thread.currentThread();
+			while (!exit) {
+				discoveryToRenew.pingResources();
+				try {
+					Thread.currentThread().sleep(timeintervall);
+				} catch (InterruptedException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+			System.out.println("exit renewal Thread");
+		}
+
+	}
+
+	/**
+	 * just for testing..edit as you like
+	 */
+	public static void main(String[] args) {
+		BasicConfigurator.configure();
+		MulticastDiscoveryService bro = new MulticastDiscoveryService();
+		bro.startService();
+		try {
+			Thread.currentThread().sleep(5000);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		// bro.stopService();
+		while (true)
+			try {
+				Vector<ComputingResourceContainer> v = bro.getResources();
+				for (ComputingResourceContainer container : v) {
+					System.out.print("Active Object: ");
+					System.out.println(container.getInformation().getProperty(
+							"name")
+							+ " with IP "
+							+ container.getInformation().getProperty("IP"));
+				}
+				Thread.currentThread().sleep(5000);
+			} catch (InterruptedException e) {
+
+			}
+	}
+
+}

Added: trunk/src/appl/parallel/services/RemoteEventProxy.java
===================================================================
--- trunk/src/appl/parallel/services/RemoteEventProxy.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/services/RemoteEventProxy.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,190 @@
+package appl.parallel.services;
+
+import java.rmi.RemoteException;
+import java.util.Vector;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.parallel.event.CommEventSink;
+import appl.parallel.event.RemoteEvent;
+import appl.parallel.event.RemoteEventSink;
+import appl.parallel.event.TimeEvent;
+import appl.parallel.event.TransferEvent;
+
+/**
+ * Delays events and fires them after the delay all <b>at once</b> in one
+ * object (this will save communication time)
+ * 
+ * @author Dominik Appl
+ */
+public class RemoteEventProxy implements CommEventSink, Service {
+
+	/**
+	 * This Thread submits the events after the delay
+	 * 
+	 * @author Dominik Appl
+	 */
+	private class SubmitThread extends Thread {
+
+		private boolean exit = false;
+
+		private final ConcurrentLinkedQueue<RemoteEvent> queue2;
+
+		private final CommEventSink sink;
+
+		private final long delay;
+
+		SubmitThread(ConcurrentLinkedQueue<RemoteEvent> queue,
+				CommEventSink sink, long delay) {
+			queue2 = queue;
+			this.sink = sink;
+			this.delay = Math.max(100, delay);
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see java.lang.Thread#run()
+		 */
+		public void run() {
+			while (!exit) {
+				try {
+					this.sleep(delay);
+				} catch (InterruptedException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				// add all new events to a vector submit them at once
+				Vector<RemoteEvent> events = new Vector<RemoteEvent>();
+				while (queue.peek() != null)
+					events.add(queue.poll());
+				try {
+					if (events.size() > 0)
+						sink.fireRemoteEvents((RemoteEvent[]) events
+								.toArray(new RemoteEvent[events.size()]));
+				} catch (RemoteException e) {
+					// TODO Auto-generated catch block
+					LOG.warn("Could not transmit events." + e.getMessage(), e);
+					events.clear();
+				}
+			}
+		}
+
+		public void startThread() {
+			exit = false;
+			this.start();
+		}
+
+		public void stopThread() {
+			exit = true;
+		}
+	}
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	private boolean timeMonitoring = false;
+
+	private boolean transferMonitoring = false;
+
+	private boolean isRunning;
+
+	SubmitThread submitThread;
+
+	ConcurrentLinkedQueue<RemoteEvent> queue;
+
+	private final CommEventSink eventSink;
+
+	private final long delay;
+
+	/**
+	 * Creates a new proxy
+	 * 
+	 * @param targetSink
+	 *            the sink where the events should be submitted to
+	 * @param delay
+	 *            the delay (in milliseconds)
+	 */
+	public RemoteEventProxy(CommEventSink targetSink, long delay) {
+		this.eventSink = targetSink;
+		this.delay = delay;
+		queue = new ConcurrentLinkedQueue<RemoteEvent>();
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.event.RemoteEventSink#fireRemoteEvent(appl.parallel.event.RemoteEvent)
+	 */
+	public void fireRemoteEvent(RemoteEvent e) throws RemoteException {
+		queue.add(e);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.event.RemoteEventSink#fireRemoteEvents(appl.parallel.event.RemoteEvent[])
+	 */
+	public void fireRemoteEvents(RemoteEvent[] e) throws RemoteException {
+		for (RemoteEvent event : e) {
+			fireRemoteEvent(event);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.Service#isRunning()
+	 */
+	public boolean isRunning() {
+		return isRunning;
+	}
+
+	/**
+	 * @return true if the service is running and time monitoring is enabled
+	 */
+	public boolean isTimeMonitoringEnabled() throws RemoteException {
+		return timeMonitoring;
+	}
+
+	/**
+	 * @return true if the service is running and tansfer monitoring is enabled
+	 */
+	public boolean isTransferMonitoringEnabled() throws RemoteException {
+		return transferMonitoring;
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.Service#startService()
+	 */
+	public void startService() {
+		isRunning = true;
+		if (submitThread != null)
+			submitThread.stopThread();
+		submitThread = new SubmitThread(queue, eventSink, delay);
+		submitThread.startThread();
+		try {
+			this.timeMonitoring = eventSink.isTimeMonitoringEnabled();
+			this.transferMonitoring = eventSink.isTransferMonitoringEnabled();
+		} catch (RemoteException e) {
+			LOG.error("Could not connect to CommEventSink!!!");
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.services.Service#stopService()
+	 */
+	public void stopService() {
+		isRunning = false;
+		if (submitThread != null)
+			submitThread.stopThread();
+	}
+}

Added: trunk/src/appl/parallel/services/Service.java
===================================================================
--- trunk/src/appl/parallel/services/Service.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/services/Service.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,24 @@
+package appl.parallel.services;
+
+/**
+ * Superclass of all Services.
+ * 
+ * @author Dominik Appl
+ */
+public interface Service {
+
+	/**
+	 * Starts the service
+	 */
+	public void startService();
+
+	/**
+	 * Stops the service
+	 */
+	public void stopService();
+
+	/**
+	 * @return true, if the service is running
+	 */
+	public boolean isRunning();
+}

Added: trunk/src/appl/parallel/services/package.html
===================================================================
--- trunk/src/appl/parallel/services/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/services/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,6 @@
+<html>
+<body>
+	Contains some service classes used with the parallelization. The discovery classes are used
+	to find servers in a network. 
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/spmd/AbstractSPMDTask.java
===================================================================
--- trunk/src/appl/parallel/spmd/AbstractSPMDTask.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/AbstractSPMDTask.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,117 @@
+package appl.parallel.spmd;
+
+import java.awt.Rectangle;
+
+import schmitzm.data.WritableGrid;
+
+/**
+ * This class may be used as the superclass to all {@link SPMDTask SPMDTasks}
+ * which should be executed on servers using the SPMD-paradigm. Subclasses
+ * should override the {@link #init()} and the {@link #run(Object...)} method,
+ * but never the {@link #initialize()} method. <br>
+ * <br>
+ * The Task provides access to the {@link SPMDClientInterface} and the
+ * {@link AdvancedSPMDClientInterface}. <br>
+ * <br>
+ * Notice that the {@link #init()} method is called exactly one time before
+ * execution for every instance (in multithreading there are multiple parallel
+ * instances of the same task, running on different parts of the resource).
+ * 
+ * @author Dominik Appl
+ */
+public abstract class AbstractSPMDTask implements SPMDTask {
+
+	protected transient AdvancedSPMDServerInterface serverController;
+
+	private boolean initalized = false;
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.SPMDTask#incomingUpdate(schmitzm.data.WritableGrid,
+	 *      java.awt.Rectangle)
+	 */
+	public void incomingUpdate(WritableGrid outgoingGrid, Rectangle location) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.SPMDTask#outgoingUpdate(schmitzm.data.WritableGrid,
+	 *      java.awt.Rectangle)
+	 */
+	public void outgoingUpdate(WritableGrid incomingGrid, Rectangle location) {
+		// TODO Auto-generated method stub
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.SPMDTask#run()
+	 */
+	public abstract Object run(Object... parameters);
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.SPMDTask#getSPMDServerController()
+	 */
+	public SPMDServerInterface getSPMDServerController() {
+		return serverController;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.SPMDTask#getAdvancedSPMDServerController()
+	 */
+	public AdvancedSPMDServerInterface getAdvancedSPMDServerController() {
+		return serverController;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.SPMDTask#setSPMDServerController(appl.parallel.spmd.SPMDServerController)
+	 */
+	public void setSPMDServerController(AdvancedSPMDServerInterface controller) {
+		this.serverController = controller;
+	}
+
+	/**
+	 * Use this method to implement if you want t
+	 */
+	public abstract void init();
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.SPMDTask#initialize()
+	 */
+	public final void initialize() {
+		init();
+		initalized = true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.SPMDTask#isInitialized()
+	 */
+	public boolean isInitialized() {
+		return initalized;
+	}
+
+	/**
+	 * returns false. Override this method to enable multithreading
+	 * 
+	 * @see appl.parallel.spmd.SPMDTask#supportsMultiThreading()
+	 */
+	public boolean supportsMultiThreading() {
+		return false;
+	}
+
+}

Added: trunk/src/appl/parallel/spmd/AdvancedSPMDClientController.java
===================================================================
--- trunk/src/appl/parallel/spmd/AdvancedSPMDClientController.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/AdvancedSPMDClientController.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,185 @@
+package appl.parallel.spmd;
+
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.thread.OneMethodThread;
+
+/**
+ * Performance optimizations on client side can be made with this class. Allows
+ * heavy multithreading.<br>
+ * <br>
+ * Merging can be done in a separate thread (parallel to further computation)<br>
+ * 
+ * @see SPMDClientController for details on the usage of a client controller
+ * 
+ * @author Dominik Appl
+ */
+public class AdvancedSPMDClientController extends SPMDClientController
+		implements AdvancedSPMDClientInterface {
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	// used for synchronization
+	private static final Object syncOperationMontitor = new Object();
+
+	/**
+	 * For each {@link SyncPoint} a vector of threads associated with the point
+	 * is created
+	 */
+	HashMap<SyncPoint, Vector<OneMethodThread>> vectorMap = new HashMap<SyncPoint, Vector<OneMethodThread>>();
+
+	/**
+	 * Empty thread which is used as indicator for a already synchronized sync
+	 * point
+	 */
+	private static final Vector<OneMethodThread> alreadySynchronized = new Vector<OneMethodThread>(
+			1);
+
+	/**
+	 * same parameters as superclass
+	 * 
+	 * @see SPMDClientController#SPMDClientController(Vector, double[],
+	 *      ClientDataServer, CommEventSink)
+	 */
+	public AdvancedSPMDClientController(
+			Vector<ComputingResourceContainer> computingResources,
+			double[] weights, ClientDataServer spmdClient,
+			CommEventSink eventProxy) {
+		super(computingResources, weights, spmdClient, eventProxy);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.AdvancedSPMDClientInterface#mergePartition(java.lang.Object,
+	 *      appl.parallel.spmd.SyncPoint)
+	 */
+	public void mergePartition(final Object partition, SyncPoint s,
+			final PrintStream stream, final String message) {
+		checkSplittable(partition);
+		// create a new thread
+		OneMethodThread newThread = new OneMethodThread("mergeThread"
+				+ s.getId(), s.getPriority()) {
+			@Override
+			public void run() {
+				mergePartition(partition);
+				if (stream != null) {
+					stream.println(message);
+				}
+			}
+		};
+		mapThreadToSyncPoint(newThread, s);
+		newThread.start();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.AdvancedSPMDClientInterface#mergePartition(java.lang.Object,
+	 *      appl.parallel.spmd.SyncPoint)
+	 */
+	public synchronized void mergePartition(Object partition, SyncPoint s) {
+		mergePartition(partition, s, null, null);
+	}
+
+	/**
+	 * Puts a Thread/Syncpoint pair into the Hashmap/Vector structure
+	 */
+	private void mapThreadToSyncPoint(OneMethodThread thread, SyncPoint s) {
+		// access to the syncpoints must be synchronized when working with
+		// multithreading
+		synchronized (syncOperationMontitor) {
+			Vector<OneMethodThread> threads = vectorMap.get(s);
+			// if this is the first thread for the syncPoint: create a new
+			// Vector
+			if (threads == null) {
+				threads = new Vector<OneMethodThread>(5);
+				vectorMap.put(s, threads);
+			}
+			threads.add(thread);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.AdvancedSPMDClientInterface#mergeMultiData(appl.parallel.spmd.MultiDataObject,
+	 *      int, appl.parallel.spmd.SyncPoint, java.io.PrintStream,
+	 *      java.lang.String)
+	 */
+	public synchronized void mergeMultiData(MultiDataObject multidata, int idx,
+			SyncPoint s, PrintStream stream, String message) {
+		// create a new thread
+		OneMethodThread newThread = new OneMethodThread("mergeThread-"
+				+ s.getId(), s.getPriority(), multidata, idx, stream, message) {
+			@Override
+			public void run() {
+				mergeMultiData((MultiDataObject) getParameter(0),
+						(Integer) getParameter(1));
+				if (getParameter(2) != null) {
+					PrintStream stream = (PrintStream) getParameter(2);
+					stream.println(getParameter(3));
+				}
+			}
+		};
+		mapThreadToSyncPoint(newThread, s);
+		newThread.start();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.AdvancedSPMDClientInterface#mergeMultiData(appl.parallel.spmd.MultiDataObject,
+	 *      int, appl.parallel.spmd.SyncPoint)
+	 */
+	public void mergeMultiData(MultiDataObject multidata, int idx, SyncPoint s) {
+		mergeMultiData(multidata, idx, s, null, null);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.AdvancedSPMDClientInterface#synchronizeToSyncPoint(appl.parallel.spmd.SyncPoint)
+	 */
+	public void synchronizeToSyncPoint(SyncPoint s) {
+		// access to the syncpoints must be synchronized when working with
+		// multithreading
+		synchronized (syncOperationMontitor) {
+			// join all threads associated with the given syncPoint
+			Vector<OneMethodThread> threads = vectorMap.get(s);
+			// Multithreading: check if another thread has already synchronized
+			// to
+			// the given point
+			if (threads == alreadySynchronized) {
+				if (LOG.isDebugEnabled())
+					LOG.debug("SyncPoint " + s.getId()
+							+ " was already synchronized");
+				return;
+			}
+			// if no thread was found: Some error occured.
+			if (threads == null) {
+				UnsupportedOperationException e = new UnsupportedOperationException(
+						"The Thread with the SyncPoint '" + s.getId()
+								+ "' does not exist. Synchronisation failed!!");
+				LOG.error("The Thread with the SyncPoint '" + s.getId()
+						+ "' was not found. Synchronisation failed!!", e);
+				throw e;
+			}
+			for (Iterator iter = threads.iterator(); iter.hasNext();) {
+				OneMethodThread thread = (OneMethodThread) iter.next();
+				thread.join();
+			}
+			// indicate as synchronized
+			vectorMap.put(s, alreadySynchronized);
+		}
+	}
+}

Added: trunk/src/appl/parallel/spmd/AdvancedSPMDClientInterface.java
===================================================================
--- trunk/src/appl/parallel/spmd/AdvancedSPMDClientInterface.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/AdvancedSPMDClientInterface.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,96 @@
+package appl.parallel.spmd;
+
+import java.io.PrintStream;
+
+import appl.parallel.server.PartitionDataManager;
+import appl.parallel.spmd.split.DataPartition;
+
+/**
+ * This class extends the {@link SPMDClientInterface} with additional features for performance tuning. You can merge
+ * partitions in background (so that the not very cpu-intensive communication can
+ * happen during extensive calculations). <br>
+ * 
+ * @author Dominik Appl
+ */
+public interface AdvancedSPMDClientInterface extends SPMDClientInterface {
+
+	/**
+	 * Merges like {@link SPMDClientController#mergePartition(int)}, but in a
+	 * separate thread, so that communication does not block computation. See
+	 * also {@link SyncPoint synchronization points}
+	 * 
+	 * @param partition
+	 *            the partition to be merged (must be splittable)
+	 * @param s
+	 *            a syncpoint
+	 */
+	public void mergePartition(Object partition, SyncPoint s);
+
+	/**
+	 * Merges like
+	 * {@link SPMDClientController#mergeMultiData(MultiDataObject, int)}. But
+	 * allows also {@link SyncPoint synchronization points}
+	 * 
+	 * @param multidata
+	 *            the multidataobject
+	 * @param idx
+	 *            the partition of the {@link MultiDataObject} to be merged
+	 * @param s
+	 *            a {@link SyncPoint}
+	 */
+	public void mergeMultiData(MultiDataObject multidata, int idx, SyncPoint s);
+
+	/**
+	 * Same functionality as {@link #mergePartition(Object, SyncPoint)}, gives
+	 * a message to the given {@link PrintStream}
+	 * 
+	 * @param partition
+	 *            the partition to merge
+	 * @param s
+	 *            a {@link SyncPoint}
+	 * @param stream
+	 *            the message is given out to this stream (or null for no
+	 *            message)
+	 * @param message
+	 *            the message to be displayed when finished (or null for no
+	 *            message)
+	 * @see #mergeMultiData(MultiDataObject, int, SyncPoint)
+	 */
+	public void mergePartition(Object partition, SyncPoint s,
+			PrintStream stream, String message);
+
+	/**
+	 * Merges like
+	 * {@link SPMDClientController#mergeMultiData(MultiDataObject, int)}. But
+	 * allows also {@link SyncPoint synchronization points}. At the end of the
+	 * merge a message is given to the provided {@link PrintStream}.
+	 * 
+	 * @param multidata
+	 *            the multidataobject
+	 * @param idx
+	 *            the partition of the {@link MultiDataObject} to be merged
+	 * @param s
+	 *            a {@link SyncPoint}
+	 * @param stream
+	 *            the message is given out to this stream (or null for no
+	 *            message)
+	 * @param message
+	 *            the message to be diplayed when finished (or null for no
+	 *            message)
+	 */
+	public void mergeMultiData(MultiDataObject multidata, int idx, SyncPoint s,
+			PrintStream stream, String message);
+
+	/**
+	 * Waits until the Thread with the specified SyncPoint finishes. After that
+	 * the Thread is removed. A second thread which synchronizes to the same
+	 * Point will directly continue.
+	 * 
+	 * @param s
+	 *            the {@link SyncPoint}
+	 * @throws UnsupportedOperationException
+	 *             if the SyncPoint does not exist and has never existed
+	 */
+	public void synchronizeToSyncPoint(SyncPoint s);
+
+}
\ No newline at end of file

Added: trunk/src/appl/parallel/spmd/AdvancedSPMDServerController.java
===================================================================
--- trunk/src/appl/parallel/spmd/AdvancedSPMDServerController.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/AdvancedSPMDServerController.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,223 @@
+package appl.parallel.spmd;
+
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Vector;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.client.DataServer;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.server.PartitionDataManager;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.thread.OneMethodThread;
+
+/**
+ * Performance optimizations can be made with this class. Allows heavy
+ * multithreading. Because multiple threads may use this class concurrently
+ * nearly all additional methods of this class are internally synchronized using a static variable.
+ * Also allows preloading of partitions using {@link SyncPoint}s.
+ * 
+ * @author Dominik Appl
+ */
+public class AdvancedSPMDServerController extends SPMDServerController
+		implements AdvancedSPMDServerInterface {
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	private static final HashMap<String, String> partitionPreloadStatus = 
+		                                                    new HashMap<String, String>();
+
+	// private static final HashMap<Integer,String> multiPartitionPreloadStatus
+	// = new HashMap<Integer, String>();
+	/**
+	 * For each {@link SyncPoint} a vector of threads associated with the id of
+	 * a SyncPoint is created. The {@link HashMap} is static so all possible threads use
+	 * the same map. Access to this map must be synchronized
+	 */
+	private static final HashMap<Integer, Vector<OneMethodThread>> vectors =
+		                                              new HashMap<Integer, Vector<OneMethodThread>>();
+
+	private boolean isMaster = true;
+
+	/**
+	 * same parameters as superclass
+	 * 
+	 * @see SPMDServerController#SPMDServerController(PartitionDataManager, int)
+	 */
+	public AdvancedSPMDServerController(PartitionDataManager dataManager,
+			int referenceResouceID) {
+		super(dataManager, referenceResouceID);
+		// TODO Auto-generated constructor stub
+	}
+
+	/**
+	 * The partition is loaded in a separate thread into the local
+	 * {@link PartitionDataManager}<br>
+	 * You must specify the partition name and a {@link SyncPoint}.<br>
+	 * You can specify a priority for the thread in the {@link SyncPoint}.
+	 * <br>
+	 * <br>
+	 * <b>Preloading will only be done one time independent of the number of 
+	 * parallel threads calling this method. (synchronized)<br>
+	 * </b>
+	 * 
+	 * @param partition
+	 *            the name of the partition for identification
+	 * @param s
+	 *            the associated {@link SyncPoint}
+	 * @see SPMDServerController#getPartition(String)
+	 * @see #isMasterThread()
+	 */
+	public void preloadPartition(String partition, SyncPoint s) {
+		// create a new thread only if some other thread has not already
+		// triggered the preloading
+		synchronized (vectors) {
+			if (partitionPreloadStatus.get(partition) == null) {
+				partitionPreloadStatus.put(partition, "inProgress");
+				OneMethodThread newThread = new OneMethodThread(
+						"getPartitionThread " + s.getId(), s.getPriority(),
+						partition) {
+					@Override
+					public void run() {
+						// retrieving the partition will as a sideeffect trigger
+						// loading the
+						// partition into the PartitionDataManager
+						getPartition((String) getParameter(0));
+					}
+				};
+				mapThreadToSyncPoint(newThread, s);
+				newThread.start();
+			}
+		}
+	}
+
+	/**
+	 * The partition is loaded in a separate thread into the local
+	 * {@link PartitionDataManager} You must specify the partition name and a
+	 * {@link SyncPoint}. You can specify a priority for the thread in the
+	 * {@link SyncPoint} <br>
+	 * <b>Preloading will only be done one time independent of the number of 
+	 * parallel threads calling this method. (synchronized)<br>
+	 * </b>
+	 * 
+	 * @param multiPartition
+	 *            the name of the partition for identification
+	 * @param idx
+	 *            the index of the partition in the multidata object
+	 * @param s
+	 *            the associated {@link SyncPoint}
+	 * @see appl.parallel.spmd.AdvancedSPMDClientInterface#mergePartition(java.lang.Object,
+	 *      appl.parallel.spmd.SyncPoint)
+	 * @see SPMDServerController#getPartition(String)
+	 */
+	public void preloadMultiPartition(String multiPartition, int idx,
+			SyncPoint s) {
+		synchronized (vectors) {
+			// create a new thread only if some other thread has not already
+			// triggered the preloading
+			if (partitionPreloadStatus.get(multiPartition
+					+ MultiDataInfo.MULTISPLITCONSTANT + idx) == null) {
+				partitionPreloadStatus.put(multiPartition
+						+ MultiDataInfo.MULTISPLITCONSTANT + idx, "inProgress");
+
+				OneMethodThread newThread = new OneMethodThread(
+						"Preload thread - getMultiPartition SID:" + s.getId(),
+						s.getPriority(), multiPartition, idx) {
+					@Override
+					public void run() {
+						// retrieving the partition will also trigger loading
+						// the
+						// partition into the PartitionDataManager
+						getMultiPartition((String) getParameter(0),
+								(Integer) getParameter(1));
+					}
+				};
+				mapThreadToSyncPoint(newThread, s);
+				newThread.start();
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.AdvancedSPMDServerInterface#synchronizeToSyncPoint(appl.parallel.spmd.SyncPoint)
+	 */
+	public void synchronizeToSyncPoint(SyncPoint s) {
+		// join all threads associated with the given syncPoint
+		synchronized (vectors) {
+			Vector<OneMethodThread> threads = vectors.get(s.getId());
+			if (threads == null) {
+				UnsupportedOperationException e = new UnsupportedOperationException(
+						"The Thread with the SyncPoint '"
+								+ s.getId()
+								+ "' was not found or was earlier synchronized. Synchronisation failed!!");
+				LOG.error("The Thread with the SyncPoint '" + s.getId()
+						+ "' was not found. Synchronisation failed!!", e);
+				throw e;
+			}
+			for (Iterator iter = threads.iterator(); iter.hasNext();) {
+				OneMethodThread thread = (OneMethodThread) iter.next();
+				thread.join();
+
+			}
+		}
+	}
+
+	/**
+	 * You should call this method from time to time to clear all syncpoints and
+	 * the associated threads out of the memory
+	 */
+	public void clearSyncData() {
+		synchronized (vectors) {
+			vectors.clear();
+			partitionPreloadStatus.clear();
+		}
+	}
+
+	/**
+	 * Puts a thread/Syncpoint pair into the Hashmap/Vector structure
+	 */
+	private static void mapThreadToSyncPoint(OneMethodThread thread, SyncPoint s) {
+		Vector<OneMethodThread> threads = vectors.get(s.getId());
+		// if this is the first thread for the syncPoint: create a new
+		// Vector
+		if (threads == null) {
+			threads = new Vector<OneMethodThread>(5);
+			vectors.put(s.getId(), threads);
+		}
+		threads.add(thread);
+
+	}
+
+	/**
+	 * If there are multiple processors on the machine and the current task
+	 * {@link SPMDTask#supportsMultiThreading() supports multithreading} there
+	 * are several threads created. Each thread uses a different
+	 * {@link #getLocalBounds(DataPartition) calculation area}. Now there might
+	 * be parts of the task code were multithreading is undesired, e.g. when
+	 * operations affect the whole partition. In this case you should use this
+	 * method to guarantee that only one thread has access to a code block.
+	 * 
+	 * @return whether this thread is the "master" thread, which means whether
+	 *         this thread refers to the first task created.
+	 */
+	public boolean isMasterThread() {
+		return isMaster;
+
+	}
+
+	/**
+	 * @param isMaster
+	 *            true, if this should be the master thread
+	 * @see #isMasterThread()
+	 */
+	public void setMasterThread(boolean isMaster) {
+		this.isMaster = isMaster;
+	}
+}

Added: trunk/src/appl/parallel/spmd/AdvancedSPMDServerInterface.java
===================================================================
--- trunk/src/appl/parallel/spmd/AdvancedSPMDServerInterface.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/AdvancedSPMDServerInterface.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,81 @@
+package appl.parallel.spmd;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import appl.parallel.server.PartitionDataManager;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.thread.OneMethodThread;
+
+/**
+ * Performance optimizations can be made with this type of controller. It allows heavy
+ * multithreading. Also allows preloading of partitions using SyncPoints.
+ * 
+ * @author Dominik Appl
+ */
+public interface AdvancedSPMDServerInterface extends SPMDServerInterface {
+	/**
+	 * The partition is loaded in a separate thread into the local {@link PartitionDataManager}
+	 * You must specify the partitionname and a {@link SyncPoint}.
+	 * You can specifiy a priority for the thread in the {@link SyncPoint}
+	 * 
+	 * @param partition the name of the partition for identification
+	 * @param s the associated {@link SyncPoint}
+	 * 
+	 * @see appl.parallel.spmd.AdvancedSPMDClientInterface#mergePartition(java.lang.Object, appl.parallel.spmd.SyncPoint)
+	 * @see SPMDServerController#getPartition(String)
+	 * 
+	 */
+	public void preloadPartition(String partition, SyncPoint s);
+	
+	/**
+	 * The partition is loaded in a separate thread into the local {@link PartitionDataManager}
+	 * You must specify the partitionname and a {@link SyncPoint}.
+	 * You can specifiy a priority for the thread in the {@link SyncPoint}
+	 * 
+	 * @param partition the name of the partition for identification
+	 * @param idx the index of the partition in the multidata object
+	 * @param s the associated {@link SyncPoint}
+	 * 
+	 * @see appl.parallel.spmd.AdvancedSPMDClientInterface#mergePartition(java.lang.Object, appl.parallel.spmd.SyncPoint)
+	 * @see SPMDServerController#getPartition(String)
+	 * 
+	 */
+	public void preloadMultiPartition(String partition, int idx, SyncPoint s);
+	
+	
+	/**
+	 * Waits until the Thread with the specified SyncPoint finishes. After that
+	 * the Thread is removed. A second call will cause a exeception.
+	 * 
+	 * @param s
+	 *            the {@link SyncPoint}
+	 * @throws UnsupportedOperationException
+	 *             if a thread with the specified SyncPoint was not found or was
+	 *             already synchronized!
+	 */
+	public void synchronizeToSyncPoint(SyncPoint s); 
+	
+	/**
+	 * If there are multiple processors on the machine and the current task
+	 * supports
+	 * {@link SPMDTask#supportsMultiThreading() supports multithreading} there
+	 * are several threads created. Each thread uses a different
+	 * {@link SPMDServerInterface#getLocalCalculationBounds(DataPartition) calculation area}. Now there might
+	 * be parts of the taskcode were multithreading is undesired, e.g. when
+	 * operations affect the whole partition. In this case you should use this
+	 * method to guarantee that only one thread has access to a code block.
+	 *  
+	 * @return whether this thread is the "master" thread, which means whether this thread
+	 * 			refers to the first task created.
+	 */
+	public boolean isMasterThread();
+	
+	/**
+	 * You should call this method from time to time to clear all syncpoints and the associated
+	 * threads out of the memory
+	 */
+	public void clearSyncData();
+	
+	
+}

Added: trunk/src/appl/parallel/spmd/MultiDataInfo.java
===================================================================
--- trunk/src/appl/parallel/spmd/MultiDataInfo.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/MultiDataInfo.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,108 @@
+package appl.parallel.spmd;
+
+import java.io.Serializable;
+import java.rmi.RemoteException;
+import java.util.Vector;
+
+import appl.parallel.server.PartitionDataServer;
+import appl.parallel.server.PartitionDataManager;
+
+/**
+ * Instances of this class encapsulate information about multiple objects
+ * of the same type, e.g. lists of grids. In contrast to the MultiDataObject there
+ * are no objects stored, but only the IDs of the objects. That simplifies the
+ * the synchronization of multidata information over a network.
+ *
+
+ *
+ * @author Dominik Appl
+ */
+public class MultiDataInfo implements Serializable {
+	Vector<Integer> ids = new Vector<Integer>();
+
+	String name;
+
+	/**
+	 * This constant is used as a divider for adding multiple data associated with the same
+	 * name.
+	 * The dividing should be as follows: name + MULTISPLITCONSTANT + index
+	 */
+	public static final String MULTISPLITCONSTANT = ";)|(;";
+
+	public MultiDataInfo(int[] ids,  String name){
+		this.name = name;
+		for (int i : ids) {
+			this.ids.add(i);
+		}
+	}
+
+	/**
+	 * Adds a new Element with the specified id.
+	 * @param id The ID of the new element.
+	 * @return the name of the new Element
+	 *
+	 */
+	public String addElement(int id){
+		ids.add(id);
+		return getNameWithIdx(getCount()-1, name);
+	}
+
+
+	public int getMultiID(int idx){
+		return ids.get(idx);
+	}
+
+	/**
+	 * Generates a identification String based only on the given name and the given idx.
+	 * It can be used for identification of the same data over multiple resources
+	 *
+	 * @param idx the index of the element in the multidata
+	 * @param name the name of the element
+	 * @return the identification string
+	 *
+	 * @see #getIndexFromNameWithIdx(String)
+	 *
+	 */
+	public static String getNameWithIdx(int idx, String name){
+		return  name + MULTISPLITCONSTANT + idx;
+	}
+
+
+	/**
+	 * Extracts the the the index out of a identification
+	 * @param identificationName the identification
+	 * @return the index
+	 *
+	 * @see #getNameWithIdx(int, String)
+	 */
+	public static int getIndexFromNameWithIdx(String identificationName){
+		String index = identificationName.split(MULTISPLITCONSTANT)[1];
+		int i = Integer.valueOf(index);
+		System.out.println("MulitDataInfo: Returning " + i);
+		return i;
+	}
+
+	/**
+	 * Generates a new id for a given index, based on the id of the first element
+	 * in the multidata.
+	 * @param idx the index for which a new id should be generated
+	 * @return the new id
+	 */
+	public int getNewIDForIndex(int idx){
+		return getMultiID(0) * (-1) - idx;
+	}
+
+	/**
+	 * @return the number of elements currently in the multi-info
+	 */
+	public int getCount(){
+		return ids.size();
+	}
+
+	/**
+	 * @return the name associated with this multi-id
+	 */
+	public String getName(){
+		return name;
+	}
+}

Added: trunk/src/appl/parallel/spmd/MultiDataObject.java
===================================================================
--- trunk/src/appl/parallel/spmd/MultiDataObject.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/MultiDataObject.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,195 @@
+package appl.parallel.spmd;
+
+import java.rmi.RemoteException;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import schmitzm.data.WritableGrid;
+
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+import appl.parallel.client.DataServer;
+import appl.parallel.server.PartitionDataServer;
+import appl.parallel.spmd.split.DataPartition;
+
+/**
+ * A multi data object stores multiple elements of the same type.
+ * While the related {@link MultiDataInfo} stores only Information about 
+ * multi-data and is used by Xulu / V for transfer of metadata, this class
+ * is a actual user object. The user can retrieve a multidata object e.g. via the
+ * {@link SPMDServerController} and work with it (e.g. add elements)
+ * 
+ * @see SPMDServerInterface#getMultiData(String)
+ * @see MultiDataInfo
+ * 
+ * @author Dominik Appl
+ **/
+
+public class MultiDataObject {
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	private final MultiDataInfo multiDataInfo;
+
+	private final DataServer dataServer;
+
+	private MultiGrid managedGrid = null;
+
+	/**
+	 * Construct a new Multidata object
+	 * 
+	 * @param info a {@link MultiDataInfo} object with the identification of the objects
+	 * @param dataServer a dataServer which is responsible for the actual loading of the data
+	 */
+	public MultiDataObject(MultiDataInfo info, DataServer dataServer) {
+		this.multiDataInfo = info;
+		this.dataServer = dataServer;
+	}
+
+	/**
+	 * @param idx the position of the element
+	 * @return the element at the indicated position
+	 */
+	public Object getElement(int idx) {
+		try {
+			checkIndex(idx);
+			return dataServer.getData(multiDataInfo.getMultiID(idx));
+		} catch (RemoteException e) {
+			LOG.error("RemoteExeception while retrieving data with ID "
+					+ multiDataInfo.getMultiID(idx)
+					+ " from PartitionDataServer");
+		}
+		return null;
+	}
+
+	/**
+	 * checks whether the indicated index is valid
+	 * @throws ArrayIndexOutOfBoundsException if idx is below zero or higher than number of elements 
+	 */
+	private void checkIndex(int idx) {
+		if ((idx > multiDataInfo.getCount() - 1) || idx <0 )
+			throw new ArrayIndexOutOfBoundsException("The Element with index "
+					+ idx + " was requested, but the MultiDataObject has only "
+					+ multiDataInfo.getCount() + " elements.");
+
+	}
+
+	/**
+	 * @return the number of elements in the multidataobject
+	 */
+	public int getCount() {
+		return multiDataInfo.getCount();
+	}
+
+	/**
+	 * Adds an element to MultiDataObjects. Method should be thread safe.
+	 * 
+	 * @return the index of the new element
+	 */
+	public synchronized int addElement() {
+		//the new ID of the MultiDataObject is generated by making
+		//the first id negative and than subtracting the index from 
+		//the ID
+		int idx = multiDataInfo.getCount() - 1;
+		try {
+			if (idx == -1)
+				throw new UnsupportedOperationException(
+						"The MultiDataInfo must have at least one element!");
+			//simply get the first element and create a empty one.
+			int firstElementID = multiDataInfo.getMultiID(0);
+			DataPartition firstElement = dataServer.getData(firstElementID);
+			//generate a new id by making the first ID negative and subtracting the index value
+			int newID = multiDataInfo.getNewIDForIndex(idx + 1);
+			//there is a rare chance of colliding with existing ids:
+			while (dataServer.getData(newID) != null) {
+				newID--;
+			}
+			//create new element 
+			DataPartition newElement = firstElement.getEmpty(newID);
+			multiDataInfo.addElement(newID);
+			//add the element to the dataServer and to the managed MultiGrid (if any)
+			dataServer.addData(newElement);
+			if (managedGrid != null)
+				managedGrid.addGrid((WritableGrid) newElement);
+			return idx + 1;
+		} catch (RemoteException e) {
+			LOG
+					.error("RemoteExeception while trying to add a new element with idx "
+							+ idx + " to MultiData");
+		}
+		return 0;
+	}
+
+	/**
+	 * Adds an element with the specified ID.
+	 * 
+	 * @param id the id of the element to add
+	 * @return the index of the new element or 0 if an error occurred
+	 */
+	public int addElement(int id) {
+		//actual maxIndex
+		int idx = multiDataInfo.getCount() - 1;
+		try {
+			if (idx == -1)
+				throw new UnsupportedOperationException(
+						"The MultiDataInfo must have at least one element!");
+			//simply get the first element and create a empty one.
+			int firstElementID = multiDataInfo.getMultiID(0);
+			DataPartition firstElement = dataServer.getData(firstElementID);
+
+			//create new element 
+			DataPartition newElement = firstElement.getEmpty(id);
+			multiDataInfo.addElement(id);
+			//add the element to the dataServer and to the managed MultiGrid (if any)
+			dataServer.addData(newElement);
+			if (managedGrid != null)
+				managedGrid.addGrid((WritableGrid) newElement);
+			return idx + 1;
+		} catch (RemoteException e) {
+			LOG
+					.error("RemoteExeception while trying to add a new element with idx "
+							+ idx + " to MultiData");
+		}
+		return 0;
+	}
+
+	/**
+	 * Manages a multigrid, which means that when a new element is added 
+	 * to the multiObject, then the same element is also added to 
+	 * the managed multiGrid.
+	 * 
+	 * @param toManageMultiGrid the grid to be managed. Only one grid will be 
+	 * managed at a time.
+	 *  
+	 */
+	public void setManagedGrid(MultiGrid toManageMultiGrid) {
+		this.managedGrid = toManageMultiGrid;
+	}
+
+	/**
+	 * @return the encapsulted {@link MultiDataInfo}
+	 */
+	public MultiDataInfo getMultiInfo() {
+		return this.multiDataInfo;
+	}
+
+	public String getName() {
+		return multiDataInfo.getName();
+	}
+
+	/**
+	 * removes the element with the specified index from the dataServer
+	 * 
+	 * @param idx the element
+	 */
+	public void deleteElement(int idx) {
+		checkIndex(idx);
+		try {
+			dataServer.removeData(multiDataInfo.getMultiID(idx));
+		} catch (RemoteException e) {
+			LOG.error("Could not reach DataServer" , e);
+			e.printStackTrace();
+		}	
+	}
+}

Added: trunk/src/appl/parallel/spmd/MultiDataPartitionObject.java
===================================================================
--- trunk/src/appl/parallel/spmd/MultiDataPartitionObject.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/MultiDataPartitionObject.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,58 @@
+package appl.parallel.spmd;
+
+import java.io.Serializable;
+import java.rmi.RemoteException;
+import java.util.Vector;
+
+import appl.parallel.client.DataServer;
+import appl.parallel.data.PartitionDataHandler;
+import appl.parallel.server.PartitionDataServer;
+import appl.parallel.server.PartitionDataManager;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.PartitionInfo;
+import appl.parallel.spmd.split.SinglePartitionInfo;
+
+/**
+ *  A extension of the {@link MultiDataObject} for storing {@link DataPartition DataPartitions}.
+ *    
+ * @author Dominik Appl
+ */
+public class MultiDataPartitionObject extends MultiDataObject {
+
+	private final PartitionDataServer partitionDataServer;
+	private final MultiDataInfo info;
+
+	public MultiDataPartitionObject(MultiDataInfo info, PartitionDataServer dataServer) {
+		super(info, dataServer);
+		this.info = info;
+		partitionDataServer = dataServer;
+	}
+
+	/**
+	 * Adds an element to the PartitionObject as {@link MultiDataObject} does. Also 
+	 * adds the needed {@link PartitionInfo} Object for the new Element
+	 * to the {@link PartitionDataServer}.
+	 * 
+	 * @return the index of the last element
+	 */
+	@Override
+	public int addElement() {
+		int lastIdx = super.addElement();
+		int newID = this.getMultiInfo().getMultiID(lastIdx);
+		//get PartitionInfo of the first grid and duplicate it
+		try {
+			SinglePartitionInfo partitionInfo = (SinglePartitionInfo) partitionDataServer.getPartitionInfo(info.getMultiID(0)).clone(newID);
+			//add the new PartitionInfo to the server
+			Vector<SinglePartitionInfo> partitionVector = new Vector<SinglePartitionInfo>();
+			partitionVector.add(partitionInfo);
+			partitionDataServer.addPartitionInfos(partitionVector);
+		} catch (RemoteException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		return lastIdx;
+	}
+	
+
+}

Added: trunk/src/appl/parallel/spmd/SPMDClientController.java
===================================================================
--- trunk/src/appl/parallel/spmd/SPMDClientController.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/SPMDClientController.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,946 @@
+package appl.parallel.spmd;
+
+import java.net.InetAddress;
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.Vector;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+import appl.data.DataLoader;
+import appl.ext.XuluConfig;
+import appl.parallel.ComputingResource;
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.ComputingResourceProperties;
+import appl.parallel.client.RemoteEventHandler;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.data.PartitionDataHandler;
+import appl.parallel.data.PartitionHandlerFactory;
+import appl.parallel.data.XuluClientLoader;
+import appl.parallel.event.CommEvent;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.event.TimeEvent;
+import appl.parallel.event.TimeMonitor;
+import appl.parallel.event.TransferEvent;
+import appl.parallel.event.TransferMonitor;
+import appl.parallel.event.CommEvent.CommType;
+import appl.parallel.server.PartitionDataServer;
+import appl.parallel.server.SPMDResource;
+import appl.parallel.spmd.split.AbstractSplitMap;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.SinglePartitionInfo;
+import appl.parallel.spmd.split.SplitMap;
+import appl.parallel.spmd.split.SplittableResource;
+import appl.parallel.spmd.split.AbstractSplitMap.NeighborhoodBoxingMode;
+import appl.parallel.thread.ComputingResourceThread;
+import appl.parallel.thread.DataServerThread;
+import appl.parallel.model.AbstractParallelStepModel;
+
+/**
+ * This class controls all the parallelization action on the client side and is
+ * the counterpart to {@link SPMDServerController}. It is accessed by the model
+ * developer by retrieving the {@link SPMDClientInterface} from the
+ * {@link AbstractParallelStepModel}.
+ *
+ * @author Dominik Appl
+ */
+public class SPMDClientController implements SPMDClientInterface {
+
+	/**
+	 * There are two states: <br>
+	 * <br>
+	 * <b>STATE.INIT</b> is the initializing state. In this state it is
+	 * allowed:<br>
+	 * to add resources to split control<br>
+	 * change neighborhodRange/boxing modes/reference resource<br>
+	 * <br>
+	 * All other methods are disabled and will throw
+	 * {@link UnsupportedOperationException}<br>
+	 * <br>
+	 * <b>STATE.RUN</b> is the running stage. All methods of {@link STATE#INIT}
+	 * are disabled and will throw {@link UnsupportedOperationException}. This
+	 * mode is automatically set by the first call to
+	 * {@link SPMDClientController#runSPMDModelTask(SPMDTask, Object...)}
+	 */
+	public enum STATE {
+		INIT, RUN
+	}
+
+	private STATE state = STATE.INIT;
+
+	private final String splitMapClassPropertyName = "Parallel.splitmapforclass";
+
+	private final Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	/**
+	 * participating servers
+	 */
+	private final SPMDResource[] servers;
+
+	private final ComputingResourceProperties[] serverInfos;
+
+	/**
+	 * stores the {@link PartitionDataServer DataServers} of the resources. They
+	 * are retrieved, after all resources are submitted to split control.
+	 */
+	private final PartitionDataServer[] dataServers;;
+
+	/**
+	 * number of partitions (== no of participating resources)
+	 */
+	private final int noOfPartitions;
+
+	/**
+	 * contains the {@link SinglePartitionInfo} of the
+	 * {@link SplittableResource splitted resources} for each server
+	 */
+	private final Vector<SinglePartitionInfo>[] singlePartitionInfos;
+
+	private final Vector<SinglePartitionInfo>[] toTransferPartitionInfos;
+
+	private HashMap<String, Object> toTransferBaseParameters;
+
+	private final HashMap<String, MultiDataInfo> multiDataInfos = new HashMap<String, MultiDataInfo>(
+			10);
+
+	private final HashMap<String, MultiDataInfo> toTransferMultiDataObjects = new HashMap<String, MultiDataInfo>(
+			10);
+
+	/** The IP-Addresses of the resources */
+	private String[] IPs;
+
+	/***************************************************************************
+	 * This Vector contains all IDs of the resources, which are currently under
+	 * splitControl
+	 *
+	 * @see #addToSplitControl(SplittableResource, String)
+	 * @see #mergePartition(SplittableResource)
+	 **************************************************************************/
+	private Vector<Integer> listOfAllActivelyControlledData = new Vector<Integer>();
+
+	/**
+	 * @see AbstractSplitMap.NeighborhoodBoxingMode
+	 */
+	private NeighborhoodBoxingMode boxingMode = AbstractSplitMap.NeighborhoodBoxingMode.inBoxing;
+
+	/** current neighborhood range, default is 0 */
+	private int neighborhoodRange = 0;
+
+	private final ClientDataServer spmdClient;
+
+	/**
+	 * Local calculation bounds on server side are calculated using the
+	 * reference resource This is the ID of that resource
+	 */
+	protected int referenceResourceID = -1;
+
+	/** Thread execution pool */
+	private final ExecutorService executor;
+
+	/** true if there is data which has to be transfered to the servers */
+	private boolean dataToTransfer = false;
+
+	private SplitMap splitMap;
+
+	private final CommEventSink eventProxy;
+
+	private final double[] weights;
+
+	/**
+	 * Creates a new Client controller.
+	 *
+	 * @param computingResources
+	 *            the resources which are used by this controller
+	 * @param spmdClient
+	 *            the spmd client responsible for the data retrieval
+	 * @param weights
+	 *            the weights for the distribution over the computing resources
+	 *            (values with a sum of 1) or null (distribution will be
+	 *            average)
+	 * @param eventProxy
+	 *            a {@link RemoteEventHandler} for eventHandling
+	 */
+	@SuppressWarnings("unchecked")
+	public SPMDClientController(
+			Vector<ComputingResourceContainer> computingResources,
+			double[] weights, ClientDataServer spmdClient,
+			CommEventSink eventProxy) {
+		if (weights == null)
+			weights = averageWeights(computingResources.size());
+		this.weights = weights;
+
+		this.eventProxy = eventProxy;
+		this.noOfPartitions = computingResources.size();
+		if (noOfPartitions == 0)
+			throw new UnsupportedOperationException(
+					"No Computing Ressources found");
+
+		this.spmdClient = spmdClient;
+		dataServers = new PartitionDataServer[noOfPartitions];
+		serverInfos = new ComputingResourceProperties[noOfPartitions];
+		servers = new SPMDResource[noOfPartitions];
+		for (int i = 0; i < computingResources.size(); i++) {
+			serverInfos[i] = computingResources.get(i).getInformation();
+			servers[i] = (SPMDResource) computingResources.get(i).getResource();
+
+		}
+		// extract the IPs
+		IPs = new String[noOfPartitions];
+		for (int i = 0; i < IPs.length; i++) {
+			IPs[i] = serverInfos[i].getIP();
+			IPs[i] = serverInfos[i].getPort() == null ? IPs[i] : IPs[i] + ":"
+					+ serverInfos[i].getPort();
+
+			if (IPs[i] == null)
+				LOG
+						.fatal("The IP-Information of a computingRessource was NULL. "
+								+ "This will result in failure of the computation!");
+		}
+
+		// initialize the singlePartitionInfos and tasks. Notice that the array
+		// singlePartitionInfos is final.
+		// Each vector of infos is permanently associated with one server.
+		this.singlePartitionInfos = new Vector[noOfPartitions];
+		this.toTransferPartitionInfos = new Vector[noOfPartitions];
+		this.toTransferBaseParameters = new HashMap<String, Object>();
+		for (int i = 0; i < noOfPartitions; i++) {
+			singlePartitionInfos[i] = new Vector<SinglePartitionInfo>();
+			toTransferPartitionInfos[i] = new Vector<SinglePartitionInfo>();
+		}
+
+		// initialize executor
+		executor = Executors.newCachedThreadPool();
+
+		// connect to all participating servers
+		connectAll();
+		// initialize DataServers (must be after connect)
+		for (int i = 0; i < noOfPartitions; i++)
+			try {
+				dataServers[i] = servers[i].createDataServer(IPs);
+			} catch (RemoteException e) {
+				LOG.fatal(e);
+				e.printStackTrace();
+			}
+	}
+
+	private double[] averageWeights(int noResources) {
+		// create weighted rating with the same weight
+		double[] weights = new double[noResources];
+		for (int i = 0; i < weights.length; i++) {
+			weights[i] = 1 / noResources;
+		}
+		return weights;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#addBaseParameter(java.lang.Object,
+	 *      java.lang.String)
+	 */
+	public void addBaseParameter(Object parameter, String parameterName) {
+		toTransferBaseParameters.put(parameterName, parameter);
+		dataToTransfer = true;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#addBaseParameters(java.lang.Object[],
+	 *      java.lang.String[])
+	 */
+	public void addBaseParameters(Object[] parameters, String[] parameterNames) {
+		for (int i = 0; i < parameterNames.length; i++) {
+			addBaseParameter(parameters[i], parameterNames[i]);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#addToMultiDataSplitControl(java.lang.Object[],
+	 *      java.lang.String)
+	 */
+	public MultiDataObject addToMultiDataSplitControl(
+			Object splittableResources[], String name) {
+		if (splittableResources.length == 0) {
+			throw new UnsupportedOperationException(
+					"There must be at least one resource to create a MultiData Element");
+		}
+		// Check if adding is allowed:
+		checkState(STATE.INIT);
+		SplittableResource[] resources = checkSplittableArray(splittableResources);
+
+		// add each element to splitcontrol. The constant gives each element a
+		// unique name and identifies it on the server side as belonging to a multisplit
+
+		MultiDataInfo multi = new MultiDataInfo(new int[0], name);
+		for (int i = 0; i < resources.length; i++) {
+			multi.addElement(resources[i].getRootID());
+			addToSplitControl(resources[i], MultiDataInfo.getNameWithIdx(i,
+					name));
+		}
+		toTransferMultiDataObjects.put(name, multi);
+		multiDataInfos.put(name, multi);
+		dataToTransfer = true;
+		return new MultiDataObject(multi, spmdClient);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#addToMultiDataSplitControl(edu.bonn.xulu.plugin.data.grid.MultiGrid,
+	 *      java.lang.String)
+	 */
+	public MultiDataObject addToMultiDataSplitControl(MultiGrid multiGrid,
+			String name) {
+		MultiDataObject dataObject = addToMultiDataSplitControl(multiGrid
+				.toArray(), name);
+		dataObject.setManagedGrid(multiGrid);
+		return dataObject;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#addToSplitControl(java.lang.Object,
+	 *      java.lang.String)
+	 */
+	public void addToSplitControl(Object splittableResource, String name) {
+
+		SplittableResource resource = checkSplittable(splittableResource);
+		// Check if adding is allowed:
+		checkState(STATE.INIT);
+		// if first call, than this is the reference for now - a map will be
+		// generated
+		if (referenceResourceID == -1)
+			setReferenceResource(resource);
+
+		// add the data to the SPMDClient for server retrieval
+		spmdClient.addData(resource);
+		// add the the resource to the controlled resources
+		listOfAllActivelyControlledData.add(resource.getRootID());
+		// make the singlePartitionInfos for each participating server and store
+		// the
+		// info for later use
+
+		SplitMap map = getSplitMap();
+		// create a partition info for each Server (only the
+		// splitMapPosition differs)
+		for (int i = 0; i < singlePartitionInfos.length; i++) {
+			PartitionDataHandler loader = PartitionHandlerFactory.newInstance(
+					resource.getRootID(), spmdClient,
+					map.getPartitionBounds(i), map
+							.getPartitionCalculationBounds(i));
+			SinglePartitionInfo info = new SinglePartitionInfo(resource
+					.getRootID(), name, loader, map, i);
+			singlePartitionInfos[i].add(info);
+			toTransferPartitionInfos[i].add(info);
+			dataToTransfer = true;
+		}
+	}
+
+	/**
+	 * Checks if the given object is an instance of {@link SplittableResource}
+	 * and gives it back as splittable.
+	 *
+	 * @param splittableResource
+	 * @throws UnsupportedOperationException
+	 *             if not instance of {@link SplittableResource}
+	 * @return the object as {@link SplittableResource}
+	 */
+	protected SplittableResource checkSplittable(Object splittableResource) {
+		if (!(splittableResource instanceof SplittableResource))
+			throw new UnsupportedOperationException(
+					"Operation failed: the argument for 'addToSplitControl' \n "
+							+ "must be an instance of SplittableResource! (like e.g. SplittableLLProxyGrid).\n "
+							+ "You can add non splittable Objects as Parameters of the SPMDTasks! For arrays"
+							+ "of SplittableResources use addToMultiSplitControl");
+		return (SplittableResource) splittableResource;
+	}
+
+	/**
+	 * checks if every object of the array is an instance of
+	 * {@link SplittableResource} and gives it back as splittable
+	 *
+	 * @param splittableResources
+	 *            an array of (hopefully)
+	 *            {@link SplittableResource SplittableResources}
+	 * @throws UnsupportedOperationException
+	 *             if not all elements are instances of
+	 *             {@link SplittableResource} or if the splitHeights or
+	 *             SplitWidths do not match
+	 * @return the object as {@link SplittableResource} array
+	 */
+	protected SplittableResource[] checkSplittableArray(
+			Object[] splittableResources) {
+		SplittableResource[] res = new SplittableResource[splittableResources.length];
+		for (int i = 0; i < splittableResources.length; i++) {
+			if (!(splittableResources[i] instanceof SplittableResource))
+				throw new UnsupportedOperationException(
+						"Operation failed: the argument must be an instance "
+								+ "of SplittableResource! (like e.g. SplittableLLProxyGrid).\n "
+								+ "You can add non splittable Objects as Parameters of the SPMDTasks!");
+			res[i] = (SplittableResource) splittableResources[i];
+		}
+		// check if the splitLengths match
+		if (res.length == 0)
+			return res;
+		int splitHeight = res[0].getSplitHeight();
+		int splitWidth = res[0].getSplitWidth();
+		for (SplittableResource resource : res) {
+			if (resource.getSplitHeight() != splitHeight
+					|| resource.getSplitWidth() != splitWidth)
+				throw new UnsupportedOperationException(
+						"Operation Failed: Splitvalues (height/width) of the array elements do not match!");
+		}
+		return res;
+	}
+
+	/**
+	 * Throws a {@link UnsupportedOperationException} if the state does not
+	 * match the required state
+	 *
+	 * @param requiredState
+	 *            the required state
+	 */
+	private void checkState(STATE requiredState) {
+		if (requiredState != state)
+			throw new UnsupportedOperationException(
+					"This Operation is not available: " + "You are in state"
+							+ state + " but you should be in state "
+							+ requiredState + ". See documentation of "
+							+ state.getClass().getName()
+							+ " for more information ");
+	}
+
+	/**
+	 * disconnects from all servers
+	 */
+	public void close() {
+		disconnectAll();
+	}
+
+	/**
+	 * connects to all servers
+	 */
+	@SuppressWarnings("unchecked")
+	private void connectAll() {
+		checkState(STATE.INIT);
+		long l = System.currentTimeMillis();
+		Future[] futureResults = new Future[servers.length];
+		for (int i = 0; i < servers.length; i++) {
+			futureResults[i] = executor.submit(new ComputingResourceThread(
+					servers[i], serverInfos[i], null, CommType.CONNECT,
+					eventProxy, true) {
+				public Object run() throws Exception {
+					getServer().connect();
+					return null;
+				}
+			});
+		}
+		try {
+			// wait for threads to finish
+			for (Future future : futureResults) {
+				future.get();
+			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		System.out.println("Connect time: " + (System.currentTimeMillis() - l)
+				+ " ms");
+	}
+
+	/**
+	 * disconnect from all servers
+	 */
+	private void disconnectAll() {
+		Future[] futureResults = new Future[servers.length];
+		for (int i = 0; i < servers.length; i++) {
+			futureResults[i] = executor.submit(new ComputingResourceThread(
+					servers[i], serverInfos[i], null, CommType.DISCONNECT,
+					eventProxy, true) {
+				public Object run() throws Exception {
+					getServer().disconnect();
+					return null;
+				}
+			});
+		}
+		try {
+			// wait threads to finish
+			for (Future future : futureResults) {
+				future.get();
+			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * @return the actual splitmap. The referenceResource must be set before
+	 *         call!
+	 */
+	private SplitMap getSplitMap() {
+		if (referenceResourceID == -1) {
+			LOG.error("NO MAP CREATED YET!");
+			return null;
+		} else
+			return splitMap;
+	}
+
+	/**
+	 * @return the current state
+	 */
+	public STATE getState() {
+		return state;
+	}
+
+	/**
+	 * Creates a {@link SplitMap} for the specified resource. Use
+	 * {@link #getSplitMap()} for retrieval.
+	 *
+	 * @param splittable
+	 *            the resource, for which the {@link SplitMap} is created
+	 */
+	private void makeSplitMap(SplittableResource splittable) {
+		SplitMap map = null;
+
+		// get splitMap implementation for this splittable from XuluConfig
+		String classname = XuluConfig.getXuluConfig().getProperty(
+				splitMapClassPropertyName + "."
+						+ splittable.getClass().getSimpleName());
+		// if no entry was found lookup default splitter
+		if (classname == null)
+			classname = XuluConfig.getXuluConfig().getProperty(
+					splitMapClassPropertyName + "." + "default");
+		try {
+			map = (SplitMap) Class.forName(classname).newInstance();
+			map.setParameters(splittable, neighborhoodRange, noOfPartitions,
+					boxingMode);
+			map.setWeights(weights);
+			map.makeMap();
+		} catch (Exception e) {
+			String error = "Could not create Splitmap from classname : '"
+					+ classname + "' out of property '"
+					+ splitMapClassPropertyName + "'. Nested errormessage is :"
+					+ e.getMessage();
+			LOG.fatal(error, e);
+			throw new UnsupportedOperationException(error);
+
+		}
+		this.splitMap = map;
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#mergeAllPartitions()
+	 */
+	@SuppressWarnings("unchecked")
+	public synchronized void mergeAllPartitions() {
+		// clone the list first, because mergePartition(int) removes elements
+		// from the list, which causes
+		// problems with the for-each loop
+		Vector<Integer> activeIDs = (Vector<Integer>) listOfAllActivelyControlledData
+				.clone();
+		// Vector<Future> futures = new Vector<Future>();
+		// for (Integer id : activeIDs) {
+		// futures.add(executor.submit(new DataServerThread(null, id) {
+		// public Object call() throws Exception {
+		// mergePartition(getIntArgument());
+		// return null;
+		// }
+		// }));
+		// }
+		// // wait on tasks to finish
+		// for (Future future : futures) {
+		// try {
+		// future.get();
+		// } catch (Exception e) {
+		// e.printStackTrace();
+		// }
+		//
+		// }
+		for (Integer id : activeIDs) {
+			mergePartition((int) id);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#mergeMultiData(appl.parallel.spmd.MultiDataObject)
+	 */
+	public synchronized void mergeMultiData(MultiDataObject multidata) {
+		// the problem is that perhaps on serverside grids were added, but not
+		// on client side. It is assumed that all servers have created the
+		// same number of grids with the same names (which is assured by
+		// multiDataInfo)
+
+		// first lookup the local multiData info and the info of any
+		// (here the first) dataserver multiInfo - as i said: all should be the
+		// same
+		MultiDataInfo localInfo = multidata.getMultiInfo();
+		String name = multidata.getName();
+		MultiDataInfo remoteInfo;
+		try {
+			// all remote infos should be the same, so it is enough to retrieve
+			// the first one
+			remoteInfo = dataServers[0].getMultiDataInfo(name);
+			if (localInfo == null || remoteInfo == null) {
+				LOG.error("Could not lookup MultidataInfo with name " + name
+						+ ". localInfo was " + localInfo + " remote info was "
+						+ remoteInfo);
+				return;
+			}
+			// merge the ids which are there on both sides:
+			int i = 0;
+			for (; i < localInfo.getCount(); i++)
+				mergePartition(localInfo.getMultiID(i));
+			// merge the new partitions
+			for (; i < remoteInfo.getCount(); i++) {
+				// get the new ID (the same as on server side)
+				int newID = remoteInfo.getMultiID(i);
+				// first create the new data element out of the first element in
+				// the list:
+				multidata.addElement(newID);
+				SplittableResource newResource = (SplittableResource) multidata
+						.getElement(multidata.getCount() - 1);
+				spmdClient.addData(newResource);
+				// now merge
+				mergePartition(newID);
+			}
+		} catch (RemoteException e) {
+			LOG.error("ERROR while trying to merge multi data: "
+					+ e.getMessage(), e);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#mergeMultiData(appl.parallel.spmd.MultiDataObject,
+	 *      int)
+	 */
+	public void mergeMultiData(MultiDataObject multidata, int idx) {
+		// the problem is that perhaps on serverside grids were added, but not
+		// on client side. It is assumed that all servers have created the
+		// same number of grids with the same names (which is assured by
+		// multiDataInfo)
+
+		// first lookup the local multiData info and the info of any
+		// (here the first) dataserver multiInfo - as i said: all should be the
+		// same
+		MultiDataInfo localInfo = multidata.getMultiInfo();
+		String name = multidata.getName();
+		MultiDataInfo remoteInfo;
+		try {
+			// all remote infos should be the same, so it is enough to retrieve
+			// the first one
+			remoteInfo = dataServers[0].getMultiDataInfo(name);
+			if (localInfo == null || remoteInfo == null) {
+				LOG.error("Could not lookup MultidataInfo with name " + name
+						+ ". localInfo was " + localInfo + " remote info was "
+						+ remoteInfo);
+				return;
+			}
+			// merge the grid with the given index
+			// for a local idx:
+			if (idx < localInfo.getCount())
+				mergePartition(localInfo.getMultiID(idx));
+			// else create a new grid
+			else {
+				// get the new ID (the same as on server side)
+				int newID = remoteInfo.getMultiID(idx);
+				if (newID == 0)
+					throw new UnsupportedOperationException(
+							"For the requested index (" + idx
+									+ ") was no grid found on the servers");
+				// first create the new data element out of the first element in
+				// the list:
+				multidata.addElement(newID);
+				SplittableResource newResource = (SplittableResource) multidata
+						.getElement(multidata.getCount() - 1);
+				spmdClient.addData(newResource);
+				// now merge the serverdata into the new clientgrid
+				mergePartition(newID);
+			}
+		} catch (RemoteException e) {
+			LOG.error("ERROR while trying to merge multi data: "
+					+ e.getMessage(), e);
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#mergePartition(int)
+	 */
+	public synchronized void mergePartition(int rootID) {
+		checkState(STATE.RUN);
+		Future[] futures = new Future[noOfPartitions];
+		for (int i = 0; i < noOfPartitions; i++)
+			futures[i] = executor.submit(new DataServerThread(dataServers[i],
+					serverInfos[i], rootID, CommType.CLIENT_MERGE, eventProxy) {
+				public Object run() throws Exception {
+					getServer().unloadToSource(getIntArgument());
+					return null;
+				}
+			});
+		// wait on tasks to finish:
+		try {
+			// wait threads to finish
+			for (Future future : futures) {
+				future.get();
+			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		listOfAllActivelyControlledData.remove((Integer) rootID);
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#mergePartition(java.lang.Object)
+	 */
+	public void mergePartition(Object splittableResource) {
+		checkSplittable(splittableResource);
+		checkState(STATE.RUN);
+		mergePartition(((SplittableResource) splittableResource).getRootID());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#runSPMDModelTask(appl.parallel.spmd.SPMDTask,
+	 *      java.lang.Object[])
+	 */
+	@SuppressWarnings("unchecked")
+	public Object[] runSPMDModelTask(final SPMDTask task, Object... parameters)
+			throws Throwable {
+		state = STATE.RUN;
+		// transfer needed data
+		if (dataToTransfer) {
+			transferDataToServers();
+		}
+		// submit task and arguments to the resources
+		// each task is calculated in its own thread;
+		// create tasks
+		parameters = (parameters == null) ? new Object[0] : parameters;
+		try {
+			Future futureResults[] = new Future[servers.length];
+			for (int i = 0; i < servers.length; i++) {
+				futureResults[i] = executor.submit(new ComputingResourceThread(
+						servers[i], serverInfos[i], new Object[] { task,
+								referenceResourceID, parameters },
+						CommType.CLIENT_EXECUTION, eventProxy) {
+					public Object run() throws Exception {
+						SPMDResource server = (SPMDResource) getServer();
+						return server.runSPMDModelTask(task.getClass()
+								.getName(),
+								(Integer) getObjectArrayArgument()[1],
+								(Object[]) getObjectArrayArgument()[2]);
+					}
+				});
+			}
+
+			Vector<Object> results = new Vector<Object>(15);
+
+			// aim of the next loop is to get single Object-array containing all
+			// results!
+			// Notice that every server result is a result array.
+			// This is because serverexecution can happen in multiple threads
+			// (when multiple processors are available) each serverthread will
+			// produce its own result
+			for (int i = 0; i < noOfPartitions; i++) {
+				// wait for threads finished and collect results
+				Object[] result = (Object[]) futureResults[i].get();
+				for (int j = 0; j < result.length; j++)
+					results.add(result[j]);
+			}
+			return results.toArray();
+
+		} catch (ExecutionException e) {
+			LOG.fatal("Error while trying to execute task "
+					+ task.getClass().getName() + ": " + e.getMessage(), e);
+			throw e.getCause();
+		} catch (Exception e) {
+			LOG.error("Error while trying to execute task "
+					+ task.getClass().getName() + ": " + e.getMessage(), e);
+			e.printStackTrace();
+		}
+		return null;
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#setBoxingMode(appl.parallel.spmd.split.AbstractSplitMap.NeighborhoodBoxingMode)
+	 */
+	public void setBoxingMode(AbstractSplitMap.NeighborhoodBoxingMode boxingMode) {
+		checkState(STATE.INIT);
+		this.boxingMode = boxingMode;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#setNeighborhoodRange(int)
+	 */
+	public void setNeighborhoodRange(int neighborhoodRange) {
+		checkState(STATE.INIT);
+		this.neighborhoodRange = neighborhoodRange;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#setReferenceResource(java.lang.Object)
+	 */
+	public void setReferenceResource(Object splittableResource) {
+		checkSplittable(splittableResource);
+		SplittableResource res = (SplittableResource) splittableResource;
+		checkState(STATE.INIT);
+		if (res instanceof SplittableResource) {
+			referenceResourceID = res.getRootID();
+			makeSplitMap(res);
+		} else
+			LOG
+					.warn("Set reference failed: given resource was not an instance of SplittableResource!");
+
+	}
+
+	/**
+	 * transfers all collected data to the servers. (The data is collected to
+	 * save communication time)
+	 */
+	private void transferDataToServers() {
+		long time = System.currentTimeMillis();
+		Vector<Future> futures = new Vector<Future>();
+		if (toTransferPartitionInfos[0].size() > 0)
+			for (int i = 0; i < servers.length; i++) {
+				futures.add(executor.submit(new DataServerThread(
+						dataServers[i], serverInfos[i],
+						toTransferPartitionInfos[i],
+						CommType.TRANSFER_METADATA, eventProxy, true) {
+					public Object run() throws Exception {
+						getServer()
+								.addPartitionInfos(
+										(Vector<SinglePartitionInfo>) getObjectArgument());
+						return null;
+					}
+				}));
+			}
+		if (toTransferMultiDataObjects.size() > 0)
+			for (int i = 0; i < servers.length; i++) {
+				futures.add(executor.submit(new DataServerThread(
+						dataServers[i], serverInfos[i],
+						toTransferMultiDataObjects, CommType.TRANSFER_METADATA,
+						eventProxy, true) {
+					public Object run() throws Exception {
+						getServer()
+								.addMultiDataInfos(
+										(HashMap<String, MultiDataInfo>) getObjectArgument());
+						return null;
+					}
+				}));
+			}
+		if (toTransferBaseParameters.size() > 0)
+			for (int i = 0; i < servers.length; i++) {
+				futures.add(executor.submit(new DataServerThread(
+						dataServers[i], serverInfos[i],
+						toTransferBaseParameters, CommType.TRANSFER_PARAMETERS,
+						eventProxy) {
+					public Object run() throws Exception {
+						getServer().updateBaseParameter(
+								(HashMap) getObjectArgument());
+						return null;
+					}
+				}));
+			}
+		// wait on threads to finish
+		for (Future future : futures) {
+			try {
+				future.get();
+			} catch (InterruptedException e) {
+				LOG.error(e);
+				e.printStackTrace();
+			} catch (ExecutionException e) {
+				LOG.error(e);
+				e.printStackTrace();
+			}
+		}
+		dataToTransfer = false;
+		toTransferBaseParameters.clear();
+		toTransferBaseParameters.clear();
+		toTransferMultiDataObjects.clear();
+		if (LOG.isDebugEnabled())
+			LOG.debug("Transfered Data to clients in "
+					+ (System.currentTimeMillis() - time) / 1000000 + " ms");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#updateNeighborhood(java.lang.Object)
+	 */
+	public void updateNeighborhood(Object splittableResource) {
+		checkSplittable(splittableResource);
+		SplittableResource res = (SplittableResource) splittableResource;
+		updateNeighborhood(res.getRootID());
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see appl.parallel.spmd.SPMDClientInterface#updateNeighborhood(appl.parallel.spmd.MultiDataObject,
+	 *      int)
+	 */
+	public void updateNeighborhood(MultiDataObject multiDataObject, int index) {
+		this.updateNeighborhood(multiDataObject.getMultiInfo()
+				.getMultiID(index));
+	}
+
+	/**
+	 * updates the neighborhood of the splittable with the given id on the
+	 * servers
+	 */
+	private void updateNeighborhood(int rootID) {
+		checkState(STATE.RUN);
+		Future[] futureResults = new Future[servers.length];
+		for (int i = 0; i < servers.length; i++) {
+			futureResults[i] = executor.submit(new DataServerThread(
+					dataServers[i], serverInfos[i], rootID,
+					CommType.CLIENT_UPDATE, eventProxy) {
+				public Object run() throws Exception {
+					getServer().updateFromNeighbors(getIntArgument());
+					return null;
+				}
+			});
+		}
+		try {
+			// wait threads to finish
+			for (Future future : futureResults) {
+				future.get();
+			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+}

Added: trunk/src/appl/parallel/spmd/SPMDClientInterface.java
===================================================================
--- trunk/src/appl/parallel/spmd/SPMDClientInterface.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/SPMDClientInterface.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,245 @@
+package appl.parallel.spmd;
+
+import appl.parallel.ComputingResource;
+import appl.parallel.spmd.split.AbstractSplitMap;
+import appl.parallel.spmd.split.SplitMap;
+import appl.parallel.spmd.split.SplittableResource;
+import appl.parallel.spmd.split.AbstractSplitMap.NeighborhoodBoxingMode;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+/**
+ * Using this interface the programmer can access the parallel functionality.
+ *
+ * @author Dominik Appl
+ */
+public interface SPMDClientInterface {
+
+	/**
+	 * <code>Base Parameters</code> are Objects which are used during the
+	 * execution of multiple {@link SPMDTask SPMD-Tasks}. They are transfered
+	 * to each of the participating
+	 * {@link ComputingResource computing resources} but are not synchronized
+	 * with the client and of course in no way splitted. <br>
+	 * <br>
+	 * <b>Notice:</b> For efficient transport it is recommended that multiple
+	 * parameters are transfered at once. To do this use the
+	 * {@link #addBaseParameters(Object[], String[])} method.
+	 *
+	 * @param parameter
+	 * @param parameterName
+	 * @see SPMDServerController
+	 */
+	public void addBaseParameter(Object parameter, String parameterName);
+
+	/**
+	 * Adds multiple Base-parameters at once. Notice that this is only for
+	 * convenience and has no performance advantages over
+	 * {@link #addBaseParameter(Object, String)}.
+	 *
+	 * @param parameters
+	 *            an array of parameters
+	 * @param parameterNames
+	 *            an array of names. The indexes of parameters and parameter
+	 *            names must of course match
+	 */
+	public void addBaseParameters(Object[] parameters, String[] parameterNames);
+
+	/**
+	 * All resources of the array are submitted to split-control. This means
+	 * they are (virtually) split and send (virtually) to the participating
+	 * computing units. The partitions can be requested on server side using the
+	 * {@link SPMDServerController#getMultiData(String)} method. It is assumed,
+	 * that all resources have the same Dimension. The same {@link SplitMap} and
+	 * splitmap Position is used for all elements. used for every element.
+	 *
+	 * @param splittableResources
+	 *            the resource to be splitted
+	 * @param name
+	 *            the name of the resource
+	 * @return the multi-data object can be used for adding elements to the
+	 *         multi data
+	 * @see SPMDServerController
+	 * @throws UnsupportedOperationException
+	 *             if splitHeight and splitWidth of the resouces does not match
+	 */
+	public MultiDataObject addToMultiDataSplitControl(
+			Object splittableResources[], String name);
+
+	/**
+	 * This method is specialized on handling MultiGrids. In principle the
+	 * {@link #addToMultiDataSplitControl(Object[], String)} could be used, but
+	 * using this method won't handle updates to the MultiGrid required for
+	 * correct display in the XuluModellingPlatform. <p/>
+	 * The elements of the Multigrid are split and send to the participating
+	 * computing units. The partitions can be requested on server side using the
+	 * {@link SPMDServerController#getMultiData(String)} method. It is assumed,
+	 * that all resources have the same Dimension. The same {@link SplitMap} and
+	 * splitmap position is used for all elements.
+	 * 
+	 * @param name
+	 *            the name of the resource
+	 * @return the multi-data object can be used for adding elements to the
+	 *         multi data
+	 * @see SPMDServerController
+	 * @throws UnsupportedOperationException
+	 *             if splitHeight and splitWidth of the resources does not match
+	 */
+	public MultiDataObject addToMultiDataSplitControl(MultiGrid multiGrid,
+			String name);
+
+	/**
+	 * The resource is submitted to splitControl. This means it is virtually
+	 * split and send virtually to the participating computing units. The
+	 * partitions can be requested on server side using the
+	 * {@link SPMDServerController#getPartition(String)} method. <br>
+	 * <br>
+	 * <i>What does "virtually" mean? </i>Well what really happens is that the
+	 * metadata is stored. When
+	 * {@link #runSPMDModelTask(SPMDTask, Object[]) runSPMDModelTask} is run
+	 * next time, the <b>metadata</b> (and all
+	 * {@link #addBaseParameter(Object, String)  base Parameters} btw.) are
+	 * Transfered to the servers. <br>
+	 * The "real" splitting will happen implicit, i.e. the participating servers
+	 * will request the correct partition.
+	 *
+	 * @param splittableResource
+	 *            the resource to be splitted
+	 * @param name
+	 *            a name for the resource (you will be able to request the
+	 *            resource on server side using this name)
+	 * @see SPMDServerController
+	 */
+	public void addToSplitControl(Object splittableResource, String name);
+
+	/**
+	 * Merges all the partitions from the server into the sources, from which
+	 * the objects were loaded (which may be the Xulu-Client, but may also be a
+	 * database or an other location if this feature is implemented).
+	 *
+	 * @see #mergeAllPartitions()
+	 * @see #addToSplitControl(Object, String)
+	 */
+	public void mergeAllPartitions();
+
+	/**
+	 * Merges all elements of the specified multidata object
+	 *
+	 * @param multidata
+	 *            the multidata to merge
+	 */
+	public void mergeMultiData(MultiDataObject multidata);
+
+	/**
+	 * Merges the element at the specified index
+	 *
+	 * @param multidata
+	 *            the multidata object containing the element to merge
+	 * @param idx
+	 *            the position of the element to merge
+	 */
+	public void mergeMultiData(MultiDataObject multidata, int idx);
+
+	/**
+	 * The counterpart of {@link #addToSplitControl(Object, String)}.
+	 * Merges the partitions from the server into the sources, from which the
+	 * objects were loaded (which will be the Xulu-Client in most cases, but may
+	 * also be a database at an other location if this feature is implemented).
+	 * Uses multithreading.
+	 *
+	 * @param rootID
+	 *            the ID of the source to be merged.
+	 * @see #mergeAllPartitions()
+	 * @see #addToSplitControl(Object, String)
+	 */
+	public void mergePartition(int rootID);
+
+	/**
+	 * The counterpart of {@link #addToSplitControl(Object, String)}.
+	 * Merges the partitions from the server into the sources, from which the
+	 * objects were loaded (which will be the Xulu-Client in most cases, but may
+	 * also be a database at an other location if this feature is implemented).
+	 * Use {@link #mergeAllPartitions()} to merge all partitions at once.
+	 *
+	 * @param splittableResource
+	 *            the resource to be merged. (must be an instance of
+	 *            {@link SplittableResource}
+	 * @see #mergeAllPartitions()
+	 * @see #addToSplitControl(Object, String)
+	 */
+	public void mergePartition(Object splittableResource);
+
+	/**
+	 * Run the given task on with the given parameters. The result is a Object
+	 * array with results from all participating servers. The number of elements
+	 * can therefore vary in different executions (using different numbers of
+	 * servers)
+	 *
+	 * @param task
+	 *            the task to be submitted. There may be certain restrictions of
+	 *            the task to be submitted.
+	 * @param parameters
+	 * @return All results are combined in one array. Should a server not return
+	 *         a result, the parallel programmer is responsible for handling
+	 *         <code>null</code> values inside the array.
+	 * @throws Throwable
+	 *             the Exceptions thrown on serverside!
+	 */
+	public Object[] runSPMDModelTask(SPMDTask task, Object... parameters)
+			throws Throwable;
+
+	/**
+	 * Here you can set the boxing mode. See {@link NeighborhoodBoxingMode}
+	 *
+	 * @param boxingMode
+	 *            the boxing mode
+	 */
+	public void setBoxingMode(AbstractSplitMap.NeighborhoodBoxingMode boxingMode);
+
+	/**
+	 * Sets the neighborhood range. From now on every splitting is done with the
+	 * given range. In most cases it should be called before any resources are
+	 * add to split control.
+	 *
+	 * @param neighborhoodRange
+	 *            the width of the neighborhood range (in cells)
+	 */
+	public void setNeighborhoodRange(int neighborhoodRange);
+
+	/**
+	 * All local bounds are calculated on server side using the reference
+	 * resource. If {@link SplittableResource splittable resources} of different
+	 * sizes or with different {@link SplitMap SplitMaps} are used, it is
+	 * possible to get the local bounds of an special resource using the
+	 * {@link SPMDServerController#getLocalCalculationBounds(appl.parallel.spmd.split.DataPartition)}
+	 * method of the SPMDServerController. <br>
+	 * <br>
+	 * If no reference resource is set, than the first call to
+	 * {@link #addToSplitControl(Object, String)} will set the reference.
+	 *
+	 * @param splittableResource
+	 *            the new reference resource (must be an instance of
+	 *            {@link SplittableResource})
+	 */
+	public void setReferenceResource(Object splittableResource);
+
+	/**
+	 * Signals to all participating servers to update the neighborhood and waits
+	 * until the update is finished.
+	 *
+	 * @param splittableResource
+	 *            (must be an instance of {@link SplittableResource}
+	 */
+	public void updateNeighborhood(Object splittableResource);
+
+	/**
+	 * Signals to all participating servers to update the neighborhood and waits
+	 * until the update is finished.
+	 *
+	 * @param multiDataObject
+	 *            the {@link MultiDataObject} to be updated
+	 * @param index
+	 *            the index of the partition to be updated
+	 */
+	public void updateNeighborhood(MultiDataObject multiDataObject, int index);
+
+}

Added: trunk/src/appl/parallel/spmd/SPMDServerController.java
===================================================================
--- trunk/src/appl/parallel/spmd/SPMDServerController.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/SPMDServerController.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,225 @@
+package appl.parallel.spmd;
+
+import java.awt.Rectangle;
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.Vector;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.parallel.ComputingResource;
+import appl.parallel.client.DataServer;
+import appl.parallel.data.WritableGridArrayPartition;
+import appl.parallel.model.AbstractParallelStepModel;
+import appl.parallel.server.PartitionDataManager;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.PartitionInfo;
+import appl.parallel.spmd.split.SplitMap;
+import appl.parallel.spmd.split.SplittableResource;
+
+/**
+ * This class controls all the parallelization action on the server side and is
+ * the counterpart to {@link SPMDClientController}. It is accessed by the model
+ * developer by retrieving the {@link SPMDServerInterface} from a
+ * {@link SPMDTask}.
+ * 
+ * @author Dominik Appl
+ */
+public class SPMDServerController implements SPMDServerInterface {
+
+	private Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	PartitionDataManager dataManager;
+	
+	private Rectangle localCalculationBounds;
+
+	private final SplitMap referenceSplitMap;
+
+	/**
+	 * the partition position (used for splitmaps)
+	 */
+	protected final int mapPosition;
+	
+	/**
+	 * Creates a new instance 
+	 * @param dataManager the partition data server responsible for managing the data on the server
+	 * @param referenceResouceID the id of the reference resource
+	 */
+	public SPMDServerController(PartitionDataManager dataManager,
+			int referenceResouceID) {
+		this.dataManager = dataManager;
+		// if there are any partitions the referenceID should be != -1
+		if (referenceResouceID != -1) {
+			referenceSplitMap = dataManager.getInfo(referenceResouceID)
+					.getSplitMap();
+			mapPosition = dataManager.getInfo(referenceResouceID)
+					.getSplitMapPos();
+		} else {
+			referenceSplitMap = null;
+			mapPosition = 0;
+		}
+		//setting the calculation bounds to the default area
+		localCalculationBounds=referenceSplitMap.getLocalCalculationBounds(mapPosition);
+	}
+	
+	/**
+	 * This method sets new calculation bounds. This is used to divide the rasters for 
+	 * parallel computation on one machine (using multiple cpu's or cpu cores)
+	 * 
+	 * @param newBounds the new calculation bounds
+	 */
+	public void setLocalCalculationBounds(Rectangle newBounds){
+		localCalculationBounds = newBounds;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getBaseParameter(java.lang.String)
+	 */
+	public Object getBaseParameter(String parameterName) {
+		Object returnValue =  dataManager.getBaseParameter(parameterName);
+		 if(returnValue==null)
+			 LOG.warn("No value for parameter '" + parameterName + "' found or value was null" );
+		 return returnValue;
+	}
+
+		
+
+	
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getLocalCalculationBounds(appl.parallel.spmd.split.DataPartition)
+	 */
+	public Rectangle getLocalCalculationBounds(DataPartition partition) {
+		return dataManager.getInfo(partition.getRootID()).getSplitMap()
+				.getLocalCalculationBounds(mapPosition);
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getLocalBounds(appl.parallel.spmd.split.DataPartition)
+	 */
+	public Rectangle getLocalBounds(DataPartition partition) {
+		PartitionInfo info = dataManager.getInfo(partition.getRootID());
+		return info.getSplitMap().getLocalBounds(mapPosition);
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getGlobalBounds(appl.parallel.spmd.split.DataPartition)
+	 */
+	public Rectangle getGlobalBounds(DataPartition partition) {
+		PartitionInfo info = dataManager.getInfo(partition.getRootID());
+		return info.getSplitMap().getGlobalBounds();
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getLocalCalculationBounds()
+	 */
+	public Rectangle getLocalCalculationBounds() {
+		return localCalculationBounds;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getLocalBounds()
+	 */
+	public Rectangle getLocalBounds() {
+		return referenceSplitMap.getLocalBounds(mapPosition);
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getPartition(java.lang.String)
+	 */
+	public DataPartition getPartition(String name) {
+		DataPartition partition = dataManager.getData(name);
+		if (partition == null)
+			LOG.error("ERROR: The Partition with the name '" + name
+							+ "' was not found or was null");
+		return partition;
+	}
+	
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getMultiPartition(java.lang.String)
+	 */
+	public DataPartition[] getMultiPartition(String name) {
+		DataPartition[] partitions = dataManager.getMultiData(name);
+		if (partitions == null)
+			LOG.error("ERROR: The Partition with the name '" + name
+							+ "' was not found or was null");
+//		if(partitions.length>0)
+//		  if(partitions[0] instanceof WritableGridArrayPartition.Float){
+//			WritableGridArrayPartition[] wgPartitions = new WritableGridArrayPartition[partitions.length];
+//			System.arraycopy(partitions, 0, wgPartitions, 0, partitions.length);
+//			return (DataPartition[]) wgPartitions;
+//		  }
+		return partitions;
+	}
+	
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getMultiData(java.lang.String)
+	 */
+	public MultiDataObject getMultiData(String name){
+		MultiDataObject multiDataObject=null;
+		try {
+			multiDataObject = dataManager.getMultiDataObject(name);
+			if(multiDataObject==null)
+				LOG.warn("No Multidataobject with name '"  + name + "' found. Returning null!");
+		} catch (RemoteException e) {
+			// Should never be be called (local call)
+			e.printStackTrace();
+		}
+		return multiDataObject;
+	}
+	
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getMultiPartition(java.lang.String, int)
+	 */
+	public DataPartition getMultiPartition(String name, int idx) {
+		DataPartition partition = dataManager.getMultiData(name,idx);
+		if (partition == null)
+			LOG.error("ERROR: The Partition with the name '" + name
+							+ "' was not found or was null");
+		return partition;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getLocalCalcMinX()
+	 */
+	public int getLocalCalcMinX() {
+		return (int) getLocalCalculationBounds().getX();
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getLocalCalcMinY()
+	 */
+	public int getLocalCalcMinY() {
+		return (int) getLocalCalculationBounds().getY();
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getLocalCalcMaxX()
+	 */
+	public int getLocalCalcMaxX() {
+		return (int) (getLocalCalculationBounds().getX()
+				+ getLocalCalculationBounds().getWidth() - 1);
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#getLocalCalcMaxY()
+	 */
+	public int getLocalCalcMaxY() {
+		return (int) (getLocalCalculationBounds().getY()
+				+ getLocalCalculationBounds().getHeight() - 1);
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDServerInterface#destroyData(java.lang.Object)
+	 */
+	public void destroyPartition(String name) {
+		dataManager.removeData(name);
+	}
+	
+	public void destroyMultiPartition(String name,int idx)
+	{
+		MultiDataObject multiData = this.getMultiData(name);
+		multiData.deleteElement(idx);
+	}
+
+}

Added: trunk/src/appl/parallel/spmd/SPMDServerInterface.java
===================================================================
--- trunk/src/appl/parallel/spmd/SPMDServerInterface.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/SPMDServerInterface.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,207 @@
+package appl.parallel.spmd;
+
+import java.awt.Rectangle;
+import java.util.HashMap;
+
+import edu.bonn.xulu.plugin.data.grid.GridList;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+
+import appl.parallel.ComputingResource;
+import appl.parallel.spmd.split.DataPartition;
+import appl.parallel.spmd.split.SplittableResource;
+
+/**
+ * Using this interface the programmer can access the parallel functionality on server side.
+ * The programmer should subclass {@link AbstractSPMDTask} and use its method {@link AbstractSPMDTask#getSPMDServerController()} to
+ * access the parallel control.
+ * @author Dominik Appl
+ */
+public interface SPMDServerInterface {
+
+	/**
+	 * Returns the base parameter with the specified id.
+	 *
+	 * @param parameterName the name of the parameter specified on client side
+	 * @return the base parameter
+	 *
+	 * @see SPMDClientInterface#addBaseParameter(Object, String)
+	 */
+	public Object getBaseParameter(String parameterName);
+
+	/**
+	 * Gives back the area which is actively used for read/write (in contrast
+	 * to neighborhood area, which is often accessed will be accessed read only).
+	 *
+	 * @param partition
+	 *            a partition for which the the bounds are requested
+	 * @return the calculation bounds in local coordinates (local means relative
+	 *         to the upper left corner of all available data)
+	 */
+	public Rectangle getLocalCalculationBounds(DataPartition partition);
+
+	/**
+	 * Gives back the area which is available for local access (including
+	 * Neighborhood)
+	 *
+	 * @param partition
+	 *            a partition for which the the bounds are requested
+	 * @return the calculation bounds in local coordinates - the upper left
+	 *         corner of the {@link Rectangle} will be (0,0)
+	 */
+	public Rectangle getLocalBounds(DataPartition partition);
+
+	/**
+	 * Gives back the global bounds, which are the bounds of all partitions over all servers.
+	 * To be clear: This are the bounds of the unsplitted data!
+	 * @param partition partition for which the bounds are queried
+	 * @return the global bounds
+	 */
+	public Rectangle getGlobalBounds(DataPartition partition);
+
+	/**
+	 * Gives back the area which is actively used for read/write (in contrast
+	 * to neighborhood area, which is often accessed will be accessed read only).
+	 *
+	 * @return the calculation bounds in local coordinates (local means relative
+	 *         to the upper left corner of all available data) of the reference
+	 *         resource (which is the first resource added to split-control on
+	 *         client side)
+	 *
+	 * @see SPMDClientController#addToSplitControl(Object, String)
+	 * @see SPMDClientController#setReferenceResource(Object)
+	 */
+	public Rectangle getLocalCalculationBounds();
+
+	/**
+	 * Gives back the area which is available for local access (including
+	 * Neighborhood)
+	 *
+	 * @return the calculation bounds in local coordinates of the reference
+	 *         resource (which is the first resource added to split-control on
+	 *         client side) - the upper left corner of the {@link Rectangle}
+	 *         will be (0,0)
+	 * @see SPMDClientController#addToSplitControl(Object, String)
+	 * @see SPMDClientController#setReferenceResource(Object)
+	 */
+	public Rectangle getLocalBounds();
+
+	/**
+	 * The whole {@link DataPartition} available for this task. In contrast to
+	 * {@link #getLocalCalculationBounds()} the neighborhood is included!
+	 *
+	 * @param name
+	 *            the name of the splittable
+	 * @return the partition of the resource which is available for local
+	 *         calculation
+	 * @see SPMDClientController#addToSplitControl(Object, String)
+	 */
+	public DataPartition getPartition(String name);
+
+	/**
+	 * Gets the array of {@link DataPartition DataPartitions} which were
+	 * submitted on client side via
+	 * {@link SPMDClientController#addToMultiDataSplitControl(Object[], String)}
+	 * All resources are retrieved from the data source and given back. If you
+	 * only need a specific resource you can use
+	 * {@link #getMultiPartition(String, int)} to avoid loading all data.
+	 *
+	 * @param name
+	 *            the name of the splittable
+	 * @return the partition of the resource which is available for local
+	 *         calculation
+	 * @see SPMDClientController#addToMultiDataSplitControl(Object[], String)
+	 * @see #getMultiPartition(String, int)
+	 */
+	public DataPartition[] getMultiPartition(String name);
+
+	/**
+	 * Gives back a MultiDataObject. A MultiDataObject can encapsulate multiple
+	 * objects and is especially intended for use with {@link GridList} and
+	 * {@link MultiGrid} types. See {@link MultiDataObject} for more details.
+	 *
+	 * @param name the name associated with the object on client side
+	 * @return the MDO
+	 */
+	public MultiDataObject getMultiData(String name);
+
+	/**
+	 * Gets a {@link DataPartition} which was submitted on client side via
+	 * {@link SPMDClientController#addToMultiDataSplitControl(Object[], String)}.
+	 * Only the grid with the index is returned. All other partitions are NOT
+	 * retrieved.
+	 *
+	 * @param name
+	 *            the name of the splittable
+	 * @param idx
+	 * @return the partition of the resource which is available for local
+	 *         calculation
+	 * @see SPMDClientController#addToMultiDataSplitControl(Object[], String)
+	 * @see #getMultiPartition(String)
+	 */
+	public DataPartition getMultiPartition(String name, int idx);
+
+	/**
+	 * Convenience method. Gets the coordinate out from the Rectangle which the
+	 * {@link #getLocalCalculationBounds()} returns
+	 *
+	 * @return the x-coordinate upperleft corner of the calcarea
+	 * @see SPMDServerController#getLocalCalculationBounds()
+	 * @see SPMDServerController#getLocalCalcMinX()
+	 * @see SPMDServerController#getLocalCalcMaxX()
+	 * @see SPMDServerController#getLocalCalcMinY()
+	 * @see SPMDServerController#getLocalCalcMaxY()
+	 */
+	public int getLocalCalcMinX();
+
+	/**
+	 * Convenience method. Gets the coordinate out from the Rectangle which the
+	 * {@link #getLocalCalculationBounds()} returns
+	 *
+	 * @return the y-coordinate upper left corner of the calculation area
+	 * @see SPMDServerController#getLocalCalculationBounds()
+	 * @see SPMDServerController#getLocalCalcMinX()
+	 * @see SPMDServerController#getLocalCalcMaxX()
+	 * @see SPMDServerController#getLocalCalcMinY()
+	 * @see SPMDServerController#getLocalCalcMaxY()
+	 */
+	public int getLocalCalcMinY();
+
+	/**
+	 * Convenience method. Gets the coordinate out from the Rectangle which the
+	 * {@link #getLocalCalculationBounds()} returns
+	 *
+	 * @return the x-coordinate lower right corner of the calculation area
+	 * @see SPMDServerController#getLocalCalculationBounds()
+	 * @see SPMDServerController#getLocalCalcMinX()
+	 * @see SPMDServerController#getLocalCalcMaxX()
+	 * @see SPMDServerController#getLocalCalcMinY()
+	 * @see SPMDServerController#getLocalCalcMaxY()
+	 */
+	public int getLocalCalcMaxX();
+
+	/**
+	 * Convenience method. Gets the coordinate out from the Rectangle which the
+	 * {@link #getLocalCalculationBounds()} returns
+	 *
+	 * @return the y-coordinate lower right corner of the calculation area
+	 * @see SPMDServerController#getLocalCalculationBounds()
+	 * @see SPMDServerController#getLocalCalcMinX()
+	 * @see SPMDServerController#getLocalCalcMaxX()
+	 * @see SPMDServerController#getLocalCalcMinY()
+	 * @see SPMDServerController#getLocalCalcMaxY()
+	 */
+	public int getLocalCalcMaxY();
+
+	/**
+	 * Removes the partition from memory. You may want to call {@link System#gc()} afterwards
+	 * @param name the name of the partition to remove
+	 */
+	public void destroyPartition(String name);
+
+	/**
+	 * Removes the partition from memory. You may want to call {@link System#gc()} afterwards
+	 * @param name the name of the multidata
+	 * @param idx the index of the partition to remove
+	 */
+	public void destroyMultiPartition(String name,int idx);
+}

Added: trunk/src/appl/parallel/spmd/SPMDTask.java
===================================================================
--- trunk/src/appl/parallel/spmd/SPMDTask.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/SPMDTask.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,89 @@
+package appl.parallel.spmd;
+
+import java.awt.Rectangle;
+import java.io.Serializable;
+
+import appl.parallel.server.XuluServer;
+
+import schmitzm.data.WritableGrid;
+
+/**
+ * A SPMDTask should be executed on servers using the SPMD-paradigm. 
+ * <br>
+ * The Task provides access to the {@link SPMDClientInterface} and the
+ * {@link AdvancedSPMDClientInterface}. <br>
+ * <br>
+ * @see AbstractSPMDTask for more details
+ * 
+ * @author Dominik Appl
+ */
+public interface SPMDTask extends Serializable {
+
+	/**
+	 * Gives access the {@link AdvancedSPMDServerInterface} for advanced parallel
+	 * programming, including performance optimizations like preloading.
+	 * @return the interface
+	 */
+	public AdvancedSPMDServerInterface getAdvancedSPMDServerController();
+
+	/**
+	 * Gives access the {@link SPMDServerInterface} for parallel programming.
+	 * 
+	 * @return the interface
+	 */
+	public SPMDServerInterface getSPMDServerController();
+
+	/**
+	 * Associates the given SPMDController with the task. Will be called e.g. by
+	 * the {@link XuluServer}.
+	 * 
+	 * @param controller
+	 */
+	public void setSPMDServerController(AdvancedSPMDServerInterface controller);
+
+	/**
+	 * Currently not used. May be used later when introducing write access on
+	 * neighborhood regions.
+	 * 
+	 * @param incomingGrid
+	 * @param location
+	 */
+	public void outgoingUpdate(WritableGrid incomingGrid, Rectangle location);
+
+	/**
+	 * Currently not used. May be used later when introducing write access on
+	 * neighborhood regions.
+	 * 
+	 * @param outgoingGrid
+	 * @param location
+	 */
+	public void incomingUpdate(WritableGrid outgoingGrid, Rectangle location);
+
+	/**
+	 * Starts the task with the given parameters. Overwrite this method to
+	 * implement the task.
+	 * 
+	 * @param parameters
+	 * @return the result of the task computation (if any)
+	 */
+	public Object run(Object... parameters);
+
+	/**
+	 * Initializes the task. Initializing is only done once!
+	 */
+	public void initialize();
+
+	/**
+	 * @return whether the task is initialized or {@link #initialize()} must be
+	 *         called
+	 */
+	public boolean isInitialized();
+
+	/**
+	 * If you want to support multiple processors, this method must return true.
+	 * 
+	 * @return whether multithreading can be used by this task
+	 */
+	public boolean supportsMultiThreading();
+
+}

Added: trunk/src/appl/parallel/spmd/SyncPoint.java
===================================================================
--- trunk/src/appl/parallel/spmd/SyncPoint.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/SyncPoint.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,91 @@
+package appl.parallel.spmd;
+
+/**
+ * Specifies details about a synchronization point. These points are used in
+ * the {@link AdvancedSPMDClientController} or {@link AdvancedSPMDServerController}
+ * as preloading-Points or multithread-barriers. They are associated with a priority. 
+ * 
+ * @author Dominik Appl
+ */
+public class SyncPoint {
+	
+	/**
+	 * A high priority means a high priority on operating system level. It should
+	 * be used by implementations of {@link AdvancedSPMDClientController} and {@link AdvancedSPMDServerController}
+	 * 
+	 * @author Dominik Appl
+	 */
+	public enum Priority
+	{
+		LOW(Thread.MIN_PRIORITY),
+		BELOW_NORMAL(Thread.NORM_PRIORITY-1),
+		NORMAL(Thread.NORM_PRIORITY),
+		ABOVE_NORMAL(Thread.NORM_PRIORITY+1),
+		HIGH(Thread.MAX_PRIORITY);
+		
+		private final int realPriorityNo;
+		
+		Priority(int realPriorityNo)
+		{
+		   this.realPriorityNo=realPriorityNo;
+		}
+		
+		/**
+		 * @return the priority
+		 */
+		public int getPriority(){
+			return realPriorityNo;
+		}
+		
+	}
+	private final int id;
+	private final Priority priority;
+
+	/**
+	 * Creates a new Sync-Point with normal priority
+	 * 
+	 * @param pointID a id for this syncPoint
+	 */
+	public SyncPoint(int pointID) {
+		this(pointID,Priority.NORMAL);
+	}
+	
+	/**
+	 * Creates a new Sync-Point with normal {@link Priority} (and with hashcode as id)
+	 */
+	public SyncPoint() {
+		this.id = this.hashCode();
+		this.priority = Priority.NORMAL;
+	}
+	
+	/**
+	 * @param id a id for the 
+	 * @param priority 
+	 */
+	public SyncPoint(int id, Priority priority ) {
+		this.id = id;
+		this.priority = priority;
+	}
+
+	/**
+	 * Creates a new Sync-Point with the given {@link Priority}
+	 */
+	public SyncPoint(Priority priority) {
+		id = this.hashCode();
+		this.priority = priority;
+	}
+
+	/**
+	 * @return the id
+	 */
+	public int getId() {
+		return id;
+	}
+
+	/**
+	 * @return the priority of the Thread (as system dependent for direct use in {@link Thread Threads})
+	 */
+	public int getPriority() {
+		return priority.getPriority();
+	}
+}

Added: trunk/src/appl/parallel/spmd/package.html
===================================================================
--- trunk/src/appl/parallel/spmd/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains classes related the the SPMD execution. 
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/spmd/split/AbstractSplitMap.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/AbstractSplitMap.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/AbstractSplitMap.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,232 @@
+package appl.parallel.spmd.split;
+
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * This class can be used for the implementation of {@link SplitMap}s. It already
+ * provides most of the functions. Normally subclasses only have to implement the methods
+ * {@link SplitMap#makeMap()} and {@link SplitMap#getNeighborsForPosition(int)}.
+ *
+ * @see SplitMap
+ *
+ * @author Dominik Appl
+ */
+public abstract class AbstractSplitMap implements SplitMap {
+
+	public enum NeighborhoodBoxingMode {
+		inBoxing, outBoxing
+	}
+
+	protected NeighborhoodBoxingMode boxingMode;
+	protected int noOfPartitions;
+	protected int globalHeight;
+	protected int globalWidth;
+
+	/**
+	 * a value of weights determines how big the share of the
+	 * partition with this position is. The sum of all values
+	 * should be 1 or near to 1.
+	 */
+	protected double[] weights;
+	protected int neighborhoodRange;
+
+	/** the Rectangle of the whole Grid **/
+	protected Rectangle globalBounds;
+	/** the calculation area of each partition */
+	protected Rectangle[] partitionCalculationBounds;
+	/** the bounds of the neighborhood data of the partition */
+	protected Rectangle[] partitionNeighborhoodBounds;
+    protected String[] IPs;
+
+	public AbstractSplitMap(SplittableResource splittable, int neighborhoodRange,
+			int noOfPartitions,
+			NeighborhoodBoxingMode boxingMode) {
+		this(splittable.getSplitWidth(),splittable.getSplitHeight(),neighborhoodRange, noOfPartitions, boxingMode);
+
+	}
+
+	public AbstractSplitMap() {
+		this.globalWidth = 1;
+		this.globalHeight = 1;
+		this.neighborhoodRange = 0;
+		this.noOfPartitions = 1;
+		this.boxingMode = NeighborhoodBoxingMode.inBoxing;
+		init();
+		makeMap();
+	}
+
+	 /**
+	 * @param width
+	 * @param height
+	 * @param neighborhoodRange
+	 * @param noOfPartitions
+	 * @param boxingMode
+	 */
+	public AbstractSplitMap(int width, int height, int neighborhoodRange, int noOfPartitions, NeighborhoodBoxingMode boxingMode) {
+		this.globalWidth = width;
+		this.globalHeight = height;
+		this.neighborhoodRange = neighborhoodRange;
+		this.noOfPartitions = noOfPartitions;
+		this.boxingMode = boxingMode;
+		init();
+		makeMap();
+	}
+
+	/* non java-doc
+	 * @see appl.parallel.spmd.split.SplitMap#setParameters(SplittableResource, int, int, appl.parallel.spmd.split.AbstractSplitMap.NeighborhoodBoxingMode)
+	 */
+	public void setParameters(SplittableResource splittable, int neighborhoodRange, int noOfPartitions, NeighborhoodBoxingMode boxingMode) {
+		this.globalWidth = splittable.getSplitWidth();
+		this.globalHeight = splittable.getSplitHeight();
+		this.neighborhoodRange = neighborhoodRange;
+		this.noOfPartitions = noOfPartitions;
+		this.boxingMode = boxingMode;
+		init();
+	}
+
+	/**
+	 * Initializes the bounds of the partitions
+	 */
+	protected void init() {
+		if (noOfPartitions < 1)
+			throw new UnsupportedOperationException(
+					"Number of Partions must be > 0");
+
+		//Initialize the weight for equal split (should not matter if not excactly 100%)
+		weights = new double[noOfPartitions];
+		for (int i = 0; i < noOfPartitions; i++)
+			weights[i] = (1.0 / noOfPartitions);
+		globalBounds = new Rectangle(0, 0, globalWidth, globalHeight);
+		partitionCalculationBounds = new Rectangle[noOfPartitions];
+		partitionNeighborhoodBounds = new Rectangle[noOfPartitions];
+
+	}
+
+
+
+	public void setWeights(double... weights) {
+		if (weights.length != noOfPartitions)
+			throw new UnsupportedOperationException("The number of weights ("
+					+ weights.length
+					+ ") does not match the number of partitions ("
+					+ noOfPartitions + ")");
+		//check if the weights are valid
+		for (double weight : weights) {
+			if(weight <=0 || weight > 1)
+				throw new UnsupportedOperationException("A weight was '" + weight + "' but must be between 0 and 1");
+		}
+		this.weights = weights;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getDescription()
+	 */
+	public abstract String getDescription();
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getNeighborsForPosition(int)
+	 */
+	public abstract int[] getNeighborsForPosition(int pos);
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#makeMap()
+	 */
+	public abstract void makeMap();
+
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getGlobalCalculationBounds()
+	 */
+	public Rectangle getGlobalCalculationBounds() {
+		return globalBounds;
+	}
+
+
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getLocalCalculationArea(int)
+	 */
+	public Rectangle getLocalCalculationBounds(int pos){
+		Rectangle localBounds = (Rectangle) partitionCalculationBounds[pos].clone();
+		//move relative to the partition bounds
+		double xdiff=partitionCalculationBounds[pos].getX()-partitionNeighborhoodBounds[pos].getX();
+		double ydiff=partitionCalculationBounds[pos].getY()-partitionNeighborhoodBounds[pos].getY();
+		//set to the local coordinates
+		localBounds.setLocation((int) xdiff, (int) ydiff);
+		return localBounds;
+	}
+
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getLocalNeighborhoodArea(int)
+	 */
+	public Rectangle getLocalNeighborhoodBounds(int pos) {
+		Rectangle localBounds = (Rectangle) partitionNeighborhoodBounds[pos]
+				.clone();
+		//move to (0,0)
+		localBounds.setLocation(0, 0);
+		return localBounds;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getPartitionCalculationArea(int)
+	 */
+	public Rectangle getPartitionCalculationBounds(int pos) {
+		return partitionCalculationBounds[pos];
+	}
+
+	public Rectangle getPartitionNeighborhoodBounds(int pos) {
+		return partitionNeighborhoodBounds[pos];
+	}
+
+
+	 /* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getGlobalBounds()
+	 */
+	public Rectangle getGlobalBounds() {
+		return globalBounds;
+	}
+
+    /* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getPartitionBounds(int)
+	 */
+	public Rectangle getPartitionBounds(int pos) {
+		return partitionNeighborhoodBounds[pos];
+	}
+
+	public Rectangle getLocalBounds(int pos)
+	{
+		return getLocalNeighborhoodBounds(pos);
+	}
+
+
+    /* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getIP(int)
+	 */
+	public String getIP(int pos) {
+	  if(IPs==null)
+		  return null;
+	  if(IPs.length!=noOfPartitions)
+		  return null;
+	  return IPs[pos];
+	}
+
+    /* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#setIPs(java.lang.String[])
+	 */
+	public void setIPs(String[] IPs) {
+       this.IPs = IPs;
+	}
+
+    /**
+	 * @return the neighborhoodRange
+	 */
+	public int getNeighborhoodRange() {
+		return neighborhoodRange;
+	}
+
+	public int getCount(){
+		return noOfPartitions;
+	}
+}

Added: trunk/src/appl/parallel/spmd/split/DataPartition.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/DataPartition.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/DataPartition.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,52 @@
+package appl.parallel.spmd.split;
+
+import java.awt.Rectangle;
+
+/**
+ * Represents a data partition. It has an id which identifies the resource, which is the mother
+ * of the partition.
+ *
+ * @author Dominik Appl
+ */
+public interface DataPartition {
+
+	/**
+	 * Returns the id of the super data structure this partition is a part of.
+	 * @return the id of the super data structure this partition is a part of.
+	 */
+	public int getRootID();
+
+	 /**
+	  * Returns the bounds of the partition as a rectangle. The coordinates
+	  * of the rectangle are global (which means relative to the root structure).
+	  * @return the bounds of the partition as a rectangle. The coordinates
+	  * of the rectangle are global (which means relative to the root structure).
+	 */
+	 public Rectangle getPartitionBounds();
+	 /**
+     * Returns the partition specified by the given {@link Rectangle}. Note, that
+     * partitioning by a rectangle does not mean, that the underlying datastructure
+     * has to be 2D, but only that the splitting has to be at max. 2D.
+     * @param partitionBounds the bounds of the partition which are to be retrieved
+     * in global coordinates (the coordinates should be relative to the root-structure)
+     */
+    public DataPartition getPartition(Rectangle partitionBounds);
+
+    /**
+     * Overwrites the data at the location specified by the {@link Rectangle} with
+     * the given partition-data.
+     *
+     * @param partition the new data
+     * @param partitionBounds the target location of the data (in coordinates of the root structure)
+     */
+    public void setPartition(DataPartition partition, Rectangle partitionBounds);
+
+	/**
+	 * Creates an empty Object with the given id. (Used e.g. by Multi-Data-Objects)
+	 * @param newID the id of the new Object
+	 * @return an Empty element with the same dimension as this element.
+	 */
+	public DataPartition getEmpty(int newID);
+
+
+}

Added: trunk/src/appl/parallel/spmd/split/PartitionInfo.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/PartitionInfo.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/PartitionInfo.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,42 @@
+package appl.parallel.spmd.split;
+
+/**
+ * A {@link PartitionInfo} object contains information about the partition, which is
+ * normally transfered a server. It contains a {@link SplitMap} for the
+ * partition, the position inside the {@link SplitMap}, the name of the base
+ * resource (the mother resource) and a method which supports cloning the
+ * information.
+ * 
+ * @see SinglePartitionInfo
+ * 
+ * @author Dominik Appl
+ */
+public interface PartitionInfo extends Cloneable {
+
+	/**
+	 * @return the splitMap for this partition
+	 */
+	public abstract SplitMap getSplitMap();
+
+	/**
+	 * @return the splitMapPos position inside the {@link SplitMap}
+	 */
+	public abstract int getSplitMapPos();
+
+	/**
+	 * @return the baseResourceName the name of the base resource (mother resource). The name
+	 * is string which is the user provides for identification an retrieval on server side. 
+	 */
+	public abstract String getBaseResourceName();
+
+	/**
+	 * This method can especially be used by multi data methods to create a new instance of this 
+	 * data type
+	 * 
+	 * @param rootID the id of the base resource for the NEW copy of the {@link PartitionInfo}
+	 * 
+	 * @return the new {@link PartitionInfo}
+	 */
+	public abstract PartitionInfo clone(int rootID);
+
+}
\ No newline at end of file

Added: trunk/src/appl/parallel/spmd/split/SinglePartitionInfo.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/SinglePartitionInfo.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/SinglePartitionInfo.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,104 @@
+package appl.parallel.spmd.split;
+
+import java.io.Serializable;
+
+import appl.data.DataLoader;
+import appl.parallel.data.PartitionDataHandler;
+
+// fuer Doku
+import javax.activation.DataHandler;
+import appl.parallel.client.DataServer;
+import appl.parallel.data.XuluClientLoader;
+
+/**
+ * This class collects the metadata of a partitioning
+ * The following information is encapsulated in a SinglePartitionInfo Object:
+ * <ul>
+ * <li>
+ * The <b>ID</b>of the {@link SplittableResource SplittableResource}
+ * </li>
+ * <li>The <b>baseResourceName</b> of the resource (given by the parallel programmer)</li>
+ * <li>The <b>{@link DataHandler}</b>, which loads the data of the partition. This is a very important aspect.
+ * The handler defines how the data is actually loaded. It may for example be loaded
+ * from a {@link DataServer} using a {@link XuluClientLoader}, but it may also be used
+ * to load data from local disk, databases etc. without communication with the client.
+ * The {@link DataHandler} is also responsible for writing the the data back to the source
+ * </li>
+ * <li>
+ * The <b>{@link SplitMap}</b> which represents the current partitioning.
+ * </li>
+ * <li>
+ * A <b>splitmap position</b>, which identifies the partition number in the split.
+ * </li>
+ *
+ * @author Dominik Appl
+ *
+ *
+ */
+public class SinglePartitionInfo implements Serializable, PartitionInfo{
+
+	private final int baseResourceID;
+    private final PartitionDataHandler handler;
+    private final SplitMap splitMap;
+    private final int splitMapPos;
+    private final String baseResourceName;
+
+    /**
+     * The constructor.
+     *
+     * @param baseResourceID the root id (see {@link DataPartition#getRootID()})
+     * @param baseResourceName the name of the resource (given by parallel programmer)
+     * @param handler {@link PartitionDataHandler}
+     * 			which is responsible for loading and unloading
+     * @param splitMap splitmap describing the partitioning
+     * @param splitMapPos the position inside the splitmap
+     */
+    public SinglePartitionInfo(int baseResourceID, String baseResourceName, PartitionDataHandler handler, SplitMap splitMap, int splitMapPos){
+        this.baseResourceID = baseResourceID;
+        this.baseResourceName = baseResourceName;
+        this.handler = handler;
+        this.splitMap = splitMap;
+        this.splitMapPos = splitMapPos;
+    }
+
+    /**
+	 * @return the baseResourceID
+	 */
+	public int getBaseResourceID() {
+		return baseResourceID;
+	}
+    /**
+	 * @return the handler
+	 */
+	public PartitionDataHandler getPartitionDataHandler() {
+		return handler;
+	}
+    /* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.PartitionInfo#getSplitMap()
+	 */
+	public SplitMap getSplitMap() {
+		return splitMap;
+	}
+    /* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.PartitionInfo#getSplitMapPos()
+	 */
+	public int getSplitMapPos() {
+		return splitMapPos;
+	}
+
+    /* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.PartitionInfo#getBaseResourceName()
+	 */
+	public String getBaseResourceName() {
+		return baseResourceName;
+	}
+
+	public PartitionInfo clone(int newRootID){
+		PartitionDataHandler clonedHandler = handler.clone();
+		clonedHandler.setRootID(newRootID);
+		return new SinglePartitionInfo(newRootID,
+				this.baseResourceName,clonedHandler,this.splitMap,
+				this.splitMapPos);
+	}
+
+}

Added: trunk/src/appl/parallel/spmd/split/SplitMap.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/SplitMap.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/SplitMap.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,147 @@
+package appl.parallel.spmd.split;
+
+import java.awt.Rectangle;
+import java.io.Serializable;
+import java.net.InetAddress;
+
+import appl.parallel.spmd.split.SplittableResource;
+import appl.parallel.spmd.split.AbstractSplitMap.NeighborhoodBoxingMode;
+
+/**
+ * Defines a split map over a {@link SplittableResource}. A split map is a
+ * layout of an actual partitioning. Each partition is associated with a number,
+ * ranging from 0 to noOfPartitions-1.
+ * <br>
+ * The partitions are layouted as rectangles, where each rectangle represents a partition
+ * or a neighborhood around a partition. Every partition or neighborhood can be queried.
+ * IP-Addresses can be associated with partitions to identify the server on which a partition is located.
+ * <br>
+ * The interface is largely implementation independent. Multiple implementations exist.
+ *
+ * You can query the SplitMap for neighbors of a partition.
+ *
+ * @see SplitMap1DHorizontal
+ * @see SplitMap1DVertical
+ * @see SplitMap2D
+ * @see AbstractSplitMap
+ *
+ * @author Dominik Appl
+ */
+public interface SplitMap extends Serializable{
+
+	/**
+	 * returns an Array of neighbors for that position in the splitmap.
+	 *
+	 * @param pos position in splitmap
+	 * @return the array
+	 *
+	 */
+	int[] getNeighborsForPosition(int pos);
+
+
+	/**
+	 * With this setter, you can assign each partition a weight, so that
+	 * the data you split is not splitted equally, but arcording to
+	 * these values. A value of weights specifies how big the share of the
+	 * partition with this position is. The sum of all values
+	 * should be 1 or near to 1.
+	 *
+	 * @param weights
+	 * @throws UnsupportedOperationException if the number of weights does
+	 * not match the number of partitions
+	 */
+	public void setWeights(double... weights);
+
+	/**
+	 * @return a short description of the type of the Splitting
+	 */
+	public String getDescription();
+
+	/**
+	 * @param pos the partition number
+	 * @return the bounds of the partiton calculation area in global coordinates
+	 */
+	public Rectangle getPartitionCalculationBounds(int pos);
+
+	/**
+	 * @param pos the partition number
+	 * @return the bounds of the partiton neighborhood area in global coordinates
+	 */
+	public Rectangle getPartitionNeighborhoodBounds(int pos);
+
+	/**
+	 * @param pos the partition number
+	 * @return  the bounds of the partiton in global coordinates,
+	 * 			which should be the same as {@link #getPartitionNeighborhoodBounds(int)}
+	 *
+	 */
+	public Rectangle getPartitionBounds(int pos);
+
+
+	/**
+	 * @return {@link #getGlobalBounds()}
+	 */
+	public Rectangle getGlobalCalculationBounds();
+
+	/**
+	 * @return the bounds of the whole area starting with 0,0 in the topleft corner
+	 */
+	public Rectangle getGlobalBounds();
+
+	/**
+	 * Gets the whole partition bounds (including available neighborhood)
+	 * @param pos the partition number
+	 * @return the bounds of the partition using local coordinates. (0,0) is the topleft corner.
+	 */
+	public Rectangle getLocalBounds(int pos);
+	/**
+	 * @param pos the partition number
+	 * @return the calculation bounds of the partition using local coordinates.
+	 */
+	public Rectangle getLocalCalculationBounds(int pos);
+	/**
+	 * @param pos the partition number
+	 * @return the bounds of the partition using local coordinates. (0,0) is the topleft corner.
+	 */
+	public Rectangle getLocalNeighborhoodBounds(int pos);
+
+
+	/**
+	 * Sets the given values. Call makeMap() for this changes to take effekt.
+	 *
+	 * @param splittable the resource on which the splitmap is calculated
+	 * @param neighborhoodRange the neighborhoodrange
+	 * @param noOfPartitions the number of partitions to be generated
+	 * @param boxingMode the boxing mode
+	 *
+	 */
+	public void setParameters(SplittableResource splittable, int neighborhoodRange,
+			int noOfPartitions,
+			NeighborhoodBoxingMode boxingMode);
+
+	/**
+	 * @param IPs a String Array of IPs which are mapped to the partition in the given order.
+	 *
+	 */
+	public void setIPs(String IPs[]);
+	/**
+	 * @param pos position for this splitmap
+	 * @return the IP associated with this position
+	 */
+	public String getIP(int pos);
+
+	 /**
+	 * @return the neighborhoodRange
+	 */
+	public int getNeighborhoodRange();
+
+	/**
+	 * Creates the map
+	 */
+	public void makeMap();
+
+	/**
+	 * @return the number of partitions
+	 */
+	public int getCount();
+}

Added: trunk/src/appl/parallel/spmd/split/SplitMap1DHorizontal.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/SplitMap1DHorizontal.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/SplitMap1DHorizontal.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,132 @@
+package appl.parallel.spmd.split;
+
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+
+import appl.parallel.spmd.split.AbstractSplitMap.NeighborhoodBoxingMode;
+import appl.util.RasterMetaData;
+import schmitzm.data.WritableGrid;
+
+/**
+ * Responsible for splitting a 2D Area (e.g a {@link WritableGrid}) in a 
+ * 1D fashion, which means in this case horizontal (by rows). This is only a
+ * a virtual split (a map of a split). 
+ * 
+ * A neighborhood range can be specified to create partitions that
+ * overlap each other. This overlapping can be done in two different
+ * ways: <br><br>
+ * 
+ * <b>Inboxing</b>(default):<br><br>
+ * Inboxing means, that the neighborhood area is not part of the calculation
+ * area. 
+ * <br> <br>
+ * <b>Outboxing:</b><br>
+ * Outboxing means that the neighborhood area is part of the calculation area.
+ *  <br> <br>
+ * 
+ *
+ * Note that this class is flexible. It may also be applied 
+ * to one dimensional data structures like for example arrays. 
+ * If u want to do this, simply choose one of the dimensions as 1. <br>
+ * 
+ * @author Dominik Appl
+ */
+
+public class SplitMap1DHorizontal extends AbstractSplitMap implements SplitMap {
+
+
+
+	public SplitMap1DHorizontal(int width, int height, int neighborhoodRange, int noOfPartitions,
+			NeighborhoodBoxingMode boxingMode) {
+		
+		super(width,height,neighborhoodRange, noOfPartitions, boxingMode);
+	}
+	
+
+	/**
+	 * needed for serialization
+	 */
+	public SplitMap1DHorizontal(){
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.DataSplitter#getDescription()
+	 */
+	public String getDescription() {
+		return "1D-GridSplitter";
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.DataSplitter#split(appl.parallel.spmd.split.SplittableRessource)
+	 */
+	public void makeMap() {
+			//the local calculation area is partitioned
+			int nextUpperLeftCorner = (int) globalBounds.getY(); //next y-value (will be 0)
+			for (int i = 0; i < noOfPartitions; i++) {
+				
+				//calculate length based on weights
+				int pHeight = (int) (globalBounds.getHeight() * weights[i]);
+				
+				//for the last position make sure, that ALL data is used 
+				//and no line is lost due to rounding errors in weight calculation
+				if(i==noOfPartitions-1)
+					pHeight = (int) globalBounds.getHeight() - nextUpperLeftCorner;
+				
+				//create inboxing(!) partition 
+				partitionCalculationBounds[i] = new Rectangle(
+						(int) globalBounds.getX(), nextUpperLeftCorner, (int)globalBounds.getWidth(),
+						pHeight);
+				
+				//if there is only one partition there are no explicit neighborhood bounds
+				if(noOfPartitions==1)
+					partitionNeighborhoodBounds[i]=partitionCalculationBounds[i];
+				//else simply calculate the neighborhood bounds out of the previosly 
+				//created calculation Area (@see AbstractSplitMap)
+				else 
+					partitionNeighborhoodBounds[i] = new Rectangle(
+							(int) globalBounds.getX(),
+							(int) partitionCalculationBounds[i].getY() - neighborhoodRange,
+							(int)(partitionCalculationBounds[i].getWidth()),
+						    (int)(partitionCalculationBounds[i].getHeight()+ 2 * neighborhoodRange));
+				
+			    //the first and the last partition have a neighborhood area only on one side of 
+			    //the calculation area:
+			    partitionNeighborhoodBounds[i] = partitionNeighborhoodBounds[i].intersection(globalBounds);
+				nextUpperLeftCorner += pHeight; //+1 not required - the partitions will not overlap
+				
+				//the partitionCalculation bounds were created for inboxing:
+				if(boxingMode==NeighborhoodBoxingMode.outBoxing)
+					partitionCalculationBounds[i]=partitionNeighborhoodBounds[i];			
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getNeighborsForPosition(int)
+	 */
+	public int[] getNeighborsForPosition(int pos) {
+		int[] oneReturn = new int[1];
+		int[] twoReturns = new int[2];
+
+		//this is very simple in one 1D case, of course:
+		//if only one Partition return null
+		if (noOfPartitions == 1)
+			return new int[0];
+		
+		//for first partition
+		if ((pos == 0)) {
+			oneReturn[0] = 1;
+			return oneReturn;
+		}
+		//for last partition
+		if (pos == noOfPartitions - 1) {
+			oneReturn[0] = noOfPartitions - 2;
+			return oneReturn;
+		}
+		//for every other partition
+		twoReturns[0] = pos - 1;
+		twoReturns[1] = pos + 1;
+		return twoReturns;
+	}
+
+}

Added: trunk/src/appl/parallel/spmd/split/SplitMap1DVertical.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/SplitMap1DVertical.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/SplitMap1DVertical.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,139 @@
+package appl.parallel.spmd.split;
+
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+
+import appl.parallel.spmd.split.AbstractSplitMap.NeighborhoodBoxingMode;
+import appl.util.RasterMetaData;
+import schmitzm.data.WritableGrid;
+
+/**
+ * Responsible for splitting a 2D Area (e.g a {@link WritableGrid}) in a 
+ * 1D fashion, which means in this case vertical (by cols). This is only a
+ * a virtual split (a map of a split). 
+ * 
+ * A neighborhood range can be specified to create partitions that
+ * overlap each other. This overlapping can be done in two different
+ * ways: <br><br>
+ * 
+ * <b>Inboxing</b>(default):<br><br>
+ * Inboxing means, that the neighborhood area is not part of the calculation
+ * area. 
+ * <br> <br>
+ * <b>Outboxing:</b><br>
+ * Outboxing means that the neighborhood area is part of the calculation area.
+ *  <br> <br>
+ * 
+ *
+ * Note that this class is flexible. It may also be applied 
+ * to one dimensional data structures like for example arrays. 
+ * If u want to do this, simply choose one of the dimensions as 1. <br>
+ * 
+ * @author Dominik Appl
+ */
+
+public class SplitMap1DVertical extends AbstractSplitMap implements SplitMap {
+
+	
+//	public SplitMap1DVertical(SplittableResource splittable, int neighborhoodRange, int noOfPartitions,
+//			NeighborhoodBoxingMode boxingMode) {
+//		
+//		super(splittable,neighborhoodRange, noOfPartitions, boxingMode);
+//	}
+	
+
+	public SplitMap1DVertical(int width, int height, int neighborhoodRange, int noOfPartitions,
+			NeighborhoodBoxingMode boxingMode) {
+		
+		super(width,height,neighborhoodRange, noOfPartitions, boxingMode);
+	}
+	
+
+	/**
+	 * needed for serialization
+	 */
+	public SplitMap1DVertical(){
+		
+	}
+	
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.DataSplitter#getDescription()
+	 */
+	public String getDescription() {
+		return "1D-GridSplitter";
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.DataSplitter#split(appl.parallel.spmd.split.SplittableRessource)
+	 */
+	public void makeMap() {
+			//the local calculation area is partitioned
+			int nextUpperLeftCorner = (int) globalBounds.getX(); //next x-value (will be 0)
+			for (int i = 0; i < noOfPartitions; i++) {
+				
+				//calculate length based on weights
+				int pWidth = (int) (globalBounds.getWidth() * weights[i]);
+				
+				//for the last position make sure, that ALL data is used 
+				//and no line is lost due to rounding errors in weight calculation
+				if(i==noOfPartitions-1)
+					pWidth = (int) globalBounds.getWidth() - nextUpperLeftCorner;
+				
+				//create inboxing(!) partition 
+				partitionCalculationBounds[i] = new Rectangle(
+						nextUpperLeftCorner, (int) globalBounds.getY(), pWidth,
+						(int) globalBounds.getHeight());
+				
+				//if there is only one partition there are no explicit neighborhood bounds
+				if(noOfPartitions==1)
+					partitionNeighborhoodBounds[i]=partitionCalculationBounds[i];
+				//else simply calculate the neighborhood bounds out of the previosly 
+				//created calculation Area
+				else 
+					partitionNeighborhoodBounds[i] = new Rectangle(
+						(int)partitionCalculationBounds[i].getX() - neighborhoodRange,
+						(int) globalBounds.getY(),
+						(int)(partitionCalculationBounds[i].getWidth() + 2 * neighborhoodRange),
+						(int)(partitionCalculationBounds[i].getHeight()));
+				
+			    //the first and the last partition have a neighborhood area only on one side of 
+			    //the calculation area:
+			    partitionNeighborhoodBounds[i] = partitionNeighborhoodBounds[i].intersection(globalBounds);
+				nextUpperLeftCorner += pWidth; //+1 not required - the partitions will not overlap
+				
+				//the partitionCalculation bounds were created for inboxing:
+				if(boxingMode==NeighborhoodBoxingMode.outBoxing)
+					partitionCalculationBounds[i]=partitionNeighborhoodBounds[i];
+				
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.split.SplitMap#getNeighborsForPosition(int)
+	 */
+	public int[] getNeighborsForPosition(int pos) {
+		int[] oneReturn = new int[1];
+		int[] twoReturns = new int[2];
+
+		//this is very simple in one 1D case, of course:
+		//if only one Partition return null
+		if (noOfPartitions == 1)
+			return new int[0];
+		
+		//for first partition
+		if ((pos == 0)) {
+			oneReturn[0] = 1;
+			return oneReturn;
+		}
+		//for last partition
+		if (pos == noOfPartitions - 1) {
+			oneReturn[0] = noOfPartitions - 2;
+			return oneReturn;
+		}
+		//for every other partition
+		twoReturns[0] = pos - 1;
+		twoReturns[1] = pos + 1;
+		return twoReturns;
+	}
+
+}

Added: trunk/src/appl/parallel/spmd/split/SplitMap2D.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/SplitMap2D.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/SplitMap2D.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,210 @@
+package appl.parallel.spmd.split;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.util.Vector;
+
+import appl.parallel.client.RemoteExecutionController;
+import appl.parallel.spmd.split.AbstractSplitMap.NeighborhoodBoxingMode;
+import appl.parallel.util.Helper;
+import appl.util.RasterMetaData;
+import schmitzm.data.WritableGrid;
+
+/**
+ * Responsible for splitting a 2D Area (e.g a {@link WritableGrid}) in a 2D
+ * fashion. The splitting is irregular, meaning that the rectangles are not
+ * equally sized, but partitioned according to the given weights. 
+ * Splitting is as follows: <br><br>
+ * 1 to 4 Partitions: 1 row <br>
+ * 4 to 8 Partitions: 2 rows <br>
+ * 9 to 15 Partitions: 3 rows <br>
+ * and so on (depending on the square root of the partititons)<br>
+ * <br>
+ * For partitioning the this class strongly depends on {@link SplitMap1DHorizontal}
+ * and {@link SplitMap1DVertical}. First the squareroot of the number of
+ * participating resources is taken to determine how many rows should be
+ * created. After this the height of the rows is weighted by adding the weight
+ * of the resources in that horizontal partition. The Grid is then splitted
+ * horizontal. Finally the horizontal partitions are splitted vertical according
+ * to the relative weight to each other. This is only a a virtual split (a map
+ * of a split). <br>
+ * A neighborhood range can be specified to create partitions that overlap each
+ * other. This overlapping can be done in two different ways: <br>
+ * <br>
+ * <b>Inboxing</b>(default):<br>
+ * <br>
+ * Inboxing means, that the neighborhood area is not part of the calculation
+ * area. <br>
+ * <br>
+ * <b>Outboxing:</b><br>
+ * Outboxing means that the neighborhood area is part of the calculation area.
+ * <br>
+ * <br>
+ * Note that this may also be applied to three dimensional data structures (a 2D
+ * splitting of a 3D datatype).
+ * 
+ * @author Dominik Appl
+ */
+
+public class SplitMap2D extends AbstractSplitMap implements SplitMap {
+
+	private SplitMap1DHorizontal horizontalMap;
+
+	private SplitMap1DVertical[] verticalMaps;
+
+	public SplitMap2D(int width, int height, int neighborhoodRange,
+			int noOfPartitions, NeighborhoodBoxingMode boxingMode) {
+		super(width, height, neighborhoodRange, noOfPartitions, boxingMode);
+	}
+
+	/**
+	 * needed for serialization
+	 */
+	public SplitMap2D() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.split.AbstractSplitMap#makeMap()
+	 */
+	public void makeMap() {
+		// take the squareroot of the number of participating resources to
+		// determine the number of rows:
+		int noOfRows = (int) Math.sqrt(noOfPartitions);
+		// calculate weights for the rows (sum of the weights of the partitions
+		// inside that row)
+		double rowWeights[] = new double[noOfRows];
+		int noOfCols[] = new int[noOfRows]; // noOfCols per row
+		for (int row = 0; row < noOfRows; row++) {
+			// calculate no. of cols in the row:
+			noOfCols[row] = (noOfPartitions / noOfRows);
+			// the last row may contain a greater number of cols
+			if (row == noOfRows - 1)
+				noOfCols[row] = noOfPartitions
+						- ((noOfRows - 1) * noOfCols[row]);
+			for (int col = 0; col < noOfCols[row]; col++)
+				rowWeights[row] += weights[row * col + col];
+		}
+
+		// create the horizontal Splitmap
+		horizontalMap = new SplitMap1DHorizontal(globalWidth, globalHeight,
+				neighborhoodRange, noOfRows, boxingMode);
+		horizontalMap.setWeights(rowWeights);
+		horizontalMap.makeMap();
+
+		// for each horizontal partition create a vertical split
+		verticalMaps = new SplitMap1DVertical[noOfRows];
+		for (int row = 0; row < noOfRows; row++) {
+			//notice: all splitmaps start at (0,0), later a conversion must be made
+			verticalMaps[row] = new SplitMap1DVertical((int) horizontalMap
+					.getGlobalBounds().getWidth(), (int) horizontalMap
+					.getPartitionCalculationBounds(row).getHeight(), neighborhoodRange,
+					noOfCols[row], boxingMode);
+			int ratings[] = new int[noOfCols[row]];
+			for (int col = 0; col < noOfCols[row]; col++) {
+				{
+					// the rating of the col is the weight of the col * 100000
+					// (ratings must be positive integers)
+					ratings[col] = (int) (weights[row * col + col] * 1000000);
+
+				}
+
+				verticalMaps[row].setWeights(Helper.calculateWeights(ratings));
+				verticalMaps[row].makeMap();
+			}
+		}
+		// now we have partitioned the grid. Lets assign the calculation and
+		// neighborhoodareas:
+		for (int i = 0; i < noOfPartitions; i++) {
+			int row = getRowForIdx(i);
+			int col = getColForIdx(i);
+			partitionCalculationBounds[i] = verticalMaps[row]
+					.getPartitionCalculationBounds(col);
+			//because all splitmaps start with (0,0) we must move 
+			//the rectangles to the right position
+			int x = (int) partitionCalculationBounds[i].getX(); //the x value remains unchanged
+			partitionCalculationBounds[i].setLocation(
+					new Point(x,(int) horizontalMap.getPartitionCalculationBounds(row).getY()));
+			// if there is only one partition there are no explicit neighborhood
+			// bounds
+			if (noOfPartitions == 1)
+				partitionNeighborhoodBounds[i] = partitionCalculationBounds[i];
+			// else simply extend the Rectangle with the Neighborhoodbounds
+			// created calculation Area (@see AbstractSplitMap)
+			else
+				partitionNeighborhoodBounds[i] = new Rectangle(
+						(int) partitionCalculationBounds[i].getX()
+								- neighborhoodRange,
+						(int) partitionCalculationBounds[i].getY()
+								- neighborhoodRange,
+						(int) (partitionCalculationBounds[i].getWidth() + 2 * neighborhoodRange),
+						(int) (partitionCalculationBounds[i].getHeight() + 2 * neighborhoodRange));
+
+			// cut of the obverlapping sections which are out of the grid:
+			partitionNeighborhoodBounds[i] = partitionNeighborhoodBounds[i]
+					.intersection(globalBounds);
+
+			// the partitionCalculation bounds were created for inboxing:
+			if (boxingMode == NeighborhoodBoxingMode.outBoxing)
+				partitionCalculationBounds[i] = partitionNeighborhoodBounds[i];
+		}
+	}
+
+	/**
+	 * @param i
+	 * @return
+	 */
+	private int getColForIdx(int index) {
+		int noOfRows = (int) Math.sqrt(noOfPartitions);
+		int avgNoOfCols = noOfPartitions / noOfRows;
+		int currentRow = getRowForIdx(index);
+		int returnValue = (index - currentRow*avgNoOfCols);
+		return returnValue;
+	}
+
+	private int getRowForIdx(int index) {
+		int noOfRows = (int) Math.sqrt(noOfPartitions);
+		int avgNoOfCols = noOfPartitions / noOfRows;
+		int returnValue = index / avgNoOfCols;
+		//special handling for the last row (contains more partitions)
+		if(noOfRows==returnValue)
+			return noOfRows-1;
+		else return returnValue;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.split.SplitMap#getNeighborsForPosition(int)
+	 */
+	public int[] getNeighborsForPosition(int pos) {
+		Vector neighbors = new Vector();
+		// simply intersect with all partitions to find the neighbors:
+		for (int i = 0; i < noOfPartitions; i++) {
+			if (i == pos)
+				continue;
+			if (partitionNeighborhoodBounds[i]
+					.intersects(partitionNeighborhoodBounds[pos]))
+				neighbors.add(pos);
+		}
+		int results[] = new int[neighbors.size()];
+		// copy into array
+		for (int i = 0; i < results.length; i++) {
+			results[i] = (Integer) neighbors.get(i);
+		}
+		return results;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.spmd.split.AbstractSplitMap#getDescription()
+	 */
+	@Override
+	public String getDescription() {
+		return "2D-irregular Splitmap";
+	}
+
+}

Added: trunk/src/appl/parallel/spmd/split/SplittableGrid.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/SplittableGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/SplittableGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,14 @@
+package appl.parallel.spmd.split;
+
+import java.awt.Rectangle;
+
+import schmitzm.data.WritableGrid;
+
+/**
+ * A grid that is {@link SplittableResource splittable}
+ * 
+ * @author Dominik Appl
+ */
+public interface SplittableGrid extends SplittableResource, WritableGrid{
+	
+}

Added: trunk/src/appl/parallel/spmd/split/SplittableResource.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/SplittableResource.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/SplittableResource.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,47 @@
+package appl.parallel.spmd.split;
+
+import java.awt.Rectangle;
+
+import org.w3c.dom.css.Rect;
+
+import appl.data.DataLoader;
+
+/**
+ * A resource that is splittable must provide some information to work with {@link SplitMap}s.
+ * Important is the with and the height of the resource to be splitted.
+ *
+ *
+ * @author Dominik Appl
+ */
+public interface SplittableResource extends DataPartition {
+	/**
+	 * Should return a unique ID for this resource. Standard implementation
+	 * would be returning the {@link Object#hashCode() hashcode} of the object.
+	 *
+	 * @return a ID which is unique for this client
+	 *
+	 */
+	public int getRootID();
+
+	/**
+	 * Returns the loader which is responible for loading the data. This loader should be
+	 * independet from the current system. This means that, e.g. for a loader which
+	 * loads a grid from filesystem, that all paths should be relative (and not
+	 * absolute), so that a possibly remote resource can load the data from its local
+	 * filesystem, if the data is stored in the same position relative to the home
+	 * directory.
+	 *
+	 * @return a loader for this resource.
+	 */
+	public DataLoader getLocalLoader();
+
+	/**
+	 * @return the splittable is splitted according to its splitHeight (example: the height of a raster)
+	 * */
+	public int getSplitHeight();
+
+	/**
+	 * @return the splittable is splitted according to its splitWidth  (example: the width of a raster or the length of an array)
+	 * */
+	public int getSplitWidth();
+}

Added: trunk/src/appl/parallel/spmd/split/WritableGridPartition.java
===================================================================
--- trunk/src/appl/parallel/spmd/split/WritableGridPartition.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/WritableGridPartition.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,12 @@
+package appl.parallel.spmd.split;
+
+import schmitzm.data.WritableGrid;
+
+/**
+ * A {@link DataPartition} that is splittable itself.
+ * 
+ * @author Dominik Appl
+ */
+public interface WritableGridPartition extends DataPartition, WritableGrid {
+
+}

Added: trunk/src/appl/parallel/spmd/split/package.html
===================================================================
--- trunk/src/appl/parallel/spmd/split/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/spmd/split/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains classes related to the data splitting during spmd-execution.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/starter/Starter.java
===================================================================
--- trunk/src/appl/parallel/starter/Starter.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/Starter.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,40 @@
+package appl.parallel.starter;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * An interface for programs which start themself other programs as separate
+ * processes. It is possible to start/stop and restart the encapsulated process.
+ * 
+ * @author Dominik Appl
+ */
+
+public interface Starter extends Remote {
+	/**
+	 * Starts the process
+	 * 
+	 * @throws RemoteException
+	 */
+	public void start() throws RemoteException;
+
+	/**
+	 * stops the process
+	 * 
+	 * @throws RemoteException
+	 */
+	public void stop() throws RemoteException;
+
+	/**
+	 * restarts the process
+	 * 
+	 * @throws RemoteException
+	 */
+	public void restart() throws RemoteException;
+
+	/**
+	 * @return true, if the process is running
+	 * @throws RemoteException
+	 */
+	public boolean isRunning() throws RemoteException;
+}

Added: trunk/src/appl/parallel/starter/client/StarterClientGUI.java
===================================================================
--- trunk/src/appl/parallel/starter/client/StarterClientGUI.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/client/StarterClientGUI.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,48 @@
+package appl.parallel.starter.client;
+
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+
+import org.apache.log4j.BasicConfigurator;
+
+import appl.parallel.starter.Starter;
+
+/**
+ * This is a GUI for controlling the {@link Starter Starters} in the network.
+ * It has options to start/stop and restart selected servers.
+ * @author Dominik Appl
+ *
+ */
+public class StarterClientGUI extends JFrame {
+	/**
+	 * Creates a new GUI
+	 */
+	public StarterClientGUI() {
+		super("Server starter");
+		this.getContentPane().add(new XuluStarterController().getPanel());
+		this.setSize(300, 400);
+		this.addWindowListener(new ExitListener());
+	}
+
+	/**
+	 * @param args no arguments interpreted
+	 */
+	public static void main(String[] args) {
+		BasicConfigurator.configure();
+		StarterClientGUI clientGUI = new StarterClientGUI();
+		clientGUI.setVisible(true);
+	}
+
+	/**
+	 * Shuts down the application on exit
+	 * 
+	 * @author Dominik Appl
+	 */
+	public class ExitListener extends WindowAdapter {
+		public void windowClosing(WindowEvent event) {
+			System.exit(0);
+		}
+	}
+}

Added: trunk/src/appl/parallel/starter/client/StarterContainer.java
===================================================================
--- trunk/src/appl/parallel/starter/client/StarterContainer.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/client/StarterContainer.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,49 @@
+package appl.parallel.starter.client;
+
+import java.rmi.RemoteException;
+
+import appl.parallel.starter.Starter;
+
+/**
+ * Just a small container class used e.g. in the
+ * {@link XuluStarterControllerFrame} for display
+ * 
+ * @author Dominik Appl
+ */
+public class StarterContainer {
+	private final Starter starter;
+
+	private boolean isRunning;
+
+	private final String hostInfo;
+
+	/**
+	 * A Container for use in SwingComponents. The status ({@link #isServerRunning()}
+	 * is only the status at the creation of the object!
+	 * 
+	 * @param starter
+	 *            The encapsulated Starter
+	 * @param hostInfo
+	 */
+	public StarterContainer(Starter starter, String hostInfo) {
+		this.starter = starter;
+		this.hostInfo = hostInfo;
+		try {
+			isRunning = starter.isRunning();
+		} catch (RemoteException e) {
+			isRunning = false;
+		}
+	}
+
+	public boolean isServerRunning() {
+		return isRunning;
+	}
+
+	public Starter getStarter() {
+		return starter;
+	}
+
+	public String toString() {
+		return hostInfo;
+	}
+}

Added: trunk/src/appl/parallel/starter/client/XuluStarterClientPanel.java
===================================================================
--- trunk/src/appl/parallel/starter/client/XuluStarterClientPanel.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/client/XuluStarterClientPanel.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,224 @@
+package appl.parallel.starter.client;
+
+import javax.swing.JPanel;
+import java.awt.GridBagLayout;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.BoxLayout;
+import javax.swing.ListSelectionModel;
+import java.awt.Insets;
+import javax.swing.border.SoftBevelBorder;
+import javax.swing.table.DefaultTableModel;
+import edu.bonn.xulu.XuluModellingPlatform;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+
+import appl.parallel.gui.ParallelControlPanelEngine;
+
+import java.awt.Rectangle;
+import javax.swing.JList;
+import java.awt.CardLayout;
+import java.awt.GridLayout;
+
+/**
+ * The GUI for the XuluStarterController . The events are controlled by the
+ * {@link XuluStarterController}. This GUI was created with the Visual Editor
+ * plugin for eclipse and should be edited using this VE.
+ * 
+ * @author Dominik Appl
+ */
+public class XuluStarterClientPanel extends JPanel {
+
+	static final long serialVersionUID = 1L;
+
+	JPanel executionPanel = null;
+
+	JLabel Steps = null;
+
+	JScrollPane jScrollPane1 = null;
+
+	JPanel buttonPanel = null;
+
+	JList serverList = null;
+
+	JButton refreshButton = null;
+
+	JButton startButton = null;
+
+	JButton stopButton = null;
+
+	JButton restartButton = null;
+
+	/**
+	 * This is the default constructor. It should be only used be the eclipse VE
+	 */
+	public XuluStarterClientPanel() {
+		super();
+		initialize();
+	}
+
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+		this.setSize(248, 292);
+		this.add(getExecutionPanel(), null);
+	}
+
+	/**
+	 * This method initializes executionPanel
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getExecutionPanel() {
+		if (executionPanel == null) {
+			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+			gridBagConstraints1.gridx = 1;
+			gridBagConstraints1.fill = GridBagConstraints.HORIZONTAL;
+			gridBagConstraints1.insets = new Insets(0, 5, 5, 5);
+			gridBagConstraints1.gridy = 4;
+			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
+			gridBagConstraints12.gridx = 1;
+			gridBagConstraints12.fill = GridBagConstraints.HORIZONTAL;
+			gridBagConstraints12.insets = new Insets(0, 5, 5, 5);
+			gridBagConstraints12.gridy = 3;
+			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
+			gridBagConstraints11.fill = GridBagConstraints.BOTH;
+			gridBagConstraints11.weighty = 1.0;
+			gridBagConstraints11.gridx = 0;
+			gridBagConstraints11.gridy = 1;
+			gridBagConstraints11.ipadx = 0;
+			gridBagConstraints11.insets = new Insets(5, 5, 5, 5);
+			gridBagConstraints11.gridwidth = 2;
+			gridBagConstraints11.weightx = 1.0;
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.insets = new Insets(0, 0, 0, 0);
+			gridBagConstraints.gridy = 0;
+			gridBagConstraints.anchor = GridBagConstraints.NORTH;
+			gridBagConstraints.gridheight = 1;
+			gridBagConstraints.gridwidth = 2;
+			gridBagConstraints.gridx = 0;
+			Steps = new JLabel();
+			Steps.setText("Potential Servers");
+			Steps.setName("Steps");
+			executionPanel = new JPanel();
+			executionPanel.setLayout(new GridBagLayout());
+			executionPanel.setBorder(new SoftBevelBorder(
+					SoftBevelBorder.LOWERED));
+			executionPanel.setVisible(true);
+			executionPanel.add(Steps, gridBagConstraints);
+			executionPanel.add(getJScrollPane1(), gridBagConstraints11);
+			executionPanel.add(getButtonPanel(), gridBagConstraints12);
+			executionPanel.add(getRefreshButton(), gridBagConstraints1);
+		}
+		return executionPanel;
+	}
+
+	/**
+	 * This method initializes jScrollPane1
+	 * 
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getJScrollPane1() {
+		if (jScrollPane1 == null) {
+			jScrollPane1 = new JScrollPane();
+			jScrollPane1.setName("jScrollPane1");
+			jScrollPane1.setViewportView(getServerList());
+			jScrollPane1.setPreferredSize(new Dimension(200, 250));
+		}
+		return jScrollPane1;
+	}
+
+	/**
+	 * This method initializes buttonPanel
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	protected JPanel getButtonPanel() {
+		if (buttonPanel == null) {
+			GridLayout gridLayout = new GridLayout();
+			gridLayout.setRows(1);
+			buttonPanel = new JPanel();
+			buttonPanel.setLayout(gridLayout);
+			buttonPanel.add(getStartButton(), null);
+			buttonPanel.add(getStopButton(), null);
+			buttonPanel.add(getRestartButton(), null);
+		}
+		return buttonPanel;
+	}
+
+	/**
+	 * This method initializes serverList
+	 * 
+	 * @return javax.swing.JList
+	 */
+	private JList getServerList() {
+		if (serverList == null) {
+			serverList = new JList();
+			serverList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		}
+		return serverList;
+	}
+
+	/**
+	 * This method initializes refreshButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getRefreshButton() {
+		if (refreshButton == null) {
+			refreshButton = new JButton();
+			refreshButton.setText("Refresh");
+		}
+		return refreshButton;
+	}
+
+	/**
+	 * This method initializes startButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getStartButton() {
+		if (startButton == null) {
+			startButton = new JButton();
+			startButton.setText("Start");
+			startButton.setName("startButton");
+		}
+		return startButton;
+	}
+
+	/**
+	 * This method initializes stopButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getStopButton() {
+		if (stopButton == null) {
+			stopButton = new JButton();
+			stopButton.setText("Stop");
+			stopButton.setName("stopButton");
+		}
+		return stopButton;
+	}
+
+	/**
+	 * This method initializes restartButton
+	 * 
+	 * @return javax.swing.JButton
+	 */
+	private JButton getRestartButton() {
+		if (restartButton == null) {
+			restartButton = new JButton();
+			restartButton.setText("Restart");
+			restartButton.setName("restartButton");
+		}
+		return restartButton;
+	}
+
+} // @jve:decl-index=0:visual-constraint="10,10"

Added: trunk/src/appl/parallel/starter/client/XuluStarterController.java
===================================================================
--- trunk/src/appl/parallel/starter/client/XuluStarterController.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/client/XuluStarterController.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,140 @@
+package appl.parallel.starter.client;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.rmi.RemoteException;
+import java.util.Vector;
+
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.DefaultListModel;
+import javax.swing.JList;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import appl.parallel.client.RemoteExecutionController;
+import appl.parallel.services.HostnameDiscoveryService;
+import appl.parallel.starter.Starter;
+import appl.parallel.starter.server.XuluServerStarter;
+
+/**
+ * This is the Controller for the {@link XuluStarterControllerFrame}, which is
+ * the user interface for the {@link XuluServerStarter}. All events are handled
+ * here. <br>
+ * 
+ * The controller updates a list of {@link Starter}s it finds in the network.
+ * At the moment is uses the {@link HostnameDiscoveryService} to discover
+ * starters.
+ * 
+ * @see HostnameDiscoveryService#getStarterContainers()
+ * @author Dominik Appl
+ */
+public class XuluStarterController implements ActionListener {
+
+	Logger LOG = LogManager.getLogger(this.getClass().getName());
+
+	private XuluStarterClientPanel GUI;
+
+	private HostnameDiscoveryService discovery;
+
+	private Vector<StarterContainer> currentData;
+
+	/**
+	 * 
+	 */
+	public XuluStarterController() {
+		GUI = new XuluStarterClientPanel();
+		// start simpleDiscovery service
+		discovery = new HostnameDiscoveryService();
+		discovery.startService();
+		updateList();
+		initGUI();
+	}
+
+	private void initGUI() {
+		GUI.startButton.addActionListener(this);
+		GUI.stopButton.addActionListener(this);
+		GUI.refreshButton.addActionListener(this);
+		GUI.restartButton.addActionListener(this);
+	}
+
+	public XuluStarterClientPanel getPanel() {
+		return GUI;
+	}
+
+	/**
+	 * 
+	 */
+	private void updateList() {
+		currentData = discovery.getStarterContainers();
+		GUI.serverList.setCellRenderer(new MyCellRenderer(currentData));
+		// DefaultListModel serverListModel = new DefaultListModel();
+		// GUI.serverList.setModel(serverListModel);
+		GUI.serverList.setListData(currentData);
+	}
+
+	private Starter getSelectedStarter() {
+		Object value = GUI.serverList.getSelectedValue();
+		if (value != null) {
+			return ((StarterContainer) value).getStarter();
+		}
+		return null;
+	}
+
+	public void actionPerformed(ActionEvent e) {
+		if (e.getSource() == GUI.refreshButton) {
+			updateList();
+		}
+		Starter selectedStarter = getSelectedStarter();
+		// if nothing selected: return
+		if (selectedStarter == null)
+			return;
+		try {
+			if (e.getSource() == GUI.startButton) {
+				selectedStarter.start();
+				updateList();
+			}
+			if (e.getSource() == GUI.stopButton) {
+				selectedStarter.stop();
+				updateList();
+			}
+			if (e.getSource() == GUI.restartButton) {
+				selectedStarter.restart();
+				updateList();
+			}
+		} catch (RemoteException e1) {
+			LOG
+					.error(
+							"Could not access selected Starter. Remote Exeception occured.",
+							e1);
+		}
+	}
+
+	class MyCellRenderer extends DefaultListCellRenderer {
+		private final Vector<StarterContainer> containers;
+
+		public MyCellRenderer(Vector<StarterContainer> containers) {
+			this.containers = containers;
+			// TODO Auto-generated constructor stub
+		}
+
+		@Override
+		public Component getListCellRendererComponent(JList list, Object value,
+				int index, boolean isSelected, boolean cellHasFocus) {
+			// TODO Auto-generated method stub
+			Component listCellRendererComponent = super
+					.getListCellRendererComponent(list, value, index,
+							isSelected, cellHasFocus);
+			if (!isSelected) {
+				if (containers.get(index).isServerRunning())
+					listCellRendererComponent.setBackground(Color.green);
+				else
+					listCellRendererComponent.setBackground(Color.red);
+			}
+			return listCellRendererComponent;
+		}
+
+	}
+}

Added: trunk/src/appl/parallel/starter/client/XuluStarterControllerFrame.java
===================================================================
--- trunk/src/appl/parallel/starter/client/XuluStarterControllerFrame.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/client/XuluStarterControllerFrame.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,37 @@
+package appl.parallel.starter.client;
+
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+
+import org.apache.log4j.BasicConfigurator;
+
+import appl.parallel.starter.Starter;
+
+/**
+ * This is a GUI for controlling the {@link Starter Starters} in the network
+ * independent of Xulu.
+ * @author appl
+ *
+ */
+public class XuluStarterControllerFrame extends JFrame {
+	public XuluStarterControllerFrame() {
+		super("Server starter");
+		this.getContentPane().add(new XuluStarterController().getPanel());
+		this.setSize(300, 400);
+		this.addWindowListener(new ExitListener());
+	}
+
+	public static void main(String[] args) {
+		BasicConfigurator.configure();
+		XuluStarterControllerFrame clientGUI = new XuluStarterControllerFrame();
+		clientGUI.setVisible(true);
+	}
+
+	public class ExitListener extends WindowAdapter {
+		public void windowClosing(WindowEvent event) {
+			System.exit(0);
+		}
+	}
+}

Added: trunk/src/appl/parallel/starter/client/XuluStarterControllerPlugin.java
===================================================================
--- trunk/src/appl/parallel/starter/client/XuluStarterControllerPlugin.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/client/XuluStarterControllerPlugin.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,38 @@
+package appl.parallel.starter.client;
+
+import appl.util.XuluFrameAdapter;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.appl.XuluPlugin;
+import edu.bonn.xulu.gui.XuluInternalFrame;
+import edu.bonn.xulu.plugin.appl.AbstractMenuPlugin;
+
+/**
+ * The starter-controller {@link XuluPlugin}.
+ * 
+ * @see XuluStarterController
+ * 
+ * @author Dominik Appl
+ */
+public class XuluStarterControllerPlugin extends AbstractMenuPlugin {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see edu.bonn.xulu.plugin.appl.AbstractMenuPlugin#createPluginApplication()
+	 */
+	@Override
+	protected XuluInternalFrame createPluginApplication() throws Exception {
+		XuluStarterController controller = new XuluStarterController();
+
+		return new XuluFrameAdapter("Xulu/V - Starter control", controller
+				.getPanel());
+	}
+
+	/**
+	 * 
+	 */
+	public XuluStarterControllerPlugin() {
+		super(4, "Xulu/V - Starter control");
+	}
+
+}

Added: trunk/src/appl/parallel/starter/client/package.html
===================================================================
--- trunk/src/appl/parallel/starter/client/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/client/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,6 @@
+<html>
+<body>
+	Contains classes related the client side of the starter functionality. If a programm is executed by a Starter, the
+	execution can be controlled remotely (start/stop/restart the process).
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/starter/package.html
===================================================================
--- trunk/src/appl/parallel/starter/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,6 @@
+<html>
+<body>
+	Contains classes related the starter functionality. If a programm is executed by a Starter, the
+	execution can be controlled remotely (start/stop/restart the process).
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/starter/server/XuluServerStarter.java
===================================================================
--- trunk/src/appl/parallel/starter/server/XuluServerStarter.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/server/XuluServerStarter.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,647 @@
+package appl.parallel.starter.server;
+
+import java.awt.AWTException;
+import java.awt.Image;
+import java.awt.MenuItem;
+import java.awt.PopupMenu;
+import java.awt.SystemTray;
+import java.awt.Toolkit;
+import java.awt.TrayIcon;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.SequenceInputStream;
+import java.rmi.AccessException;
+import java.rmi.Naming;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.UnicastRemoteObject;
+
+import javax.swing.JOptionPane;
+import javax.swing.JTextArea;
+
+import schmitzm.swing.TextAreaPrintStream;
+import schmitzm.swing.event.PopupMenuListener;
+
+import appl.ext.XuluConfig;
+import appl.parallel.ComputingResource;
+import appl.parallel.server.XuluServer;
+import appl.parallel.starter.Starter;
+import appl.parallel.util.Helper;
+import appl.util.GeneralUtil;
+
+/**
+ * A running instance of the XuluServerStarter waits for a signal to start a
+ * {@link XuluServer}. When {@link #start()} is called the Server is started.
+ * All output from the new Serverprocess are forwarded to the actual screen (if
+ * any). The Server can also be {@link #restart() restarted} or
+ * {@link #stop() stopped}. <br>
+ * <br>
+ * For configuration of the XuluServer the {@link XuluConfig} is used. The
+ * following configuration entries are supported <TABLE border="1"
+ * <tr>
+ * <th>Entry</th>
+ * <th>Default</th>
+ * <th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>XuluServerStarter.port</td>
+ * <td>1099</td>
+ * <td> The port which is used for the registry creation (if none is running)</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServerStarter.javaprogram</td>
+ * <td>java</td>
+ * <td> The path to the java program</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServerStarter.codebasedir</td>
+ * <td></td>
+ * <td> The absolute path to the codebase directory (should be the path to the
+ * binaries)</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServerStarter.securitypolicy</td>
+ * <td></td>
+ * <td> The path to the security policy</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServerStarter.furtherjavaarguments</td>
+ * <td></td>
+ * <td> further JVM arguments</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServerStarter.classpath</td>
+ * <td></td>
+ * <td> The libaries needed</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServerStarter.memorymax</td>
+ * <td>64</td>
+ * <td> The maximum memory the XuluSever attempts to use (-xmx)</td>
+ * </tr>
+ * <tr>
+ * <td>XuluServerStarter.memorymin</td>
+ * <td>4</td>
+ * <td> The inital memory the XuluServer uses (-xms)</td>
+ * </tr>
+ * </TABLE>
+ * 
+ * @author Dominik Appl
+ */
+public class XuluServerStarter extends UnicastRemoteObject implements Starter,
+		ActionListener {
+
+	private enum Status {
+		/** server is not started */
+		serverOff,
+		/** * Server is started */
+		serverStarted,
+		/** A client is connected */
+		serverActive
+	}
+
+	private String bindingName = "XuluServerStarter";
+
+	private int port = 1099;
+
+	private String javaprogram = "java";
+
+	private String codebase = "";
+
+	private String securitypolicy = "";
+
+	private String furtherjavaarguments = "";
+
+	private String xuluserverarguments = "";
+
+	private String classpath = "";
+
+	private String XuluServerString = "appl.parallel.server.XuluServer";
+
+	private Process p;
+
+	// private BufferedReader input;
+
+	private SimpleConsoleOutputThread thread;
+
+	private int xms = 64;
+
+	private int xmx = 128;
+
+	private SequenceInputStream twoStreams;
+
+	private XuluStarterServerGUI starterServerGUI;
+
+	private TextAreaPrintStream textAreaOutput;
+
+	private MenuItem menu_exit;
+
+	private MenuItem menu_start;
+
+	private MenuItem menu_stop;
+
+	private MenuItem menu_showConsole;
+
+	private TrayIcon trayIcon;
+
+	private ComputingResource xuluServer;
+
+	private Image redIcon;
+
+	private Image greenIcon;
+
+	private Image yellowIcon;
+
+	private String cmd;
+
+	/**
+	 * @param cmd
+	 *            the command to be executed by the starter. If null, the
+	 *            XuluConfig is used to create the commandline
+	 * @param showGUI
+	 *            if false, no GUI/Tray is shown
+	 * @throws RemoteException
+	 */
+	private XuluServerStarter(String cmd, boolean showGUI)
+			throws RemoteException {
+		super();
+		this.cmd = cmd;
+		this.bind(bindingName, this, port);
+		if (showGUI) {
+			redIcon = Toolkit.getDefaultToolkit().getImage(
+					"resource/xulu_icon_red.gif");
+			greenIcon = Toolkit.getDefaultToolkit().getImage(
+					"resource/xulu_icon_green.gif");
+			yellowIcon = Toolkit.getDefaultToolkit().getImage(
+					"resource/xulu_icon_yellow.gif");
+			createGUI();
+			createTray();
+			setStatus(Status.serverOff);
+		}
+	}
+
+	/**
+	 * Should be called if the status has changed (changes tray icon)
+	 * 
+	 * @param newStatus
+	 *            the new status
+	 */
+	private void setStatus(Status newStatus) {
+		// if tray disabled: return
+		if (trayIcon == null)
+			return;
+		switch (newStatus) {
+		case serverOff:
+			trayIcon.setImage(redIcon);
+			trayIcon.setToolTip("XuluServer is disabled");
+			break;
+		case serverStarted:
+			trayIcon.setImage(greenIcon);
+			trayIcon.setToolTip("Xulu Server is ready and waiting for tasks");
+			break;
+		case serverActive:
+			trayIcon.setImage(yellowIcon);
+			trayIcon.setToolTip("A client is connected to the XuluServer");
+			break;
+		}
+	}
+
+	/**
+	 * creates and inits the tray icon.
+	 */
+	private void createTray() {
+
+		if (SystemTray.isSupported()) {
+
+			SystemTray tray = SystemTray.getSystemTray();
+			Image image = Toolkit.getDefaultToolkit().getImage(
+					"temp/xulu_icon.gif");
+
+			// create menu entries
+			PopupMenu popup = new PopupMenu();
+			menu_exit = new MenuItem("Exit");
+			menu_start = new MenuItem("Start Server");
+			menu_stop = new MenuItem("Stop Server");
+			menu_showConsole = new MenuItem("Show contol window");
+			menu_exit.addActionListener(this);
+			menu_start.addActionListener(this);
+			menu_stop.addActionListener(this);
+			menu_showConsole.addActionListener(this);
+
+			popup.add(menu_start);
+			popup.add(menu_stop);
+			popup.add(menu_showConsole);
+			popup.add(menu_exit);
+			trayIcon = new TrayIcon(image, "Xulu Server", popup);
+			trayIcon.setImageAutoSize(true);
+			trayIcon.addMouseListener(new MouseAdapter() {
+				// on doubleclick popup the control-window
+				public void mouseClicked(MouseEvent e) {
+					if (e.getClickCount() > 1) {
+						starterServerGUI.setVisible(!starterServerGUI
+								.isVisible());
+					}
+				}
+			});
+
+			try {
+				tray.add(trayIcon);
+			} catch (AWTException e) {
+				System.err.println("TrayIcon could not be added.");
+				tray = null;
+			}
+
+		} else {
+			// System Tray is not supported
+			System.out.println("System Tray not supported"); 
+			trayIcon = null;
+		}
+
+	}
+
+	/**
+	 * creates the GUI for the Starter
+	 */
+	private void createGUI() {
+		// create new GUI
+		starterServerGUI = new XuluStarterServerGUI();
+		// register this instance as button listener
+		starterServerGUI.button_exit.addActionListener(this);
+		starterServerGUI.button_start.addActionListener(this);
+		starterServerGUI.button_stop.addActionListener(this);
+
+		// register TextArea as OutputStream
+		textAreaOutput = new TextAreaPrintStream(starterServerGUI.consoleArea);
+		System.setErr(textAreaOutput);
+		System.setOut(textAreaOutput);
+
+	}
+
+	/**
+	 * reads the configuration out of the {@link XuluConfig}
+	 */
+	private void loadConfig() {
+		XuluConfig config = XuluConfig.getXuluConfig();
+		if (config.getIntProperty("XuluServerStarter.port") != 0)
+			port = config.getIntProperty("XuluServerStarter.port");
+		if (config.getProperty("XuluServerStarter.javaprogram") != null)
+			javaprogram = config.getProperty("XuluServerStarter.javaprogram");
+		if (config.getProperty("XuluServerStarter.codebasedir") != null)
+			codebase = config.getProperty("XuluServerStarter.codebasedir");
+		if (config.getProperty("XuluServerStarter.securitypolicy") != null)
+			securitypolicy = config
+					.getProperty("XuluServerStarter.securitypolicy");
+		if (config.getProperty("XuluServerStarter.furtherjavaarguments") != null)
+			furtherjavaarguments = config
+					.getProperty("XuluServerStarter.furtherjavaarguments");
+		if (config.getProperty("XuluServerStarter.classpath") != null)
+			classpath = config.getProperty("XuluServerStarter.classpath");
+		if (config.getProperty("XuluServerStarter.memorymax") != null)
+			xmx = config.getIntProperty("XuluServerStarter.memorymax");
+		if (config.getProperty("XuluServerStarter.memorymin") != null)
+			xms = config.getIntProperty("XuluServerStarter.memorymin");
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.starter.Starter#restart()
+	 */
+	public void restart() throws RemoteException {
+		this.stop();
+		this.start();
+	}
+
+	/**
+	 * Creates the Java commandline and starts the {@link XuluServer}
+	 * 
+	 * @see appl.parallel.starter.Starter#start()
+	 */
+	public void start() throws RemoteException {
+		loadConfig();
+		try {
+			if (p != null) {
+				System.out
+						.println("Process is already running. Stop process first");
+				return;
+			}
+			String commandline = "\"" + javaprogram + "\"" + " -cp \""
+					+ codebase;
+			if (!(classpath.equals("")))
+				commandline += (";" + classpath);
+			commandline += "\" ";
+			if (xms != 0)
+				commandline += (" -Xms" + xms + "M ");
+			if (xmx != 0)
+				commandline += (" -Xmx" + xmx + "M ");
+
+			commandline += (" -Djava.rmi.server.codebase=file:///" + codebase
+					+ " -Djava.security.policy=" + securitypolicy + " "
+					+ furtherjavaarguments + " " + XuluServerString + " " + xuluserverarguments);
+			// if there is a user commandline, use this instead
+			if (cmd != null)
+				commandline = cmd;
+			System.out.println("Executing commandline: " + commandline);
+			p = Runtime.getRuntime().exec(commandline);
+			xuluServer = null;
+			// forward the inputstream of the new process to the
+			// console/textarea
+			InputStream standardInput = p.getInputStream();
+			InputStream errorInput = p.getErrorStream();
+			thread = new SimpleConsoleOutputThread(standardInput, errorInput);
+			thread.startThread();
+			// wait until the server is bound to the registry
+			Thread.sleep(5000);
+			// lookup the new Server
+			xuluServer = (ComputingResource) Naming
+					.lookup("rmi://localhost/XuluServer");
+			setStatus(Status.serverStarted);
+			System.out
+					.println("The Starter has successfully discovered the XuluServer instance");
+
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (NotBoundException e) {
+			System.out
+					.println("Could not find the Xulu server instance(NotBoundException).\n Creation of the XuluServer failed..please correct the commandline...");
+
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see appl.parallel.starter.Starter#stop()
+	 */
+	public void stop() throws RemoteException {
+		try {
+			if (twoStreams != null)
+				twoStreams.close();
+			if (thread != null)
+				thread.stopThread();
+			// if (input != null)
+			// input.close();
+			if (p != null)
+				p.destroy();
+			p = null;
+			System.out.println("Process stopped");
+			this.setStatus(Status.serverOff);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Starts the XuluServerStarter <br/> The parameter -start can be used to
+	 * start the Server at launch of the Starter. <br>
+	 * The parameter -cmd <command> will use the given command to try to start
+	 * the server. Else the XuluConfig will be used. <br>
+	 * The parameter -noGUI forces the starter to not use any GUI functionality.
+	 */
+	public static void main(String[] args) {
+		try {
+			System.out
+					.println("Use the parameter -help to see all available commandline options");
+			String cmd = null;
+			boolean noGUI = false;
+			boolean start = false;
+			// search for command parameter
+			for (int i = 0; i < args.length; i++) {
+				if (args[i].toLowerCase().equals("-cmd") && i < args.length)
+					cmd = args[i + 1];
+				if (args[i].toLowerCase().equals("-nogui") && i < args.length)
+					noGUI = true;
+				if (args[i].toLowerCase().equals("-start"))
+					start = true;
+				if (args[i].toLowerCase().equals("-help"))
+					printHelp();
+			}
+			XuluServerStarter starter = new XuluServerStarter(cmd, !noGUI);
+			System.out.println("XuluServerStarter initialized .... ");
+			if (start) {
+				starter.start();
+			}
+			if (!starter.isRunning()) {
+				System.out
+						.println("Hint: use parameter '-start' to start the server directly");
+			}
+		} catch (RemoteException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * 
+	 */
+	private static void printHelp() {
+		System.out
+				.println("The following commands can be used: \n\n"
+						+ "-start can be used to start the Server at launch of the Starter.\n"
+						+ "-cmd <command> will use the given command to try to start the server."
+						+ " Else the XuluConfig will be used.\n"
+						+ "-noGUI doesn't use any GUI functionality.\n"
+						+ "-help displays this help");
+
+	}
+
+	public boolean isRunning() throws RemoteException {
+		return (p != null);
+
+	}
+
+	/**
+	 * Copied from {@link Helper} and modified so that it does not depend on
+	 * log4j. Binds the remote object's stub in the registry. Creates a registry
+	 * if no running registry is found.
+	 * 
+	 * @param bindingName
+	 *            the name to be used for binding
+	 * @param bindingInstance
+	 *            an instance of the type to bind to the registry
+	 * @param defaultPort
+	 *            the default registry port
+	 * @throws RemoteException
+	 *             if something goes wrong
+	 */
+	public void bind(String bindingName, Remote bindingInstance, int defaultPort)
+			throws RemoteException {
+		boolean failed = true;
+		Registry registry;
+		try {
+			registry = LocateRegistry.getRegistry();
+			registry.rebind(bindingName, bindingInstance);
+			failed = false;
+		} catch (AccessException e) {
+			System.err.println("Not enough permissions to bind" + bindingName
+					+ "to the registry! Adjust your security permission file!");
+			e.printStackTrace();
+		} catch (RemoteException e) {
+			if (e instanceof java.rmi.ConnectException) {
+				System.out
+						.println("Could not connect to registry! Trying to create new one...");
+				try {
+					registry = LocateRegistry.createRegistry(defaultPort);
+					registry.rebind(bindingName, bindingInstance);
+					System.out.println("Registry successfully created at port "
+							+ defaultPort);
+					failed = false;
+				} catch (RemoteException e1) {
+					// TODO Auto-generated catch block
+					e1.printStackTrace();
+				}
+			} else
+				e.printStackTrace();
+		}
+		if (failed)
+			throw new RemoteException("Could not find or create registry!");
+	}
+
+	/**
+	 * The Thread is used to direct the output of the process to System.out.
+	 * Notice that this stream may be redirected to a
+	 * {@link TextAreaPrintStream} or any other printstream using
+	 * {@link System#setOut(java.io.PrintStream)}
+	 * 
+	 * @author appl
+	 */
+	class SimpleConsoleOutputThread implements Runnable {
+		private volatile Thread outputThread;
+
+		private boolean exit;
+
+		private final InputStream standardInput;
+
+		private final InputStream errorInput;
+
+		private final BufferedReader input;
+
+		private final SequenceInputStream twoStreams;
+
+		private boolean availableLastTime = false;
+
+		/**
+		 * Creates a new thread. The parmeters are the inputstreams which should
+		 * be forwarded to System.out
+		 * 
+		 * @param standardInput
+		 * @param errorInput
+		 */
+		public SimpleConsoleOutputThread(InputStream standardInput,
+				InputStream errorInput) {
+			this.standardInput = standardInput;
+			this.errorInput = errorInput;
+			// combine the streams
+			twoStreams = new SequenceInputStream(standardInput, errorInput);
+			input = new BufferedReader(new InputStreamReader(twoStreams));
+		}
+
+		public void startThread() {
+			exit = false;
+			if (outputThread == null)
+				outputThread = new Thread(this);
+			outputThread.start();
+		}
+
+		public void stopThread() {
+			exit = true;
+			outputThread.interrupt();
+			try {
+				input.close();
+			} catch (IOException e) {
+				System.out.println("Input closed");
+				e.printStackTrace();
+			}
+		}
+
+		public void run() {
+			String line;
+			while (exit == false) {
+				try {
+					while (input.ready()) {
+						line = input.readLine();
+						System.out.println(line);
+					}
+					Thread.sleep(1000);
+					// check if server is active for tray icon change
+					if (xuluServer != null)
+						if (availableLastTime != xuluServer.isAvailable()) {
+							if (availableLastTime)
+								setStatus(Status.serverActive);
+							else
+								setStatus(Status.serverStarted);
+							availableLastTime = (!availableLastTime);
+						}
+
+				} catch (IOException e) {
+					System.out
+							.println("Connection to server failed. Input closed");
+					e.printStackTrace();
+					exit = true;
+				} catch (InterruptedException e) {
+					if (exit == true)
+						System.out.println("Stopped output thread...");
+				}
+			}
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+	 */
+	public void actionPerformed(ActionEvent e) {
+		if (e.getSource() == starterServerGUI.button_stop
+				|| e.getSource() == menu_stop) {
+			try {
+				this.stop();
+			} catch (Exception e1) {
+				System.out
+						.println("Could not stop the Server. Reason follows: ");
+				e1.printStackTrace();
+			}
+		} else if (e.getSource() == starterServerGUI.button_exit
+				|| e.getSource() == menu_exit) {
+			// if user does not confirm: return.
+			if (JOptionPane
+					.showConfirmDialog(
+							starterServerGUI,
+							"Are you sure that you want to exit the Starter-Application?",
+							"Confirm exit", JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION)
+				return;
+			try {
+				this.stop();
+			} catch (RemoteException e1) {
+			}
+			System.exit(1);
+
+		} else if (e.getSource() == starterServerGUI.button_start
+				|| e.getSource() == menu_start) {
+			try {
+				this.start();
+			} catch (Exception e1) {
+				System.out
+						.println("Could not start the Server. Reason follows: ");
+				e1.printStackTrace();
+			}
+		} else if (e.getSource() == menu_showConsole) {
+			starterServerGUI.setVisible(true);
+		}
+
+	}
+}

Added: trunk/src/appl/parallel/starter/server/XuluStarterServerGUI.java
===================================================================
--- trunk/src/appl/parallel/starter/server/XuluStarterServerGUI.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/server/XuluStarterServerGUI.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,294 @@
+package appl.parallel.starter.server;
+
+import java.awt.BorderLayout;
+import javax.swing.JPanel;
+import javax.swing.JFrame;
+import java.awt.GridBagLayout;
+import javax.swing.JTextArea;
+import javax.swing.JLabel;
+import javax.swing.JButton;
+import java.awt.GridBagConstraints;
+import java.awt.Dimension;
+import javax.swing.JScrollPane;
+import javax.swing.BoxLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JPopupMenu;
+import javax.swing.JMenuItem;
+
+import schmitzm.swing.event.PopupMenuListener;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+import java.awt.CardLayout;
+
+/**
+ * This is the GUI for the {@link XuluServerStarter}
+ * 
+ * @author Dominik Appl
+ */
+public class XuluStarterServerGUI extends JFrame {
+
+	private static final long serialVersionUID = 1L;
+
+	private JPanel jContentPane = null;
+
+	private JPanel controlPanel = null;
+
+	 JTextArea consoleArea = null;
+
+	JButton button_start = null;
+
+	 JButton button_stop = null;
+
+	 JButton button_exit = null;
+
+	private JScrollPane jScrollPane = null;
+
+	private JPopupMenu jPopupMenu = null;  //  @jve:decl-index=0:visual-constraint="615,231"
+
+	private JMenuItem clearText = null;
+
+	private JPanel jPanel = null;
+
+	private JButton button_clear = null;
+
+	/**
+	 * This is the default constructor
+	 */
+	public XuluStarterServerGUI() {
+		super();
+		initialize();
+	}
+
+	/**
+	 * This method initializes this
+	 * 
+	 * @return void
+	 */
+	private void initialize() {
+		this.setSize(450, 316);
+		this.setContentPane(getJContentPane());
+		this.setTitle("Xulu Server Starter");
+	}
+
+	/**
+	 * This method initializes jContentPane
+	 * 
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJContentPane() {
+		if (jContentPane == null) {
+			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
+			gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
+			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
+			gridBagConstraints6.gridx = 0;
+			gridBagConstraints6.ipadx = 140;
+			gridBagConstraints6.gridy = 2;
+			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
+			gridBagConstraints5.fill = GridBagConstraints.BOTH;
+			gridBagConstraints5.gridy = 1;
+			gridBagConstraints5.ipadx = 0;
+			gridBagConstraints5.ipady = 0;
+			gridBagConstraints5.weightx = 1.0;
+			gridBagConstraints5.weighty = 1.0;
+			gridBagConstraints5.insets = new Insets(0, 5, 0, 5);
+			gridBagConstraints5.gridx = 0;
+			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
+			gridBagConstraints3.gridx = 0;
+			gridBagConstraints3.ipadx = 0;
+			gridBagConstraints3.ipady = 0;
+			gridBagConstraints3.fill = GridBagConstraints.HORIZONTAL;
+			gridBagConstraints3.gridy = 5;
+			jContentPane = new JPanel();
+			jContentPane.setLayout(new GridBagLayout());
+			jContentPane.add(getJScrollPane(), gridBagConstraints5);
+			jContentPane.add(getControlPanel(), gridBagConstraints6);
+			jContentPane.add(getJPanel(), gridBagConstraints8);
+		}
+		return jContentPane;
+	}
+
+	/**
+	 * This method initializes controlPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getControlPanel() {
+		if (controlPanel == null) {
+			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
+			gridBagConstraints11.fill = GridBagConstraints.BOTH;
+			gridBagConstraints11.gridy = 3;
+			gridBagConstraints11.weightx = 1.0;
+			gridBagConstraints11.weighty = 1.0;
+			gridBagConstraints11.gridx = 0;
+			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
+			gridBagConstraints2.gridx = 3;
+			gridBagConstraints2.anchor = GridBagConstraints.EAST;
+			gridBagConstraints2.gridy = 1;
+			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+			gridBagConstraints1.gridx = 2;
+			gridBagConstraints1.anchor = GridBagConstraints.WEST;
+			gridBagConstraints1.gridy = 1;
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.gridx = 0;
+			gridBagConstraints.anchor = GridBagConstraints.WEST;
+			gridBagConstraints.gridy = 1;
+			controlPanel = new JPanel();
+			controlPanel.setLayout(new GridBagLayout());
+			controlPanel.add(getButton_start(), gridBagConstraints);
+			controlPanel.add(getButton_stop(), gridBagConstraints1);
+			controlPanel.add(getButton_exit(), gridBagConstraints2);
+		}
+		return controlPanel;
+	}
+
+	/**
+	 * This method initializes consoleArea	
+	 * 	
+	 * @return javax.swing.JTextArea	
+	 */
+	private JTextArea getConsoleArea() {
+		if (consoleArea == null) {
+			consoleArea = new JTextArea();
+			consoleArea.setToolTipText("");
+			consoleArea.setWrapStyleWord(false);
+			consoleArea.setLineWrap(true);
+			consoleArea.addMouseListener(new PopupMenuListener(this.getJPopupMenu()));
+		}
+		return consoleArea;
+	}
+
+	/**
+	 * This method initializes button_start	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getButton_start() {
+		if (button_start == null) {
+			button_start = new JButton();
+			button_start.setText("Start Server");
+		}
+		return button_start;
+	}
+
+	/**
+	 * This method initializes button_stop	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getButton_stop() {
+		if (button_stop == null) {
+			button_stop = new JButton();
+			button_stop.setText("Stop Server");
+		}
+		return button_stop;
+	}
+
+	/**
+	 * This method initializes button_exit	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getButton_exit() {
+		if (button_exit == null) {
+			button_exit = new JButton();
+			button_exit.setText("Exit Starter");
+		}
+		return button_exit;
+	}
+
+	/**
+	 * This method initializes jScrollPane	
+	 * 	
+	 * @return javax.swing.JScrollPane	
+	 */
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setDoubleBuffered(false);
+			jScrollPane.setViewportView(getConsoleArea());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes jPopupMenu	
+	 * 	
+	 * @return javax.swing.JPopupMenu	
+	 */
+	private JPopupMenu getJPopupMenu() {
+		if (jPopupMenu == null) {
+			jPopupMenu = new JPopupMenu();
+			jPopupMenu.add(getClearText());
+
+			
+		}
+		return jPopupMenu;
+	}
+
+	/**
+	 * This method initializes clearText	
+	 * 	
+	 * @return javax.swing.JMenuItem	
+	 */
+	private JMenuItem getClearText() {
+		if (clearText == null) {
+			clearText = new JMenuItem();
+			clearText.setText("clear");
+			clearText.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					getConsoleArea().setText("");
+				}
+			});
+		}
+		return clearText;
+	}
+
+	/**
+	 * This method initializes jPanel	
+	 * 	
+	 * @return javax.swing.JPanel	
+	 */
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			FlowLayout flowLayout = new FlowLayout();
+			flowLayout.setHgap(0);
+			flowLayout.setVgap(0);
+			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
+			gridBagConstraints9.gridx = 0;
+			gridBagConstraints9.anchor = GridBagConstraints.EAST;
+			gridBagConstraints9.gridy = 0;
+			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
+			gridBagConstraints4.gridy = -1;
+			gridBagConstraints4.anchor = GridBagConstraints.WEST;
+			gridBagConstraints4.gridx = -1;
+			jPanel = new JPanel();
+			jPanel.setLayout(flowLayout);
+			jPanel.add(getButton_clear(), null);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes button_clear	
+	 * 	
+	 * @return javax.swing.JButton	
+	 */
+	private JButton getButton_clear() {
+		if (button_clear == null) {
+			button_clear = new JButton();
+			button_clear.setText("Clear Console");
+			button_clear.setPreferredSize(new Dimension(130, 15));
+			button_clear.setName("jButton");
+			button_clear.addActionListener(new java.awt.event.ActionListener() {
+				public void actionPerformed(java.awt.event.ActionEvent e) {
+					getConsoleArea().setText("");
+				}
+			});
+		}
+		return button_clear;
+	}
+
+}  //  @jve:decl-index=0:visual-constraint="10,10"

Added: trunk/src/appl/parallel/starter/server/package.html
===================================================================
--- trunk/src/appl/parallel/starter/server/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/starter/server/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,6 @@
+<html>
+<body>
+	Contains classes related the server side of the starter functionality. If a programm is executed by a Starter, the
+	execution can be controlled remotely (start/stop/restart the process).
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/test/AverageNeighborhoodTestTask.java
===================================================================
--- trunk/src/appl/parallel/test/AverageNeighborhoodTestTask.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/AverageNeighborhoodTestTask.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,80 @@
+package appl.parallel.test;
+
+import java.awt.Rectangle;
+
+import schmitzm.data.WritableGrid;
+import appl.parallel.spmd.AbstractSPMDTask;
+import appl.parallel.spmd.SPMDServerInterface;
+import appl.util.RasterUtil;
+
+/**
+ * @author Dominik Appl
+ */
+public class AverageNeighborhoodTestTask extends AbstractSPMDTask {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 13L;
+
+    /* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDTask#run()
+	 */
+	public Object run(Object...parameters) {
+		
+		SPMDServerInterface controller = getSPMDServerController();
+		WritableGrid gridInput = (WritableGrid) controller
+				.getPartition("inputGrid");
+		WritableGrid gridOutput = (WritableGrid) controller
+				.getPartition("outputGrid");
+		int neighborhoodRange = (Integer) parameters[0];
+		/********************** START REMOTE ALGORITHM *********************
+		 * start the calculation (notice that only the outer loop variables have changed)
+		 * *****************************************************************/
+		float overallSum = 0;
+		Rectangle partition = controller.getLocalBounds();
+		//System.out.println("290,64: " + gridInput.getRasterSampleAsFloat(controller.getLocalCalcMinX()+289,64));
+		for (int y = controller.getLocalCalcMinY(); y < controller
+				.getLocalCalcMaxY() + 1; y++)
+			for (int x = controller.getLocalCalcMinX(); x < controller
+					.getLocalCalcMaxX() + 1; x++) {
+				float tmp = gridInput.getRasterSampleAsFloat(x,y);
+				if(!Float.isNaN(tmp))
+					overallSum += tmp;
+				//the local sum is simply the sum over all elements in the neighborhood
+				float localSum = 0;
+				//number of cells over which the sum is calculated
+				int noOfCells = 0;
+				//for each cell: calculate the sum of all neighbors
+				for (int y2 = y - neighborhoodRange; y2 <= y
+						+ neighborhoodRange; y2++)
+					for (int x2 = x - neighborhoodRange; x2 <= x
+							+ neighborhoodRange; x2++)
+						//check if the coordinates are valid (inside the grid and not NaN)
+						if (partition.contains(x2, y2))
+							if (!Float.isNaN(gridInput
+									.getRasterSampleAsFloat(x2, y2))) {
+								localSum += gridInput.getRasterSampleAsFloat(
+										x2, y2);
+								noOfCells++;
+							}
+				gridOutput.setRasterSample(localSum / (float) (noOfCells), x,y);
+
+			}
+	//copy values into results from output to input (for next step)
+	RasterUtil.copyInto(gridOutput, gridInput);
+	return overallSum;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.AbstractSPMDTask#init()
+	 */
+	@Override
+	public void init() {
+		// TODO Auto-generated method stub
+		
+	}
+
+	
+	
+}
\ No newline at end of file

Added: trunk/src/appl/parallel/test/AverageNeighborhoodTestTask_MultiGrid.java
===================================================================
--- trunk/src/appl/parallel/test/AverageNeighborhoodTestTask_MultiGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/AverageNeighborhoodTestTask_MultiGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,89 @@
+package appl.parallel.test;
+
+import java.awt.Rectangle;
+
+import schmitzm.data.WritableGrid;
+import appl.parallel.spmd.AbstractSPMDTask;
+import appl.parallel.spmd.SPMDServerInterface;
+import appl.parallel.spmd.split.DataPartition;
+import appl.util.RasterUtil;
+
+/**
+ * @author Dominik Appl
+ */
+public class AverageNeighborhoodTestTask_MultiGrid extends AbstractSPMDTask {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 13L;
+
+    /* (non-Javadoc)
+	 * @see appl.parallel.spmd.SPMDTask#run()
+	 */
+	public Object run(Object...parameters) {
+		SPMDServerInterface controller = getSPMDServerController();
+//		WritableGrid gridInput = (WritableGrid) controller
+//				.getPartition("inputGrid");
+//		WritableGrid gridOutput = (WritableGrid) controller
+//				.getPartition("outputGrid");
+		
+		
+//		WritableGrid gridInput = (WritableGrid) controller
+//		.getMultiPartition("gridData",0);
+//		WritableGrid gridOutput = (WritableGrid) controller
+//		.getMultiPartition("gridData",1);
+//		
+		DataPartition[] gridData = (DataPartition[]) controller.getMultiPartition("gridData");
+		WritableGrid gridInput = (WritableGrid) gridData[0]; 
+		WritableGrid gridOutput = (WritableGrid) gridData[1];
+		
+		int neighborhoodRange = (Integer) parameters[0];
+		/********************** START REMOTE ALGORITHM *********************
+		 * start the calculation (notice that only the outer loop variables have changed)
+		 * *****************************************************************/
+		float overallSum = 0;
+		Rectangle partition = controller.getLocalBounds();
+		//System.out.println("290,64: " + gridInput.getRasterSampleAsFloat(controller.getLocalCalcMinX()+289,64));
+		for (int y = controller.getLocalCalcMinY(); y < controller
+				.getLocalCalcMaxY() + 1; y++)
+			for (int x = controller.getLocalCalcMinX(); x < controller
+					.getLocalCalcMaxX() + 1; x++) {
+				float tmp = gridInput.getRasterSampleAsFloat(x,y);
+				if(!Float.isNaN(tmp))
+					overallSum += tmp;
+				//the local sum is simply the sum over all elements in the neighborhood
+				float localSum = 0;
+				//number of cells over which the sum is calculated
+				int noOfCells = 0;
+				//for each cell: calculate the sum of all neighbors
+				for (int y2 = y - neighborhoodRange; y2 <= y
+						+ neighborhoodRange; y2++)
+					for (int x2 = x - neighborhoodRange; x2 <= x
+							+ neighborhoodRange; x2++)
+						//check if the coordinates are valid (inside the grid and not NaN)
+						if (partition.contains(x2, y2))
+							if (!Float.isNaN(gridInput
+									.getRasterSampleAsFloat(x2, y2))) {
+								localSum += gridInput.getRasterSampleAsFloat(
+										x2, y2);
+								noOfCells++;
+							}
+				gridOutput.setRasterSample(localSum / (float) (noOfCells), x,y);
+
+			}
+	//copy values into results from output to input (for next step)
+	RasterUtil.copyInto(gridOutput, gridInput);
+	return overallSum;
+	}
+
+	/* (non-Javadoc)
+	 * @see appl.parallel.spmd.AbstractSPMDTask#init()
+	 */
+	@Override
+	public void init() {
+		// TODO Auto-generated method stub
+		
+	}
+	
+}
\ No newline at end of file

Added: trunk/src/appl/parallel/test/MulticastSocketTest.java
===================================================================
--- trunk/src/appl/parallel/test/MulticastSocketTest.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/MulticastSocketTest.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,35 @@
+package appl.parallel.test;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.UnknownHostException;
+
+public class MulticastSocketTest {
+	public static void main( String[] args ) throws IOException
+	  {
+	
+		 String msg = "Hello";
+		 InetAddress group = InetAddress.getByName("224.0.0.1");
+		 MulticastSocket s = new MulticastSocket(50000);
+		 s.joinGroup(group);
+		 DatagramPacket hi = new DatagramPacket(msg.getBytes(), msg.length(),
+		                             group, 6789);
+		 System.out.println("sending");
+		 s.send(hi);
+		 // get their responses!
+		 System.out.println("waiting");
+		 byte[] buf = new byte[1000];
+		 
+		 DatagramPacket recv = new DatagramPacket(buf, buf.length);
+		 s.receive(recv);
+		 System.out.println("finished");
+		 // OK, I'm done talking - leave the group...
+		 s.leaveGroup(group);
+		 
+	  	}
+
+}
+

Added: trunk/src/appl/parallel/test/PartitialGridTest.java
===================================================================
--- trunk/src/appl/parallel/test/PartitialGridTest.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/PartitialGridTest.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,66 @@
+package appl.parallel.test;
+
+
+import java.awt.Rectangle;
+import java.io.File;
+import java.io.FileNotFoundException;
+import appl.parallel.spmd.split.WritableGridPartition;
+import appl.parallel.util.PartitionUtil;
+import appl.util.RasterUtil;
+import schmitzm.data.WritableGridRaster;
+import schmitzm.geotools.io.GeoExportUtil;
+import schmitzm.geotools.io.GeoImportUtil;
+
+/**
+ * Simple JUnit Test
+ * @author Dominik Appl
+ */
+public class PartitialGridTest {
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	public void setUp() throws Exception {
+	}
+
+	/**
+	 * @throws java.lang.Exception
+	 */
+	public void tearDown() throws Exception {
+	}
+
+	/**
+	 * Test method for {@link appl.parallel.util.PartitionUtil#getPartitialGrid2D(schmitzm.data.WritableGrid, Rectangle, int)}.
+	 */
+	public void testGetPartitialGrid2D() {
+		WritableGridRaster baseGrid;
+		try {
+			baseGrid = GeoImportUtil
+					.readGridRasterFromArcInfoASCII(new File(
+							"../Xulu-Data/minigrid.arc"));
+			GeoExportUtil.writeGridRasterToArcInfoASCII(baseGrid, new File(
+					"TEST_getpartitialgrid2d_o1"));
+			RasterUtil.printGrid(baseGrid, 4, 0, "base partition");
+			//make five partitions: four quarters and one inner partition
+					RasterUtil.printGrid(PartitionUtil.getPartitialGrid2D(baseGrid, new Rectangle(0, 0, 5, 5),0),4,0, "upperleft partition");
+					RasterUtil.printGrid(PartitionUtil.getPartitialGrid2D(baseGrid,new Rectangle( 5, 0, 5, 5),0),4,0, "upperright partition");
+					RasterUtil.printGrid(PartitionUtil.getPartitialGrid2D(baseGrid, new Rectangle(0, 5, 5, 5),0),4,0, "lowerleft partition");
+					RasterUtil.printGrid(PartitionUtil.getPartitialGrid2D(baseGrid, new Rectangle(5, 5, 5, 5),0),4,0, "lowerright partition");
+					WritableGridPartition baseGrid2 = PartitionUtil.getPartitialGrid2D(baseGrid,new Rectangle( 0, 0, 10, 10),0);
+					System.out.println("********************* Starting test 2 *********************");
+					RasterUtil.printGrid(baseGrid2,5,0, "baseGrid2");
+					WritableGridPartition baseGrid2partition = PartitionUtil.getPartitialGrid2D(baseGrid, new Rectangle(0, 0, 5, 5),0);
+					RasterUtil.printGrid(baseGrid2partition,5,0, "baseGrid2 partition");
+					baseGrid2.setPartition(baseGrid2partition, new Rectangle(1,1,5,5));
+					RasterUtil.printGrid(baseGrid2,5,0, "baseGrid2 (after setting baseGrid2-partition to (1,1)");
+
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+}

Added: trunk/src/appl/parallel/test/PingTestObject.java
===================================================================
--- trunk/src/appl/parallel/test/PingTestObject.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/PingTestObject.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,23 @@
+package appl.parallel.test;
+
+import java.io.Serializable;
+
+/**
+ * Simply constructs a object with a given size which can be used for pinging.
+ * @author Dominik Appl
+ */
+public class PingTestObject implements Serializable {
+	byte[] data = null;
+	
+	
+	/**
+	 * @param bytes pingobject size in bytes
+	 */
+	public PingTestObject(int bytes)
+{
+		data = new byte[bytes];
+		for (int i = 0; i < data.length; i++) {
+			data[i]=(byte) i;
+		}}
+
+}

Added: trunk/src/appl/parallel/test/SPMDTest.java
===================================================================
--- trunk/src/appl/parallel/test/SPMDTest.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/SPMDTest.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,250 @@
+package appl.parallel.test;
+
+import java.awt.Rectangle;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.Serializable;
+import java.util.Random;
+import java.util.Vector;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Layout;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+import schmitzm.data.WritableGridRaster;
+import schmitzm.geotools.io.GeoImportUtil;
+
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.client.RemoteEventHandler;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.data.splittable.SplittableLLProxyGrid;
+import appl.parallel.services.GlobalDiscoveryService;
+import appl.parallel.spmd.AbstractSPMDTask;
+import appl.parallel.spmd.SPMDClientController;
+import appl.parallel.spmd.SPMDTask;
+import appl.parallel.spmd.SPMDServerController;
+import appl.parallel.spmd.split.SplittableGrid;
+import appl.util.RasterMetaData;
+import appl.util.RasterUtil;
+
+/**
+ * Generated code for the test suite <b>SPMDTest</b> located at
+ * <i>/XuluSVN/javasrc/appl/parallel/test/SPMDTest.testsuite</i>. This class
+ * tests all the SPMD functionality, using only XULU/V and nearly nothing of
+ * XULU
+ */
+public class SPMDTest extends TestCase implements Serializable {
+
+	transient private final Logger LOG = LogManager.getLogger(this.getClass()
+			.getName());
+
+	transient private ClientDataServer client;
+	transient private Vector<ComputingResourceContainer> computingResources;
+	transient private SPMDClientController clientController;
+
+	transient SplittableGrid gridInput;
+	transient SplittableGrid remoteInput;
+	transient SplittableGrid localOutput;
+	transient SplittableGrid remoteOutput;
+
+	/**
+	 * Constructor for SPMDTest.
+	 * 
+	 * @param name
+	 */
+	public SPMDTest(String name) {
+		super(name);
+	}
+
+	/**
+	 * Returns the JUnit test suite that implements the <b>SPMDTest</b>
+	 * definition.
+	 */
+	public static Test suite() {
+		TestSuite sPMDTest = new TestSuite("SPMDTest");
+//		sPMDTest.setArbiter(DefaultTestArbiter.INSTANCE).setId(
+//				"E873D66A70977ED2A98AAC10B54511DB");
+//
+//		sPMDTest.addTest(new SPMDTest("testSPMD").setId(
+//				"E873D66A70977ED2E5E8ED20B54511DB").setTestInvocationId(
+//				"E873D66A70977ED2EF7E3C00B54511DB"));
+		return sPMDTest;
+	}
+
+	/**
+	 * @see junit.framework.TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		PropertyConfigurator.configure("xululog4j.cfg");
+		computingResources = new GlobalDiscoveryService()
+				.getRemoteResources();
+
+		for (ComputingResourceContainer computingRes : computingResources) {
+			System.out.println("DiscoveredRessource " + computingRes);
+		}
+		LOG.info("Discovery finished...");
+		RemoteEventHandler handler = new RemoteEventHandler();
+		client = new ClientDataServer(handler);
+		clientController = new SPMDClientController(computingResources,null, client,handler);
+		// ////////// Initialise data \\\\\\\\\\\\\
+		WritableGridRaster baseGrid = GeoImportUtil
+				.readGridRasterFromArcInfoASCII(new File(
+						"../Xulu-Data/minigrid2.arc")); // small data
+//		 "../Xulu-Data/large_clue_data/sc1gr0.0")); //large data
+		gridInput = new SplittableLLProxyGrid(new WritableGridArrayFactory(),
+				new RasterMetaData(baseGrid));
+		localOutput = new SplittableLLProxyGrid(new WritableGridArrayFactory(),
+				new RasterMetaData(baseGrid));
+		remoteInput = new SplittableLLProxyGrid(new WritableGridArrayFactory(),
+				new RasterMetaData(baseGrid));
+		remoteOutput = new SplittableLLProxyGrid(
+				new WritableGridArrayFactory(), new RasterMetaData(baseGrid));
+		RasterUtil.copyInto(baseGrid, gridInput);
+		RasterUtil.copyInto(baseGrid, remoteInput);
+		//RasterUtil.copyInto(baseGrid, localOutput);
+		//RasterUtil.copyInto(baseGrid, remoteOutput);
+	}
+
+	/**
+	 * @see junit.framework.TestCase#tearDown()
+	 */
+	protected void tearDown() throws Exception {
+		client.close();
+		clientController.close();
+		// GlobalDiscoveryService.getInstance().stopServices();
+	}
+
+	/**
+	 * TestSPMD
+	 * 
+	 * @throws Exception
+	 */
+	public void testSPMD() throws Exception {
+		int steps = 3;
+		int neighborhoodRange = 6;
+		System.out.println("Starting step 1: ");
+				
+		/***********************************************************************
+		 * START LOCAL ALGORITHM ******************** The simple Algorithm will
+		 * calculate the average of the neighborhood und write the output to the
+		 * coresponing cell in the output cell
+		 **********************************************************************/
+
+		Rectangle partition = new Rectangle(0, 0, gridInput.getWidth(),
+				gridInput.getHeight());
+		if (gridInput.getWidth() < 20)
+			RasterUtil.printGrid(gridInput, 5, 1, "Input");
+		
+		for (int step = 0; step < steps; step++) {
+//			 the overallsum is simply the sum over all elements
+			float overallSum = 0f;
+			long localStartTime = System.currentTimeMillis();
+			for (int y = 0; y < gridInput.getHeight(); y++)
+				for (int x = 0; x < gridInput.getWidth(); x++) {
+					float tmp = gridInput.getRasterSampleAsFloat(x, y);
+					if (!Float.isNaN(tmp))
+						overallSum += tmp;
+					// the local sum is simply the sum over all elements in the
+					// neighborhood
+					float localSum = 0;
+					// number of cells over which the sum is calculated
+					int noOfCells = 0;
+					// for each cell: calculate the sum of all neighbors
+					for (int y2 = y - neighborhoodRange; y2 <= y
+							+ neighborhoodRange; y2++)
+						for (int x2 = x - neighborhoodRange; x2 <= x
+								+ neighborhoodRange; x2++)
+							// check if the coordinates are valid (inside the
+							// grid and not NaN)
+							if (partition.contains(x2, y2))
+								if (!Float.isNaN(gridInput
+										.getRasterSampleAsFloat(x2, y2))) {
+									localSum += gridInput
+											.getRasterSampleAsFloat(x2, y2);
+									noOfCells++;
+								}
+
+					localOutput.setRasterSample(localSum / (float) (noOfCells),
+							x, y);
+
+				}
+
+			System.out.print("Finished step " + (step+1) + " in "
+					+ ((System.currentTimeMillis() - localStartTime)) + " ms");
+			localStartTime = System.currentTimeMillis();
+			System.out.println(" with sum (local calculated): " + overallSum);
+			//copy values into results from output to input (for next step)
+			RasterUtil.copyInto(localOutput, gridInput);
+		 }
+		 if(gridInput.getWidth()<20)
+		 RasterUtil.printGrid(localOutput, 5, 1, "Local Output");
+
+		/***********************************************************************
+		 * START REMOTE ALGORITHM
+		 *  ******************** All the same..now remotely********************/
+		 //set back the grid to the original input
+		 
+		 System.out
+				.println("******************* starting remote execution *****************");
+		long remoteStartTime = System.currentTimeMillis();
+		clientController.setNeighborhoodRange(neighborhoodRange);
+		clientController.addToSplitControl(remoteInput, "inputGrid");
+		clientController.addToSplitControl(remoteOutput, "outputGrid");
+		System.out.println("After "
+				+ ((System.currentTimeMillis() - remoteStartTime))
+				+ "ms: finished with adding to splitcontroll");
+		
+		//********************** START STEP CONTROL *********************
+		for (int step = 0; step < steps; step++) {
+			if(step > 0){
+				long updateStartTime = System.currentTimeMillis();
+				clientController.updateNeighborhood(remoteInput);
+				System.out.println("Update took:" + (System.currentTimeMillis()-updateStartTime));
+			}
+			try {
+				Object[] sum =clientController.runSPMDModelTask(
+						new AverageNeighborhoodTestTask(), neighborhoodRange);
+//				add results
+				float overallSum = 0;
+				for (int i = 0; i < sum.length; i++)
+					overallSum += (Float) sum[i];
+				System.out.println("finished step "
+						+ (step+1) + " in "
+						+ ((System.currentTimeMillis() - remoteStartTime))
+						+ "ms " + " with sum "+
+						+ overallSum);
+				remoteStartTime = System.currentTimeMillis();
+			} catch (Throwable e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		//***************** END STEP CONTROL *****************************
+		
+		//After execution:
+		// merge partitions and check if the local and remotely calculated
+		// versions are equal
+		remoteStartTime = System.currentTimeMillis();
+		clientController.mergePartition(remoteOutput);
+		System.out.println("Merging took another "
+				+ ((System.currentTimeMillis() - remoteStartTime))
+				+ "ms");
+		// Thread.currentThread().sleep(10000);
+		 if(remoteInput.getWidth()<20)
+			 RasterUtil.printGrid(remoteOutput, 5, 1, "Remote Output");
+		assertTrue(RasterUtil.checkEqual(remoteOutput, localOutput, true));
+	}
+}

Added: trunk/src/appl/parallel/test/SPMDTest.testsuite
===================================================================
(Binary files differ)


Property changes on: trunk/src/appl/parallel/test/SPMDTest.testsuite
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/src/appl/parallel/test/SPMDTest_MultiGrid.java
===================================================================
--- trunk/src/appl/parallel/test/SPMDTest_MultiGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/SPMDTest_MultiGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,259 @@
+package appl.parallel.test;
+
+import java.awt.Rectangle;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.Serializable;
+import java.util.Random;
+import java.util.Vector;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.ConsoleAppender;
+import org.apache.log4j.Layout;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+
+import edu.bonn.xulu.io.ImportFactory;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+import schmitzm.data.WritableGridRaster;
+import schmitzm.geotools.io.GeoImportUtil;
+
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.client.RemoteEventHandler;
+import appl.parallel.client.ClientDataServer;
+import appl.parallel.data.splittable.SplittableLLProxyGrid;
+import appl.parallel.services.GlobalDiscoveryService;
+import appl.parallel.spmd.AbstractSPMDTask;
+import appl.parallel.spmd.SPMDClientController;
+import appl.parallel.spmd.SPMDTask;
+import appl.parallel.spmd.SPMDServerController;
+import appl.parallel.spmd.split.SplittableGrid;
+import appl.util.RasterMetaData;
+import appl.util.RasterUtil;
+
+/**
+ * This is a minor modification of {@link SPMDTest}. It is only used to test the
+ * Multi-Splittable functionality of the parallelization. For the test of all
+ * other features and more detailed information see {@link SPMDTest}.
+ * 
+ * @author Dominik Appl
+ */
+public class SPMDTest_MultiGrid extends TestCase implements Serializable {
+
+	transient private final Logger LOG = LogManager.getLogger(this.getClass()
+			.getName());
+
+	transient private ClientDataServer client;
+	transient private Vector<ComputingResourceContainer> computingResources;
+	transient private SPMDClientController clientController;
+
+	transient SplittableGrid gridInput;
+	transient SplittableGrid remoteInput;
+	transient SplittableGrid localOutput;
+	transient SplittableGrid remoteOutput;
+
+	/**
+	 * Constructor for SPMDTest.
+	 * 
+	 * @param name
+	 */
+	public SPMDTest_MultiGrid(String name) {
+		super(name);
+	}
+
+	/**
+	 * Returns the JUnit test suite that implements the <b>SPMDTest</b>
+	 * definition.
+	 */
+	public static Test suite() {
+		TestSuite sPMDTest = new TestSuite("SPMDTest");
+//		sPMDTest.setArbiter(DefaultTestArbiter.INSTANCE).setId(
+//				"E873D66A70977ED2A98AAC10B54511DB");
+//
+//		sPMDTest.addTest(new SPMDTest("testSPMD").setId(
+//				"E873D66A70977ED2E5E8ED20B54511DB").setTestInvocationId(
+//				"E873D66A70977ED2EF7E3C00B54511DB"));
+		return sPMDTest;
+	}
+
+	/**
+	 * @see junit.framework.TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		PropertyConfigurator.configure("xululog4j.cfg");
+		computingResources = new GlobalDiscoveryService()
+				.getRemoteResources();
+
+		for (ComputingResourceContainer computingRes : computingResources) {
+			System.out.println("DiscoveredRessource " + computingRes);
+		}
+		LOG.info("Discovery finished...");
+		RemoteEventHandler handler = new RemoteEventHandler();
+		client = new ClientDataServer(handler);
+		clientController = new SPMDClientController(computingResources,null, client,handler);
+		// ////////// Initialise data \\\\\\\\\\\\\
+		WritableGridRaster baseGrid = GeoImportUtil
+				.readGridRasterFromArcInfoASCII(new File(
+						"../Xulu-Data/minigrid2.arc")); // small data
+//		 "../Xulu-Data/large_clue_data/sc1gr0.0")); //large data
+		gridInput = new SplittableLLProxyGrid(new WritableGridArrayFactory(),
+				new RasterMetaData(baseGrid));
+		localOutput = new SplittableLLProxyGrid(new WritableGridArrayFactory(),
+				new RasterMetaData(baseGrid));
+		remoteInput = new SplittableLLProxyGrid(new WritableGridArrayFactory(),
+				new RasterMetaData(baseGrid));
+		remoteOutput = new SplittableLLProxyGrid(
+				new WritableGridArrayFactory(), new RasterMetaData(baseGrid));
+		RasterUtil.copyInto(baseGrid, gridInput);
+		RasterUtil.copyInto(baseGrid, remoteInput);
+		//RasterUtil.copyInto(baseGrid, localOutput);
+		//RasterUtil.copyInto(baseGrid, remoteOutput);
+	}
+
+	/**
+	 * @see junit.framework.TestCase#tearDown()
+	 */
+	protected void tearDown() throws Exception {
+		client.close();
+		clientController.close();
+		// GlobalDiscoveryService.getInstance().stopServices();
+	}
+
+	/**
+	 * TestSPMD
+	 * 
+	 * @throws Exception
+	 */
+	public void testSPMD() throws Exception {
+		int steps = 4;
+		int neighborhoodRange = 3;
+		System.out.println("Starting step 1: ");
+				
+		/***********************************************************************
+		 * START LOCAL ALGORITHM ******************** The simple Algorithm will
+		 * calculate the average of the neighborhood und write the output to the
+		 * coresponing cell in the output cell
+		 **********************************************************************/
+
+		Rectangle partition = new Rectangle(0, 0, gridInput.getWidth(),
+				gridInput.getHeight());
+		if (gridInput.getWidth() < 20)
+			RasterUtil.printGrid(gridInput, 5, 1, "Input");
+		
+		for (int step = 0; step < steps; step++) {
+//			 the overallsum is simply the sum over all elements
+			float overallSum = 0f;
+			long localStartTime = System.currentTimeMillis();
+			for (int y = 0; y < gridInput.getHeight(); y++)
+				for (int x = 0; x < gridInput.getWidth(); x++) {
+					float tmp = gridInput.getRasterSampleAsFloat(x, y);
+					if (!Float.isNaN(tmp))
+						overallSum += tmp;
+					// the local sum is simply the sum over all elements in the
+					// neighborhood
+					float localSum = 0;
+					// number of cells over which the sum is calculated
+					int noOfCells = 0;
+					// for each cell: calculate the sum of all neighbors
+					for (int y2 = y - neighborhoodRange; y2 <= y
+							+ neighborhoodRange; y2++)
+						for (int x2 = x - neighborhoodRange; x2 <= x
+								+ neighborhoodRange; x2++)
+							// check if the coordinates are valid (inside the
+							// grid and not NaN)
+							if (partition.contains(x2, y2))
+								if (!Float.isNaN(gridInput
+										.getRasterSampleAsFloat(x2, y2))) {
+									localSum += gridInput
+											.getRasterSampleAsFloat(x2, y2);
+									noOfCells++;
+								}
+
+					localOutput.setRasterSample(localSum / (float) (noOfCells),
+							x, y);
+
+				}
+
+			System.out.print("Finished step " + (step+1) + " in "
+					+ ((System.currentTimeMillis() - localStartTime)) + " ms");
+			localStartTime = System.currentTimeMillis();
+			System.out.println(" with sum (local calculated): " + overallSum);
+			//copy values into results from output to input (for next step)
+			RasterUtil.copyInto(localOutput, gridInput);
+		 }
+		 if(gridInput.getWidth()<20)
+		 RasterUtil.printGrid(localOutput, 5, 1, "Local Output");
+
+		
+		 
+		 
+		 /***********************************************************************
+		 * 							START REMOTE ALGORITHM
+		 *  ******************** All the same..now remotely********************/
+		 
+		 System.out
+				.println("******************* starting remote execution *****************");
+		long remoteStartTime = System.currentTimeMillis();
+		clientController.setNeighborhoodRange(neighborhoodRange);
+//		initialize as MulitSplittable
+		WritableGrid[] testSplittable = {remoteInput,remoteOutput};
+		clientController.addToMultiDataSplitControl(testSplittable, "gridData");
+		
+//		clientController.addToSplitControl(remoteInput, "inputGrid");
+//		clientController.addToSplitControl(remoteOutput, "outputGrid");
+		System.out.println("After "
+				+ ((System.currentTimeMillis() - remoteStartTime))
+				+ "ms: finished with adding to splitcontroll");
+		
+		//********************** START STEP CONTROL *********************
+		for (int step = 0; step < steps; step++) {
+			if(step > 0){
+				long updateStartTime = System.currentTimeMillis();
+				clientController.updateNeighborhood(remoteInput);
+				System.out.println("Update took:" + (System.currentTimeMillis()-updateStartTime));
+			}
+			Object[] sum;
+			try {
+				sum = clientController.runSPMDModelTask(
+						new AverageNeighborhoodTestTask_MultiGrid(), neighborhoodRange);
+				//add results
+				float overallSum = 0;
+				for (int i = 0; i < sum.length; i++)
+					overallSum += (Float) sum[i];
+				System.out.println("finished step "
+						+ (step+1) + " in "
+						+ ((System.currentTimeMillis() - remoteStartTime))
+						+ "ms " + " with sum "+
+						+ overallSum);
+				remoteStartTime = System.currentTimeMillis();
+				
+			} catch (Throwable e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		//***************** END STEP CONTROL *****************************
+		
+		//After execution:
+		// merge partitions and check if the local and remotely calculated
+		// versions are equal
+		remoteStartTime = System.currentTimeMillis();
+		clientController.mergePartition(remoteOutput);
+		System.out.println("Merging took another "
+				+ ((System.currentTimeMillis() - remoteStartTime))
+				+ "ms");
+		// Thread.currentThread().sleep(10000);
+		 if(remoteInput.getWidth()<20)
+			 RasterUtil.printGrid(remoteOutput, 5, 1, "Remote Output");
+		assertTrue(RasterUtil.checkEqual(remoteOutput, localOutput, true));
+	}
+}

Added: trunk/src/appl/parallel/test/SplitMapTest.java
===================================================================
--- trunk/src/appl/parallel/test/SplitMapTest.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/SplitMapTest.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,184 @@
+package appl.parallel.test;
+
+import java.awt.Rectangle;
+import java.io.File;
+import java.io.FileInputStream;
+
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import appl.parallel.data.splittable.SplittableGridLLFactory;
+import appl.parallel.data.splittable.SplittableLLProxyGrid;
+import appl.parallel.spmd.split.AbstractSplitMap;
+import appl.parallel.spmd.split.SplitMap;
+import appl.parallel.spmd.split.SplitMap1DHorizontal;
+import appl.parallel.spmd.split.SplitMap1DVertical;
+import appl.parallel.spmd.split.SplitMap2D;
+import appl.parallel.util.Helper;
+import appl.util.GeneralUtil;
+import appl.util.RasterMetaData;
+import appl.util.RasterUtil;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridRaster;
+import schmitzm.geotools.io.GeoImportUtil;
+
+/**
+ * Generated code for the test suite <b>SplitMapTest</b> located at
+ * <i>/XuluSVN/javasrc/appl/parallel/test/SplitMapTest.testsuite</i>.
+ *
+ * Tests different splitmaps
+ */
+public class SplitMapTest extends TestCase {
+
+	Rectangle globalCalcBounds;
+
+	Rectangle partitionCalcBounds;
+
+	Rectangle partitionNeighborhoodBounds;
+
+	Rectangle globalNeighborhoodBounds;
+
+	Rectangle localCalcBounds;
+
+	Rectangle localNeighborhoodBounds;
+
+	private SplittableLLProxyGrid baseGrid;
+
+	private SplitMap map;
+
+	/**
+	 * Constructor for SplitMapTest.
+	 * @param name
+	 */
+	public SplitMapTest(String name) {
+		super(name);
+	}
+
+	/**
+	 * Returns the JUnit test suite that implements the <b>SplitMapTest</b>
+	 * definition.
+	 */
+	public static Test suite() {
+		TestSuite splitMapTest = new TestSuite("SplitMapTest");
+		//		splitMapTest.setArbiter(DefaultTestArbiter.INSTANCE).setId(
+		//				"D35DB07792EF13413F23D9D0B19111DB");
+		//	
+		//		splitMapTest.addTest(new SplitMapTest("test1DSplitMap").setId(
+		//				"D35DB07792EF134149AEAC40B19111DB").setTestInvocationId(
+		//				"D35DB07792EF134168064FE0B19111DB"));
+		return splitMapTest;
+	}
+
+	/**
+	 * @see junit.framework.TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		//		load a very simple 10x10 Grid 
+		WritableGrid loadGrid = GeoImportUtil
+				.readGridRasterFromArcInfoASCII(new File(
+						"../Xulu-Data/regularGrid.arc"));
+		baseGrid = new SplittableLLProxyGrid(new RasterMetaData(loadGrid),2);
+		RasterUtil.copyInto(loadGrid, baseGrid);
+		//RasterUtil.printGrid(baseGrid, "Base grid");
+	}
+
+	/**
+	 * @see junit.framework.TestCase#tearDown()
+	 */
+	protected void tearDown() throws Exception {
+	}
+
+	public void basicTest() {
+		//make simply 2 Partitions without neighborhood
+		map.makeMap();
+		//check first partition
+		initVariables(map, 0);
+		assertEquals(new Rectangle(0, 0, 10, 10), globalCalcBounds);
+		assertEquals(new Rectangle(0, 0, 10, 10), globalNeighborhoodBounds);
+		assertEquals(new Rectangle(0, 0, 5, 10), partitionCalcBounds);
+		assertEquals(new Rectangle(0, 0, 5, 10), partitionNeighborhoodBounds);
+		assertEquals(new Rectangle(0, 0, 5, 10), localCalcBounds);
+		assertEquals(new Rectangle(0, 0, 5, 10), localNeighborhoodBounds);
+		//check second partition
+		initVariables(map, 1);
+		assertEquals(globalCalcBounds, new Rectangle(0, 0, 10, 10));
+		assertEquals(globalNeighborhoodBounds, new Rectangle(0, 0, 10, 10));
+		assertEquals(partitionCalcBounds, new Rectangle(5, 0, 5, 10));
+		assertEquals(partitionNeighborhoodBounds, new Rectangle(5, 0, 5, 10));
+		assertEquals(localCalcBounds, new Rectangle(0, 0, 5, 10));
+		assertEquals(localNeighborhoodBounds, new Rectangle(0, 0, 5, 10));
+	}
+
+	public void test1DHorizontal() {
+        //2 Partitions
+		map = new SplitMap1DHorizontal(baseGrid.getWidth(), baseGrid.getHeight(),
+				1, 2, AbstractSplitMap.NeighborhoodBoxingMode.inBoxing);
+		
+		
+	    
+	    map = new SplitMap1DHorizontal(baseGrid.getWidth(), baseGrid.getHeight(),
+				1, 3, AbstractSplitMap.NeighborhoodBoxingMode.inBoxing);
+	   
+	    
+	}
+	
+	public void print(){
+		for(int i=0; i < map.getCount(); i++){
+			RasterUtil.printGrid(baseGrid.getPartition(map.getPartitionCalculationBounds(i)),3,0,"Calculation Partition " + (i+1) + "/" + map.getCount());
+		}
+		for(int i=0; i < map.getCount(); i++){
+			RasterUtil.printGrid(baseGrid.getPartition(map.getPartitionNeighborhoodBounds(i)),3,0,"Neighborhood Partition " + (i+1) + "/" + map.getCount());
+		}
+	}
+	
+	public void test2DIrregular(){
+//		map = new SplitMap2D(10, 10,
+//				1, 3, AbstractSplitMap.NeighborhoodBoxingMode.inBoxing);
+		
+	    map = new SplitMap2D(baseGrid.getWidth(), baseGrid.getHeight(),
+				1, 9, AbstractSplitMap.NeighborhoodBoxingMode.inBoxing);
+	    print();
+	}
+
+	/**
+	 * 1DSplitMap
+	 * @throws Exception
+	 */
+	public void test1DVertical() throws Exception {
+		//2 Partitions
+		map = new SplitMap1DVertical(baseGrid.getWidth(), baseGrid.getHeight(),
+				0, 2, AbstractSplitMap.NeighborhoodBoxingMode.inBoxing);
+		basicTest();
+		//make 3 Partitions
+		map = new SplitMap1DVertical(baseGrid.getWidth(), baseGrid.getHeight(),
+				0, 3, AbstractSplitMap.NeighborhoodBoxingMode.inBoxing);
+		
+		//make 2 Partitions with neighborhoodrange 2
+		map = new SplitMap1DVertical(baseGrid.getWidth(), baseGrid.getHeight(),
+				2, 2, AbstractSplitMap.NeighborhoodBoxingMode.inBoxing);
+		//intersect the partitions and see if you have the right rect
+
+		Rectangle r = map.getPartitionNeighborhoodBounds(0).intersection(
+				map.getPartitionNeighborhoodBounds(1));
+		assertEquals(new Rectangle(3, 0, 4, 10), r);
+
+		initVariables(map, 1);
+	}
+
+	/**
+	 * @param map
+	 */
+	private void initVariables(SplitMap map, int pos) {
+		globalCalcBounds = map.getGlobalCalculationBounds();
+		partitionCalcBounds = map.getPartitionCalculationBounds(pos);
+		partitionNeighborhoodBounds = map.getPartitionNeighborhoodBounds(pos);
+		globalNeighborhoodBounds = map.getGlobalBounds();
+		localCalcBounds = map.getLocalCalculationBounds(pos);
+		localNeighborhoodBounds = map.getLocalNeighborhoodBounds(pos);
+
+	}
+
+}

Added: trunk/src/appl/parallel/test/SplitMaps.testsuite
===================================================================
(Binary files differ)


Property changes on: trunk/src/appl/parallel/test/SplitMaps.testsuite
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/src/appl/parallel/test/XuluGridTestCase.java
===================================================================
--- trunk/src/appl/parallel/test/XuluGridTestCase.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/XuluGridTestCase.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,159 @@
+package appl.parallel.test;
+
+import java.awt.Rectangle;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory_ArcInfoAsciiGrid;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+import schmitzm.data.WritableGridRaster;
+import schmitzm.geotools.io.GeoExportUtil;
+import schmitzm.geotools.io.GeoImportUtil;
+import appl.parallel.data.xulugridfile.XuluGridFile;
+import appl.parallel.spmd.split.WritableGridPartition;
+import appl.util.RasterMetaData;
+import appl.util.RasterUtil;
+
+/**
+ * Generated code for the test suite <b>XuluGridTestCase</b> located at
+ * <i>/Xulu-latest/javasrc/appl/test/XuluGridTestCase.testsuite</i>.
+ *
+ * Extensivly tests the XuluGridFile for errors
+ */
+public class XuluGridTestCase extends TestCase {
+	 XuluGridFile gridFile;
+	
+	/**
+	 * Constructor for XuluGridTestCase.
+	 * @param name
+	 */
+	public XuluGridTestCase(String name) {
+		super(name);
+	}
+
+	/**
+	 * Returns the JUnit test suite that implements the <b>XuluGridTestCase</b>
+	 * definition.
+	 */
+	public static Test suite() {
+		TestSuite xuluGridTestCase = new TestSuite("XuluGridTestCase");
+//		xuluGridTestCase.setArbiter(DefaultTestArbiter.INSTANCE).setId(
+//				"D14CC6AE1994BD92F864B0C0A54011DB");
+//	
+//		xuluGridTestCase.addTest(new XuluGridTestCase("testReadingPartitialGrid")
+//				.setId("D14CC6AE1994BD92132B3E60A54111DB").setTestInvocationId(
+//						"D14CC6AE1994BD9269E4C820A54111DB"));
+//	
+//		xuluGridTestCase.addTest(new XuluGridTestCase("testMartin").setId(
+//				"D14CC6AE1994BD92FC1EA54AA62111DB").setTestInvocationId(
+//				"D14CC6AE1994BD9262B92000A62211DB"));
+		return xuluGridTestCase;
+	}
+
+	/**
+	 * @see junit.framework.TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+	}
+
+	/**
+	 * @see junit.framework.TestCase#tearDown()
+	 */
+	protected void tearDown() throws Exception {
+		if (gridFile!=null) 
+			gridFile.close();	
+	}
+
+    /**
+	* testReadingPartitial Grid
+	* @throws Exception
+	*/
+	public void testReadingPartitialGrid()
+	throws Exception
+	{
+		
+		//base file: all assertions are checked against this grid
+		WritableGridRaster baseGrid = GeoImportUtil.readGridRasterFromArcInfoASCII(new File("../Xulu-Data/minigrid.arc"));
+		printSmall(baseGrid);
+		GeoExportUtil.writeGridRasterToArcInfoASCII(baseGrid, new File("BaseGridExport_miniGrid_export1"));
+        
+		// write a XuluGridFile / check it against baseGrid 
+        File file = new File("XuluGridFile_miniGrid.xgrid");
+        XuluGridFile.writeToXuluGridFile(baseGrid,file);
+        // fill the grid2 with any Data
+        WritableGrid grid2 = GeoImportUtil.readGridRasterFromArcInfoASCII(new File("../Xulu-Data/SimpleGrid.arc"));
+        assertFalse(RasterUtil.checkEqual(baseGrid,grid2,true));
+        XuluGridFile.readIntoGridFromXuluGridFile(grid2, file);
+        assertTrue(RasterUtil.checkEqual(baseGrid,grid2,true));
+        
+        //export und reimport an check it again (this caused some hard to trace errors in the past, even if it should not.)
+        GeoExportUtil.writeGridRasterToArcInfoASCII((WritableGridRaster)grid2, new File("BaseGridExport_miniGrid_export2"));
+        grid2 = GeoImportUtil.readGridRasterFromArcInfoASCII(new File("BaseGridExport_miniGrid_export2"));
+        assertTrue(RasterUtil.checkEqual(baseGrid,grid2,true));
+        
+        //initialize a new XuluGrid 
+        gridFile = new XuluGridFile(new File("XuluGridFile_miniGrid.xgrid"),"r");
+        RasterMetaData meta = gridFile.getMetaData();
+        //get the whole gridFile using the partition method and check it
+        WritableGrid wholeGrid = gridFile.getPartitialGrid2D(new Rectangle(0, 0, meta.getWidth(), meta.getHeight()));
+        assertTrue(RasterUtil.checkEqual(baseGrid,wholeGrid,true));
+        assertTrue(RasterUtil.checkEqual(grid2,wholeGrid,true));
+        //write all data from wholeGrid into grid2, then export grid2
+        for (int y = meta.getMinY(); y < meta.getHeight()- meta.getMinY(); y++)
+        		for (int x = meta.getMinX(); x < meta.getWidth() - meta.getMinY(); x++)
+        			grid2.setRasterSample(wholeGrid.getRasterSample(x,y),x,y);
+        GeoExportUtil.writeGridRasterToArcInfoASCII(baseGrid, new File("XuluGrid2FromWholeGrid_test"));
+        	        
+        
+        //new WritableGridArrayFactory_ArcInfoAsciiGrid().exportObject(wholeGrid, new BufferedOutputStream(new FileOutputStream("XuluGridTest_ARCINFO2")));
+        
+//        for (y = 1; y < metadata.getheight(); y++)
+//            for (x = 1; x < metadata.getwidth(); x++) {
+        //get left half of the gridFile
+        WritableGrid leftHalf = gridFile.getPartitialGrid2D(new Rectangle(0, 0, (meta.getWidth()/2), meta.getHeight()));
+        new WritableGridArrayFactory_ArcInfoAsciiGrid().exportObject(leftHalf, new BufferedOutputStream(new FileOutputStream("LeftHalf_XULUGRID")));
+        
+        //########################### no gridfile test ###############################
+        XuluGridFile gridfile = new XuluGridFile(new File("XuluGridFile_miniGrid.xgrid"),"rw");
+        WritableGridPartition partition = gridfile.getPartitialGrid2D(new Rectangle(0,0,5,5));
+        printSmall(partition);
+         partition = gridfile.getPartitialGrid2D(new Rectangle(0,0,4,4));
+        printSmall(partition);
+         partition = gridfile.getPartitialGrid2D(new Rectangle(1,1,8,8));
+        printSmall(partition);
+         partition = gridfile.getPartitialGrid2D(new Rectangle(5,5,5,5));
+        printSmall(partition);
+         partition = gridfile.getPartitialGrid2D(new Rectangle(1,1,2,2));
+        printSmall(partition);
+        
+}
+	/**
+	 * prints only small grids
+	 * 
+	 * @param grid
+	 */
+	public void printSmall(WritableGrid grid){
+		if(grid.getWidth()<20 && grid.getHeight()<20)
+			RasterUtil.printGrid(grid,5,1,"output");
+	}
+
+public void testMartin()
+	throws Exception
+	{
+		WritableGridRaster baseGrid = GeoImportUtil.readGridRasterFromArcInfoASCII(new File("../Xulu-Data/standard_clue_data/CLUE-Datensatz1/sc1gr0.23"));
+		WritableGridArray testGrid = new WritableGridArray.Float(baseGrid.getMinX(),baseGrid.getMinY(),baseGrid.getWidth(),baseGrid.getHeight(),baseGrid.getX(),baseGrid.getY(),baseGrid.getRealWidth(),baseGrid.getRealHeight(),null,null);
+		for (int y = baseGrid.getMinY(); y < baseGrid.getHeight()- baseGrid.getMinY(); y++)
+    		for (int x = baseGrid.getMinX(); x < baseGrid.getWidth() - baseGrid.getMinY(); x++)
+    			testGrid.setRasterSample(baseGrid.getRasterSample(x,y),x,y);
+       GeoExportUtil.writeGridRasterToArcInfoASCII(baseGrid, new File("Test_baseGrid"));
+       new WritableGridArrayFactory_ArcInfoAsciiGrid().exportObject(testGrid,new FileOutputStream("Test_testGrid2"));
+	}
+}

Added: trunk/src/appl/parallel/test/XuluGridTestCase.testsuite
===================================================================
(Binary files differ)


Property changes on: trunk/src/appl/parallel/test/XuluGridTestCase.testsuite
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/src/appl/parallel/test/XuluServerTest.java
===================================================================
--- trunk/src/appl/parallel/test/XuluServerTest.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/XuluServerTest.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,113 @@
+package appl.parallel.test;
+
+import java.io.Serializable;
+import java.net.MalformedURLException;
+import java.rmi.Naming;
+import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
+
+import appl.parallel.server.XuluServer;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Generated code for the test suite <b>XuluServerTest</b> located at
+ * <i>/XuluSVN/javasrc/appl/parallel/test/XuluServerTest.testsuite</i>.
+ *
+ * Tests the Server functionality
+ */
+public class XuluServerTest extends TestCase {
+	public final String IP = "192.168.18.238";
+	XuluServer server;
+
+	/**
+	 * @see junit.framework.TestCase#setUp()
+	 */
+	protected void setUp() throws Exception {
+		String name = "rmi://" + IP + "/XuluServer";
+
+		server = (XuluServer) Naming.lookup(name);
+
+
+	}
+
+	/**
+	 * Constructor for XuluServerTest.
+	 * @param whatsthis
+	 */
+	public XuluServerTest(String whatsthis) {
+		super(whatsthis);
+	}
+
+	/**
+	 * Returns the JUnit test suite that implements the <b>XuluServerTest</b>
+	 * definition.
+	 */
+	public static Test suite() {
+		TestSuite xuluServerTest = new TestSuite("XuluServerTest");
+//		xuluServerTest.setArbiter(DefaultTestArbiter.INSTANCE).setId(
+//				"F534D0796F99AD6BA80D9B00A9AA11DB");
+
+		return xuluServerTest;
+	}
+
+
+	/**
+	 * @see junit.framework.TestCase#tearDown()
+	 */
+	protected void tearDown() throws Exception {
+	}
+
+    /**
+		* testServer
+		* @throws Exception
+		*/
+		public void testPingServer()
+		throws Exception
+		{
+			  try{
+			    	Object data;
+			    	PingTestObject pingObj = new PingTestObject(32);
+	    			// do 10 pings
+					long sum1 = 0;
+					for (int i = 0; i < 10; i++) {
+						long mstime = System.currentTimeMillis();
+			            data = server.ping(pingObj);
+				        long mstimediff = System.currentTimeMillis() - mstime;
+				        sum1 += mstimediff;
+				       // Thread.sleep(100);
+					}
+					long sum2 = 0;
+					for (int i = 0; i < 10; i++) {
+						long nanotime = System.nanoTime();
+			            data = server.ping(pingObj);
+				        long nanolatency = System.nanoTime() - nanotime;
+				        double timediff = (double)nanolatency / 1000000.0;
+				        sum2+= nanolatency;
+				        //Thread.sleep(100);
+					}
+					System.out.println("Average MS: " + sum1/10 + " Average nano: " + (double)sum2 / 10000000.0  );
+
+
+				} catch (RemoteException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+
+
+		}
+
+    /**
+	* sendModel
+	* @throws Exception
+	*/
+	public void testSendModel()
+	throws Exception
+	{
+		System.out.println("fu");
+	// Enter your code here
+	}
+
+}

Added: trunk/src/appl/parallel/test/XuluServerTest.testsuite
===================================================================
(Binary files differ)


Property changes on: trunk/src/appl/parallel/test/XuluServerTest.testsuite
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/src/appl/parallel/test/generalTestClass.java
===================================================================
--- trunk/src/appl/parallel/test/generalTestClass.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/generalTestClass.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,20 @@
+package appl.parallel.test;
+
+
+import java.awt.Rectangle;
+
+
+import schmitzm.data.WritableGrid;
+
+/**
+ * @author Dominik Appl
+ */
+public class generalTestClass {
+
+	public static void main(String[] args) {
+		String testString = "Blueberry";
+		System.out.println(testString.getClass().getCanonicalName());
+	}
+
+
+}

Added: trunk/src/appl/parallel/test/package.html
===================================================================
--- trunk/src/appl/parallel/test/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/test/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains some thread related classes.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/thread/ComputingResourceThread.java
===================================================================
--- trunk/src/appl/parallel/thread/ComputingResourceThread.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/thread/ComputingResourceThread.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,25 @@
+package appl.parallel.thread;
+
+import appl.parallel.ComputingResource;
+import appl.parallel.ComputingResourceProperties;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.event.CommEvent.CommType;
+
+/**
+ * @author Dominik Appl
+ */
+public abstract class ComputingResourceThread extends ExecutionThread{
+
+	
+	 public ComputingResourceThread(ComputingResource resource, ComputingResourceProperties resourceInfos, Object argument,  CommType type, CommEventSink sink){
+			super(resource, resourceInfos, argument,type,sink,false);
+		}
+	 
+	 public ComputingResourceThread(ComputingResource resource, ComputingResourceProperties resourceInfos, Object argument,  CommType type, CommEventSink sink, boolean disableTransferEvents){
+			super(resource, resourceInfos, argument,type,sink,disableTransferEvents);
+		}
+		
+		protected ComputingResource getServer(){
+			return (ComputingResource) server;
+		}
+}

Added: trunk/src/appl/parallel/thread/DataServerThread.java
===================================================================
--- trunk/src/appl/parallel/thread/DataServerThread.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/thread/DataServerThread.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,25 @@
+package appl.parallel.thread;
+
+import appl.parallel.ComputingResourceProperties;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.event.CommEvent.CommType;
+import appl.parallel.server.PartitionDataServer;
+
+/**
+ * @author Dominik Appl
+ */
+public abstract class DataServerThread extends ExecutionThread {
+	
+	public DataServerThread(PartitionDataServer dataServer,ComputingResourceProperties resourceInfos, Object argument,CommType type, CommEventSink sink){
+		super(dataServer,resourceInfos,argument,type,sink,false);
+	}
+	
+	public DataServerThread(PartitionDataServer dataServer,ComputingResourceProperties resourceInfos, Object argument,CommType type, CommEventSink sink, boolean disableTransferEvents){
+		super(dataServer,resourceInfos,argument,type,sink,disableTransferEvents);
+	}
+	
+	protected PartitionDataServer getServer(){
+		return (PartitionDataServer) server;
+	}
+	
+}
\ No newline at end of file

Added: trunk/src/appl/parallel/thread/ExecutionThread.java
===================================================================
--- trunk/src/appl/parallel/thread/ExecutionThread.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/thread/ExecutionThread.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,158 @@
+package appl.parallel.thread;
+
+import java.nio.channels.Pipe.SinkChannel;
+import java.rmi.RemoteException;
+import java.util.concurrent.Callable;
+
+import appl.parallel.ComputingResourceProperties;
+import appl.parallel.client.RemoteEventHandler;
+import appl.parallel.event.CommEvent;
+import appl.parallel.event.CommEventSink;
+import appl.parallel.event.TimeEvent;
+import appl.parallel.event.TransferEvent;
+import appl.parallel.event.CommEvent.CommType;
+
+/**
+ * A simple helper class for more easy Thread handling with anonymous classes.
+ *
+ * @see DataServerThread
+ * @see ComputingResourceThread
+ *
+ * @author Dominik Appl
+ */
+public abstract class ExecutionThread implements Callable {
+
+	protected final Object server;
+
+	protected final Object argument;
+
+	protected final CommType commType;
+
+	protected final ComputingResourceProperties serverInfos;
+
+	protected final CommEventSink eventSink;
+
+	protected boolean disableTransferEvents=false;
+
+	/**
+	 * creates a new thread
+	 *
+	 * @param server
+	 *            the server which is accessed with this thread
+	 * @param serverInfos the serverinfos (used for event info)
+	 * @param argument
+	 *            an argument which can be used inside the anonymous class
+	 * @param type the type of the communication
+	 * @param sink events are submitted to this sink
+	 * @param disableTransferEvents says whether to ignore transfer events (if the transfer volume is to low to be counted))
+	 */
+	public ExecutionThread(Object server,
+			ComputingResourceProperties serverInfos, Object argument,
+			CommType type, CommEventSink sink, boolean disableTransferEvents) {
+		this.server = server;
+		this.serverInfos = serverInfos;
+		this.argument = argument;
+		this.commType = type;
+		this.eventSink = sink;
+		this.disableTransferEvents = disableTransferEvents;
+	}
+
+	/**
+	 * @return the server given the constructor (should be overwrited by a
+	 *         subclass)
+	 */
+	protected Object getServer() {
+		return server;
+	}
+
+	/**
+	 * @return the argument given in the constructor as int value
+	 */
+	protected int getIntArgument() {
+		return (Integer) argument;
+	}
+
+	/**
+	 * @return the argument given in the constructor as object value
+	 */
+	protected Object getObjectArgument() {
+		return argument;
+	}
+
+	/**
+	 * @return the argument given in the constructor as array value
+	 */
+	protected Object[] getObjectArrayArgument() {
+		return (Object[]) argument;
+	}
+
+	/**
+	 * Sends standard {@link CommEvent CommEvents} to the {@link CommEventSink} given with the
+	 * constructor. Executes the {@link #run()} method and returns its result.
+	 *
+	 * @return the result of {@link #run()}.
+	 *
+	 * @see java.util.concurrent.Callable#call()
+	 */
+	public Object call() throws Exception {
+		long l = System.nanoTime();
+		Object result = run();
+		if (eventSink.isTimeMonitoringEnabled())
+			fireTimeEvents((System.nanoTime() - l), result);
+		if (eventSink.isTransferMonitoringEnabled())
+			fireTransferEvent(result);
+		return result;
+
+	}
+
+	/**
+	 * Sends the time events for this execution. Method generates only the event of
+	 * this execution. If you want more events (e.g. details from a remote
+	 * execution) you can overwrite this method. This method is only called if time
+	 * monitoring is enabled
+	 *
+	 * @param execTime
+	 *            the time of THIS execution
+	 * @param result the result of the computation (may be of use when overwriting)
+	 */
+	protected void fireTimeEvents(long execTime, Object result) {
+		// localhost as String for performance reasons
+		try {
+			eventSink.fireRemoteEvent(new TimeEvent(execTime, "localhost",
+					serverInfos.getName(), commType));
+		} catch (RemoteException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * The TransferEvents for this execution. Method generates only the event
+	 * out of the size of {@link #getObjectArgument()}.If you want more events
+	 * (e.g. details from a remote execution) you can overwrite this method.
+	 * This method is only called if time monitoring is enabled.
+	 *  Notice that this will be very slow for large Data!!
+	 *
+	 * @param result
+	 *            the result of the execution (per default not needed)
+	 */
+	protected void fireTransferEvent(Object result) {
+		if(!disableTransferEvents)
+		// client as String for performance reasons
+		try {
+			eventSink.fireRemoteEvent(new TransferEvent("Xulu/V-Client",
+					serverInfos.getName(), commType, argument));
+		} catch (RemoteException e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * This method should implement the real running code.
+	 * @return the result you want to retrieve later
+	 * @throws Exception the exceptions thrown by your code
+	 */
+	protected abstract Object run() throws Exception;
+
+}

Added: trunk/src/appl/parallel/thread/OneMethodThread.java
===================================================================
--- trunk/src/appl/parallel/thread/OneMethodThread.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/thread/OneMethodThread.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,74 @@
+package appl.parallel.thread;
+/**
+ * Executes a method call in a single Thread
+ *
+ * @author Dominik Appl
+ */
+public abstract class OneMethodThread implements Runnable {
+	private volatile Thread thisThread;
+
+	private final String threadName;
+
+	private final int priority;
+
+	private final Object[] parameters;
+
+	protected Object executionResult;
+
+	/**
+	 * Creates a new Thread. Do not forget to {@link #start()} it.
+	 * @param threadName a name for the thread (usefull while debugging)
+	 * @param priority a priority for the Thread
+	 * @param parameters the parameters may be used later in the run method by calling the {@link #getParameter(int)} method
+	 *
+	 */
+	public OneMethodThread(String threadName, int priority, Object... parameters) {
+		this.threadName = threadName;
+		this.priority = priority;
+		// TODO Auto-generated constructor stub
+		this.parameters = parameters;
+	}
+
+	public abstract void run();
+
+	/**
+	 * Starts the thread
+	 */
+	public void start() {
+		thisThread = new Thread(this);
+		thisThread.setName(threadName);
+		thisThread.setPriority(priority);
+		thisThread.start();
+	}
+
+	/**
+	 * @param paraNo the position in the given parameter array
+	 * @return the parameter given in the constructor
+	 */
+	public Object getParameter(int paraNo) {
+		return parameters[paraNo];
+	}
+
+	/**
+	 * waits until the encapulated Thread has finished
+	 *
+	 */
+	public void join(){
+		try {
+			thisThread.join();
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+	}
+
+
+	/**
+	 * the execution result must be explicitly set in the {@link #run()} method.
+	 *
+	 * @return the result
+	 */
+	public Object getExecutionResult(){
+		return executionResult;
+	}
+
+}

Added: trunk/src/appl/parallel/thread/package.html
===================================================================
--- trunk/src/appl/parallel/thread/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/thread/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,6 @@
+<html>
+<body>
+	Contains classes related the client side of the starter functionality. If a programm is executed by a Starter, the
+	execution can be controlled remotely (start/stop/restart the process).
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/parallel/util/Helper.java
===================================================================
--- trunk/src/appl/parallel/util/Helper.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/util/Helper.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,233 @@
+package appl.parallel.util;
+
+import java.rmi.AccessException;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.util.Vector;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+
+import appl.parallel.ComputingResource;
+import appl.parallel.ComputingResourceContainer;
+import appl.parallel.ComputingResourceProperties;
+import appl.parallel.test.PingTestObject;
+
+/**
+ * See method description for details.
+ *
+ * @author Dominik Appl
+ */
+public class Helper {
+	private static final Logger LOG = LogManager.getLogger("appl.parallel.util.Helper");
+
+	/**
+	 * 	Bind the remote object's stub in the registry. Creates a registry if no running registry
+	 * is found.
+	 *
+	 * @param bindingName the name to be used for binding (with port specified, if necessary)
+	 * @param bindingInstance an instance of the type to bind to the registry
+	 * @param registryPort the default registry port
+	 * @throws RemoteException if something goes wrong
+	 */
+	public static void bind(String bindingName, Remote bindingInstance, int registryPort) throws RemoteException{
+		boolean failed=true;
+		Registry registry;
+		try {
+			 registry = LocateRegistry.getRegistry(registryPort);
+			 registry.rebind(bindingName, bindingInstance);
+			 failed = false;
+		} catch (AccessException e) {
+			System.err.println("Not enough permissions to bind" + bindingName +
+					"to the registry! Adjust your security permission file!");
+			LOG.error("Not enough permissions to bind" + bindingName +
+					"to the registry! Adjust your security permission file!",e);
+			e.printStackTrace();
+		} catch (RemoteException e) {
+			if(e instanceof java.rmi.ConnectException){
+				System.out.println("Could not connect to registry! Trying to create new one...");
+				try {
+					registry = LocateRegistry.createRegistry(registryPort);
+					registry.rebind(bindingName, bindingInstance);
+					System.out.println("Registry successfully created at port " + registryPort);
+					failed = false;
+				} catch (RemoteException e1) {
+					// TODO Auto-generated catch block
+					e1.printStackTrace();
+				}
+			}
+			else
+			  e.printStackTrace();
+		}
+		if(failed)
+			throw new RemoteException("Could not find or create registry!");
+	}
+
+	/**
+	 * Unbinds a a stub from the registry!
+	 * @param bindingName
+	 */
+	public static void unbind(String bindingName){
+	Registry registry;
+	try {
+		registry = LocateRegistry.getRegistry();
+		registry.unbind(bindingName);
+		LOG.debug("Sucessfully removed " + bindingName + " from reggie");
+	} catch (RemoteException e) {
+		LOG.debug("tried to unbind " + bindingName
+				+ " from reggie, but an exception occured: "
+				+ e.getMessage());
+	} catch (NotBoundException e) {
+		LOG.debug("tried to unbind " + bindingName
+				+ " from reggie, but the name was not bound "
+				+ e.getMessage());
+	}
+	}
+
+	/**
+	 * Gets the remote resources from all given {@link ComputingResource} objects.
+	 * For this all resources are queried. If a ressouce does not respond the
+	 * Resource is removed form the Vector(!!!!!) and a warning is given to the
+	 * logger.
+	 *
+	 * @param res
+	 */
+	public static Vector<ComputingResourceContainer> getResourceContainersForVector(
+			Vector<ComputingResource> res) {
+
+	final Vector<ComputingResourceContainer> containers = new Vector<ComputingResourceContainer>();
+    ExecutorService executor = Executors.newCachedThreadPool();
+
+	//this is not a for each loop to avoid ConcurrentModificationException form threads
+
+	Future[] results = new Future[res.size()];
+	int i = res.size() - 1;
+	while (i >= 0) {
+			results[i] = executor.submit(new Helper().new SimpleConnectionThread(res,i));
+		i--;
+	}
+	//wait for the threads to finish  /
+	//add the responding containers to a new Vector and return it
+	for (int j = 0; j < results.length; j++) {
+		Object result;
+		try {
+			result = results[j].get();
+			if(result!=null)
+				containers.add((ComputingResourceContainer) result);
+		} catch (InterruptedException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (ExecutionException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+	return containers;
+}
+
+	/**
+	 * if a connection to the given resource is possible the ResourceProperties of this object
+	 * are returned. Else NULL is returned.
+	 *
+	 * @author Dominik Appl
+	 */
+	public class SimpleConnectionThread implements Callable {
+
+		private final Vector<ComputingResource> containers;
+
+		private final int position;
+
+		public SimpleConnectionThread(
+				Vector<ComputingResource> containers, int position) {
+			this.containers = containers;
+			this.position = position;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 *
+		 * @see java.util.concurrent.Callable#call()
+		 */
+		public Object call() throws Exception {
+//			will remain true, if there is a connection error
+			boolean error = true;
+			ComputingResource r = (ComputingResource) containers.get(position);
+			try {
+				// throw a exeception in case of a connection error:
+				ComputingResourceProperties rp = r.getResourceInformation();
+				error = false;
+				if (LOG.isDebugEnabled())
+					LOG.debug("Getting of resInfo of <"
+							+ rp.getProperty("Name") + "> was successfull!");
+				return new ComputingResourceContainer(r, rp);
+			} catch (Exception e) {
+				LOG.warn("A server was not responding .. removing ressouce!");
+				if (LOG.isDebugEnabled())
+					LOG.debug("Reason was: " + e.getMessage());
+			}
+			return null;
+		}
+	}
+
+
+	/**
+	 * Calculates weights out of ratings. A rating is a value >=1. If the rating
+	 * is 0 an average rating is assumed. This method weights the ratings
+	 * relative to each other so that a weight is a double value between 0 and
+	 * 1 and the sum of all calculated weights is 1.
+	 *
+	 * @param ratings
+	 */
+	public static double[] calculateWeights(int ratings[]){
+		// values with 0 are weightes average. Add all values and count the
+		// values ==0
+		double sum = 0;
+		double nulls = 0;
+		for (int i : ratings) {
+			sum += i;
+			if (i == 0)
+				nulls++;
+		}
+		// for each null add the average
+		double average = (sum / (ratings.length - nulls));
+		// if there are ONLY nulls define the average seperately
+		if (nulls == ratings.length)
+			average = 1000.0 / ratings.length;
+		sum += average * nulls;
+
+		// calculate weights
+		double[] weights = new double[ratings.length];
+		for (int i = 0; i < weights.length; i++) {
+			if (ratings[i] == 0)
+				ratings[i] = (int) average;
+			weights[i] = ratings[i] / sum;
+		}
+
+		if (true == true) {
+			String weightString = "Calculated weights: ";
+			for (double d : weights) {
+				weightString += (d + " ");
+			}
+			LOG.debug("Calculated weights: + " + weightString);
+			System.out.println(weightString);
+		}
+		return weights;
+
+
+
+	}
+
+}
+
+

Added: trunk/src/appl/parallel/util/PartitionUtil.java
===================================================================
--- trunk/src/appl/parallel/util/PartitionUtil.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/util/PartitionUtil.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,157 @@
+package appl.parallel.util;
+
+import java.awt.Rectangle;
+import java.awt.image.DataBuffer;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.data.WritableGridArray;
+import appl.parallel.data.WritableGridArrayPartition;
+import appl.parallel.data.WritableGridArrayPartition.Double;
+import appl.parallel.data.WritableGridArrayPartition.Float;
+import appl.parallel.data.WritableGridArrayPartition.Integer;
+import appl.parallel.spmd.split.SplittableResource;
+import appl.parallel.spmd.split.WritableGridPartition;
+import appl.util.RasterMetaData;
+
+/**
+ * See method description for details.
+ * 
+ * @author Dominik Appl
+ */
+public class PartitionUtil {
+
+	/**
+		 * Returns partition of a {@link WritableGrid} as a {@link WritableGridArray}.
+		 * Notice, that the minX and minY values are ignored and will be set to 0
+		 * (see {@link WritableGrid} for more information about minX and minY). If
+		 * the given {@link WritableGrid} is not an instance of
+		 * {@link WritableGridPartition} it is assumed that the topLeft corner of
+		 * the source grid is (0,0) (like in standard image processing).<br>
+		 * If the partition is a {@link WritableGridPartition} it is assumed that
+		 * the the bounds of the two Partition refer to the same coordinate system.
+		 * Real coordinates are supposed to reference the South(!)-West Corner.
+		 * 
+		 * @param sourceGrid
+		 *            the grid to be partitioned
+		 * @param partitionBounds
+		 *            the rectangle describing the partition
+		 * @param rootID
+		 *            the id to identify the root partition
+		 * @return the new partition including the given corners
+		 * @see SplittableResource#getRootID()
+		 */
+		public static WritableGridPartition getPartitialGrid2D(WritableGrid sourceGrid,
+				Rectangle partitionBounds, int rootID) {
+			
+	//				(int) partitionBounds.getX(),
+	//				(int) partitionBounds.getY(),
+	//				(int) (partitionBounds.getX() + partitionBounds.getWidth() - 1),
+	//				(int) (partitionBounds.getY() + partitionBounds.getHeight() - 1));
+			
+	//		get Metadata of the big Grid
+			RasterMetaData bigMeta = new RasterMetaData(sourceGrid);
+	
+			//create MetaData for the new partitial Grid
+			//Height an width of the partitial Grid
+			int pHeight = (int) partitionBounds.getHeight();
+			int pWidth = (int)partitionBounds.getWidth();
+	
+			//real coordinates of the partitial Grid (which are referenced by the SW Corner)
+			double pX = partitionBounds.getX() * bigMeta.getCellWidth() + bigMeta.getX();
+			double pY = (partitionBounds.getY() + partitionBounds.getHeight() - 1) * bigMeta.getCellHeight() + bigMeta.getY();
+			double pRealWidth = pWidth * bigMeta.getCellWidth();
+			double pRealHeight = pHeight * bigMeta.getCellHeight();
+	
+			//the MetaData of the new Grid
+			RasterMetaData pMetaData = new RasterMetaData(bigMeta.getDataType(),
+					pWidth, pHeight, 0, 0, pX, pY, pRealWidth, pRealHeight, bigMeta.getCoordinateReferenceSystem());
+	
+			//create empty return Grid
+			WritableGridPartition pGrid;
+			switch(bigMeta.getDataType()){
+			case DataBuffer.TYPE_INT:
+				pGrid = new WritableGridArrayPartition.Integer(pMetaData,rootID,partitionBounds);	
+				break;
+			case DataBuffer.TYPE_DOUBLE:
+				pGrid = new WritableGridArrayPartition.Double(pMetaData,rootID,partitionBounds);
+				break;
+			default:
+				pGrid = new WritableGridArrayPartition.Float(pMetaData,rootID,partitionBounds);	
+			}
+			
+			//if the sourceGrid is a partition itself then we do not want to to start reading from (0,0)
+			//but shifted relative to the global coordinate system. So we calculate now the start values:
+			
+			//for standard WritableGrids these are simply the bounds of the new partition...
+			int startX = (int) partitionBounds.getX();
+			int startY = (int) partitionBounds.getY();
+			
+			// ...but for partitions these values are shifted:
+			if(sourceGrid instanceof WritableGridPartition){
+				Rectangle srcBounds = ((WritableGridPartition) sourceGrid).getPartitionBounds();
+				startX -= srcBounds.getX();
+				startY -= srcBounds.getY();
+			}
+			//read the data into the raster from left to right and downwards
+			int x=0,y=0;
+			try{
+			for (y = 0; y < pHeight; y++)
+				for (x = 0; x < pWidth; x++)
+					pGrid.setRasterSample(
+							sourceGrid.getRasterSample(startX  + x, startY + y),
+							x, 
+							y);
+			}catch (Exception e) {
+				System.out.println("stop");
+			}
+			return pGrid;
+		}
+
+	/**
+	     * Overwrites the data at the location specified by the {@link Rectangle} with
+	     * the given partition-data. If the given baseGrid is NOT an instance
+		 * of {@link WritableGridPartition} it is assumed that its the topLeft corner (0,0). 
+		 * If it IS a {@link WritableGridPartition} it is assumed that the the
+		 * bounds of the two Partition refer to the same coordinate system and the partition
+		 * is inserted at the correct absolut position.
+	     * 
+		 * @param baseGrid the grid in which the data is inserted
+		 * @param gridPartition the grid to be inserted
+		 * @param partitionBounds the excact location in coordinates of the baseGrid
+		 */
+		public static void setPartition(WritableGrid baseGrid, WritableGrid gridPartition, Rectangle partitionBounds) {
+			//Check if partition and the rectangle fit
+			if((gridPartition.getWidth()!=partitionBounds.getWidth()) ||
+					(gridPartition.getHeight()!=partitionBounds.getHeight()))
+			  throw new UnsupportedOperationException("The partition width/height does not match the rectangle width/height");
+			
+			//if the baseeGrid is a partition itself then we do not want to to start writing from (0,0)
+			//but shifted relative to the global coordinate system. So we calculate now the start values:
+			
+			//for standard WritableGrids these are simply the bounds of the new partition...
+			int startX = (int) partitionBounds.getX();
+			int startY = (int) partitionBounds.getY();
+			
+			// ...but for partitions these values are shifted:
+			if(baseGrid instanceof WritableGridPartition){
+				Rectangle targetBounds = ((WritableGridPartition) baseGrid).getPartitionBounds();
+				startX -= targetBounds.getX();
+				startY -= targetBounds.getY();
+			}
+			//check if the partition fits in
+	//		if(((partitionBounds.getX()+partitionBounds.getWidth()-1)>baseGrid.getWidth()  ||
+	//				(partitionBounds.getY()+partitionBounds.getHeight()-1)>baseGrid.getHeight()))
+	//				System.out.println("X");
+				//throw new UnsupportedOperationException("The partition does not fit in the Grid!");
+			//write the partition into the Grid
+			
+			for(int y = 0; y < partitionBounds.getHeight();y++)
+				for(int x = 0; x < partitionBounds.getWidth(); x++)
+					baseGrid.setRasterSample(
+											gridPartition.getRasterSample(x,y),
+											x + startX, 
+											y + startY);
+			
+		}
+
+}

Added: trunk/src/appl/parallel/util/package.html
===================================================================
--- trunk/src/appl/parallel/util/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/parallel/util/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains some helper classes.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/plugin/multimodelcontrol/ModelListObject.java
===================================================================
--- trunk/src/appl/plugin/multimodelcontrol/ModelListObject.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/plugin/multimodelcontrol/ModelListObject.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,58 @@
+package appl.plugin.multimodelcontrol;
+
+import edu.bonn.xulu.gui.ModelControlFrame;
+import edu.bonn.xulu.model.XuluModel;
+
+/**
+ * Simple container class that encapulates the data stored a model list (GUI Component)
+ * 
+ * @author Dominik Appl
+ */
+public class ModelListObject {
+
+	private final ModelControlFrame frame;
+    private final XuluModel model;
+    private final String name;
+
+    /**
+     * 
+	 * @param frame modelcontrolframe responsible for the model
+	 * @param model the model
+	 * @param name name of the model
+	 */
+	public ModelListObject(ModelControlFrame frame, XuluModel model, String name) {
+        this.frame = frame;
+		// TODO Auto-generated constructor stub
+        this.model = model;
+        this.name = name;
+	}
+
+    /**
+	 * @return the frame
+	 */
+	public ModelControlFrame getFrame() {
+		return frame;
+	}
+
+    /**
+	 * @return the model
+	 */
+	public XuluModel getModel() {
+		return model;
+	}
+
+    /**
+	 * @return the name
+	 */
+	public String getName() {
+		return name;
+	}
+	
+	/* (non-Javadoc)
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString(){
+        return name;}
+	
+	
+}

Added: trunk/src/appl/plugin/multimodelcontrol/MultiModelControlFrame.java
===================================================================
--- trunk/src/appl/plugin/multimodelcontrol/MultiModelControlFrame.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/plugin/multimodelcontrol/MultiModelControlFrame.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,489 @@
+package appl.plugin.multimodelcontrol;
+
+import java.awt.BorderLayout;
+import javax.swing.JPanel;
+import javax.swing.JFrame;
+import javax.swing.JSplitPane;
+import java.awt.GridBagLayout;
+import java.awt.Dimension;
+import javax.swing.JList;
+import java.awt.GridBagConstraints;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+import javax.swing.JRadioButton;
+import javax.swing.BoxLayout;
+import java.awt.CardLayout;
+import javax.swing.DefaultListModel;
+import javax.swing.ListSelectionModel;
+import javax.swing.BorderFactory;
+import javax.swing.border.EtchedBorder;
+import java.awt.FlowLayout;
+import java.awt.Insets;
+import java.awt.GridLayout;
+import javax.swing.border.SoftBevelBorder;
+import java.awt.ComponentOrientation;
+import java.awt.Cursor;
+import javax.swing.plaf.multi.MultiPanelUI;
+import javax.swing.plaf.basic.BasicPanelUI;
+import javax.swing.JCheckBox;
+import javax.swing.SwingConstants;
+import javax.swing.JToggleButton;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+
+import javax.swing.JTabbedPane;
+
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.gui.XuluInternalFrame;
+import javax.swing.JScrollPane;
+import appl.parallel.gui.ParallelControlPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JTextPane;
+import javax.swing.JTextArea;
+import javax.swing.border.TitledBorder;
+import java.awt.Color;
+
+// fuer Doku
+import appl.parallel.gui.ParallelControlPanelEngine;
+
+/**
+ * The GUI for the ModelControlCenter (MCC). All the interesting stuff happens in the
+ * {@link ParallelControlPanelEngine}.
+ * This GUI was created with the Visual Editor plugin for eclipse.
+ *
+ * @author Dominik Appl
+ */
+public class MultiModelControlFrame extends XuluInternalFrame {
+
+	 static final long serialVersionUID = 1L;
+	 JPanel jContentPane = null;
+     JPanel modelPanel = null;
+     JPanel synchronisationPanel = null;
+     JList modelList = null;
+     JLabel loadedModels = null;
+     JList syncCommandList = null;
+     JLabel syncPanelName = null;
+     JButton addStepCommand = null;
+     JButton newOverAllStep = null;
+     JButton clearModelSteps = null;
+     JPanel syncButtonsPanel = null;
+     JScrollPane jScrollPane = null;
+	 private JPanel jPanel = null;
+	private JPanel controlPanel = null;
+	 JButton startButton = null;
+	 JButton stepButton = null;
+	 JButton stopButton = null;
+	private JPanel jPanel3 = null;
+	private JScrollPane jScrollPane1 = null;
+	private JPanel jPanel5 = null;
+	private JScrollPane jScrollPane2 = null;
+	private JLabel jLabel3 = null;
+	JTextArea console = null;
+
+
+	public MultiModelControlFrame() {
+		super("Multi Model ControlFrame");
+		initialize();
+	}
+
+	/**
+	 * This method initializes this
+	 *
+	 * @return void
+	 */
+	private void initialize() {
+		this.setSize(486, 395);
+		this.setContentPane(getJContentPane());
+		this.setTitle("Multi Model Control");
+		this.setClosable(true);
+		this.setDefaultCloseOperation(HIDE_ON_CLOSE);
+	}
+	/**
+	 * This method initializes jContentPane
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJContentPane() {
+		if (jContentPane == null) {
+			jContentPane = new JPanel();
+			jContentPane.setLayout(new BoxLayout(getJContentPane(), BoxLayout.Y_AXIS));
+			jContentPane.add(getControlPanel(), null);
+			jContentPane.add(getJPanel(), null);
+			jContentPane.add(getJPanel5(), null);
+		}
+		return jContentPane;
+	}
+    /**
+	 * This method initializes modelPanel
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getModelPanel() {
+		if (modelPanel == null) {
+			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
+			gridBagConstraints3.insets = new Insets(0, 0, 2, 0);
+			gridBagConstraints3.gridy = 2;
+			gridBagConstraints3.ipadx = 0;
+			gridBagConstraints3.ipady = 0;
+			gridBagConstraints3.gridx = 0;
+			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
+			gridBagConstraints2.fill = GridBagConstraints.BOTH;
+			gridBagConstraints2.gridy = 1;
+			gridBagConstraints2.ipadx = 0;
+			gridBagConstraints2.ipady = 0;
+			gridBagConstraints2.weightx = 1.0;
+			gridBagConstraints2.weighty = 1.0;
+			gridBagConstraints2.insets = new Insets(5, 5, 5, 5);
+			gridBagConstraints2.gridx = 0;
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.insets = new Insets(3, 3, 3, 3);
+			gridBagConstraints.gridy = 0;
+			gridBagConstraints.ipadx = 0;
+			gridBagConstraints.gridx = 0;
+			loadedModels = new JLabel();
+			loadedModels.setText("Models");
+			loadedModels.setMinimumSize(new Dimension(86, 10));
+			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
+			gridBagConstraints1.fill = GridBagConstraints.BOTH;
+			gridBagConstraints1.weighty = 1.0;
+			gridBagConstraints1.weightx = 1.0;
+			modelPanel = new JPanel();
+			modelPanel.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+			modelPanel.setName("modelPanel");
+			modelPanel.setLayout(new GridBagLayout());
+			modelPanel.add(loadedModels, gridBagConstraints);
+			modelPanel.add(getJScrollPane(), gridBagConstraints2);
+			modelPanel.add(getAddStepCommand(), gridBagConstraints3);
+		}
+		return modelPanel;
+	}
+
+    /**
+	 * This method initializes synchronisationPanel
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getSynchronisationPanel() {
+		if (synchronisationPanel == null) {
+			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
+			gridBagConstraints11.fill = GridBagConstraints.BOTH;
+			gridBagConstraints11.weighty = 1.0;
+			gridBagConstraints11.gridy = 1;
+			gridBagConstraints11.insets = new Insets(0, 5, 2, 5);
+			gridBagConstraints11.weightx = 1.0;
+			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
+			gridBagConstraints5.gridx = 0;
+			gridBagConstraints5.insets = new Insets(0, 0, 2, 0);
+			gridBagConstraints5.gridy = 11;
+			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
+			gridBagConstraints7.gridx = 0;
+			gridBagConstraints7.ipady = 0;
+			gridBagConstraints7.insets = new Insets(3, 0, 3, 0);
+			gridBagConstraints7.gridy = 0;
+			syncPanelName = new JLabel();
+			syncPanelName.setText("Commands");
+			synchronisationPanel = new JPanel();
+			synchronisationPanel.setToolTipText("Here you can synchronize the steps of multiple models");
+			synchronisationPanel.setLayout(new GridBagLayout());
+			synchronisationPanel.add(syncPanelName, gridBagConstraints7);
+			synchronisationPanel.add(getJScrollPane1(), gridBagConstraints11);
+			synchronisationPanel.add(getSyncButtonsPanel(), gridBagConstraints5);
+		}
+		return synchronisationPanel;
+	}
+    /**
+	 * This method initializes jList
+	 *
+	 * @return javax.swing.JList
+	 */
+	private JList getModelList() {
+		if (modelList == null) {
+			modelList = new JList();
+			modelList.setName("modelList");
+			modelList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+			modelList.setToolTipText("All models, which are currently loaded. Doubleclick on a model to set propertys");
+		}
+		return modelList;
+	}
+    /**
+	 * This method initializes jList
+	 *
+	 * @return javax.swing.JList
+	 */
+	private JList getSyncCommandList() {
+		if (syncCommandList == null) {
+			syncCommandList = new JList();
+			syncCommandList.setToolTipText("The list of commands to be executed");
+
+		}
+		return syncCommandList;
+	}
+
+    /**
+	 * This method initializes addStepCommand
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JButton getAddStepCommand() {
+		if (addStepCommand == null) {
+			addStepCommand = new JButton();
+			addStepCommand.setText("Add ====> ");
+			addStepCommand.setPreferredSize(new Dimension(100, 20));
+		}
+		return addStepCommand;
+	}
+    /**
+	 * This method initializes newOverAllStep
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JButton getNewOverAllStep() {
+		if (newOverAllStep == null) {
+			newOverAllStep = new JButton();
+			newOverAllStep.setText("Add Repeat");
+			newOverAllStep.setPreferredSize(new Dimension(119, 20));
+		}
+		return newOverAllStep;
+	}
+    /**
+	 * This method initializes clearModelSteps
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JButton getClearModelSteps() {
+		if (clearModelSteps == null) {
+			clearModelSteps = new JButton();
+			clearModelSteps.setText("Delete entry");
+			clearModelSteps.setPreferredSize(new Dimension(64, 20));
+		}
+		return clearModelSteps;
+	}
+    /**
+	 * This method initializes syncButtonsPanel
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getSyncButtonsPanel() {
+		if (syncButtonsPanel == null) {
+			GridLayout gridLayout1 = new GridLayout();
+			gridLayout1.setRows(1);
+			gridLayout1.setColumns(2);
+			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
+			gridBagConstraints9.anchor = GridBagConstraints.WEST;
+			gridBagConstraints9.gridx = -1;
+			gridBagConstraints9.gridy = -1;
+			gridBagConstraints9.fill = GridBagConstraints.HORIZONTAL;
+			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
+			gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
+			gridBagConstraints8.gridy = -1;
+			gridBagConstraints8.gridx = -1;
+			syncButtonsPanel = new JPanel();
+			syncButtonsPanel.setLayout(gridLayout1);
+			syncButtonsPanel.add(getNewOverAllStep(), null);
+			syncButtonsPanel.add(getClearModelSteps(), null);
+		}
+		return syncButtonsPanel;
+	}
+    /* (non-Javadoc)
+	 * @see edu.bonn.xulu.gui.XuluInternalFrame#refresh()
+	 */
+	@Override
+	public void refresh() {
+		// TODO Auto-generated method stub
+
+	}
+
+    /**
+	 * This method initializes jScrollPane
+	 *
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getJScrollPane() {
+		if (jScrollPane == null) {
+			jScrollPane = new JScrollPane();
+			jScrollPane.setViewportView(getModelList());
+		}
+		return jScrollPane;
+	}
+
+	/**
+	 * This method initializes jPanel
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJPanel() {
+		if (jPanel == null) {
+			GridLayout gridLayout = new GridLayout();
+			gridLayout.setRows(1);
+			gridLayout.setVgap(0);
+			gridLayout.setColumns(4);
+			gridLayout.setHgap(0);
+			jPanel = new JPanel();
+			jPanel.setLayout(gridLayout);
+			jPanel.add(getModelPanel(), null);
+			jPanel.add(getSynchronisationPanel(), null);
+		}
+		return jPanel;
+	}
+
+	/**
+	 * This method initializes controlPanel
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getControlPanel() {
+		if (controlPanel == null) {
+			GridLayout gridLayout3 = new GridLayout();
+			gridLayout3.setRows(1);
+			gridLayout3.setHgap(5);
+			gridLayout3.setColumns(2);
+			gridLayout3.setVgap(5);
+			controlPanel = new JPanel();
+			controlPanel.setMaximumSize(new Dimension(1000, 20));
+			controlPanel.setLayout(gridLayout3);
+			controlPanel.add(getJPanel3(), null);
+		}
+		return controlPanel;
+	}
+
+	/**
+	 * This method initializes startButton
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JButton getStartButton() {
+		if (startButton == null) {
+			startButton = new JButton();
+			startButton.setText("Start");
+		}
+		return startButton;
+	}
+
+	/**
+	 * This method initializes stepButton
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JButton getStepButton() {
+		if (stepButton == null) {
+			stepButton = new JButton();
+			stepButton.setText("Step");
+		}
+		return stepButton;
+	}
+
+	/**
+	 * This method initializes stopButton
+	 *
+	 * @return javax.swing.JButton
+	 */
+	private JButton getStopButton() {
+		if (stopButton == null) {
+			stopButton = new JButton();
+			stopButton.setText("Stop");
+		}
+		return stopButton;
+	}
+
+
+
+	/**
+	 * This method initializes jPanel3
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJPanel3() {
+		if (jPanel3 == null) {
+			GridBagConstraints gridBagConstraints14 = new GridBagConstraints();
+			gridBagConstraints14.gridx = -1;
+			gridBagConstraints14.gridy = -1;
+			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
+			gridBagConstraints13.gridx = -1;
+			gridBagConstraints13.gridy = -1;
+			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
+			gridBagConstraints12.anchor = GridBagConstraints.WEST;
+			gridBagConstraints12.gridy = -1;
+			gridBagConstraints12.gridx = -1;
+			jPanel3 = new JPanel();
+			jPanel3.setLayout(new GridBagLayout());
+			jPanel3.add(getStartButton(), gridBagConstraints12);
+			jPanel3.add(getStepButton(), gridBagConstraints13);
+			jPanel3.add(getStopButton(), gridBagConstraints14);
+		}
+		return jPanel3;
+	}
+
+	/**
+	 * This method initializes jScrollPane1
+	 *
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getJScrollPane1() {
+		if (jScrollPane1 == null) {
+			jScrollPane1 = new JScrollPane();
+			jScrollPane1.setViewportView(getSyncCommandList());
+		}
+		return jScrollPane1;
+	}
+
+	/**
+	 * This method initializes jPanel5
+	 *
+	 * @return javax.swing.JPanel
+	 */
+	private JPanel getJPanel5() {
+		if (jPanel5 == null) {
+			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
+			gridBagConstraints4.anchor = GridBagConstraints.NORTH;
+			gridBagConstraints4.insets = new Insets(3, 0, 0, 0);
+			gridBagConstraints4.gridy = 3;
+			jLabel3 = new JLabel();
+			jLabel3.setText("Console");
+			GridBagConstraints gridBagConstraints15 = new GridBagConstraints();
+			gridBagConstraints15.fill = GridBagConstraints.BOTH;
+			gridBagConstraints15.weighty = 1.0;
+			gridBagConstraints15.gridy = 4;
+			gridBagConstraints15.gridx = 0;
+			gridBagConstraints15.anchor = GridBagConstraints.SOUTH;
+			gridBagConstraints15.insets = new Insets(5, 5, 5, 5);
+			gridBagConstraints15.weightx = 1.0;
+			jPanel5 = new JPanel();
+			jPanel5.setLayout(new GridBagLayout());
+			jPanel5.add(jLabel3, gridBagConstraints4);
+			jPanel5.add(getJScrollPane2(), gridBagConstraints15);
+		}
+		return jPanel5;
+	}
+
+	/**
+	 * This method initializes jScrollPane2
+	 *
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getJScrollPane2() {
+		if (jScrollPane2 == null) {
+			jScrollPane2 = new JScrollPane();
+			jScrollPane2.setViewportView(getConsole());
+		}
+		return jScrollPane2;
+	}
+
+	/**
+	 * This method initializes console
+	 *
+	 * @return javax.swing.JTextArea
+	 */
+	private JTextArea getConsole() {
+		if (console == null) {
+			console = new JTextArea();
+		}
+		return console;
+	}
+
+}  //  @jve:decl-index=0:visual-constraint="10,10"

Added: trunk/src/appl/plugin/multimodelcontrol/MultiModelControlHandler.java
===================================================================
--- trunk/src/appl/plugin/multimodelcontrol/MultiModelControlHandler.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/plugin/multimodelcontrol/MultiModelControlHandler.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,773 @@
+package appl.plugin.multimodelcontrol;
+
+import java.awt.Color;
+import java.awt.PopupMenu;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Vector;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import appl.parallel.gui.ParallelControlPanelEngine;
+
+import schmitzm.data.event.ObjectEvent;
+import schmitzm.data.event.ObjectListener;
+import schmitzm.lang.WorkingThread;
+import schmitzm.lang.WorkingThreadAdapter;
+import schmitzm.lang.WorkingThreadListener;
+import schmitzm.swing.TextAreaPrintStream;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.appl.ModelControlManager;
+import edu.bonn.xulu.gui.ModelControlFrame;
+import edu.bonn.xulu.model.StepModel;
+import edu.bonn.xulu.model.XuluModel;
+import edu.bonn.xulu.model.event.ModelEvent;
+import edu.bonn.xulu.model.event.ModelListener;
+import edu.bonn.xulu.plugin.gui.ModelControlFrame_Basic;
+
+/**
+ * The class allows to control several models at once. At the moment it provides
+ * a batch like execution functionality. It is still under development but
+ * should basically work. It was developed in very short time and is therefore
+ * not as well commented, as other classes.
+ * 
+ * @author Dominik Appl
+ */
+public class MultiModelControlHandler implements ListSelectionListener,
+		ObjectListener, ActionListener {
+
+	private MultiModelControlFrame frame;
+
+	private final XuluModellingPlatform xulu;
+
+	private DefaultListModel modelListModel;
+
+	private ParallelControlPanelEngine parallelControlPanelEngine;
+
+	private DefaultListModel commandListModel;
+
+	private InterpretingThread interpretingThread;
+
+	private TextAreaPrintStream consoleStream;
+
+	private String string;
+
+	public MultiModelControlHandler(XuluModellingPlatform xulu) {
+		this.xulu = xulu;
+		frame = new MultiModelControlFrame();
+		initGUI();
+		consoleStream = new TextAreaPrintStream(frame.console);
+	}
+
+	/**
+	 * 
+	 */
+	private void initGUI() {
+		// register as listener for changes in the ModelControlManager
+		xulu.getModelControlManager().addObjectListener(this);
+		// init model list
+		initModelList();
+		initCommandList();
+		registerListeners();
+	}
+
+	/**
+	 * 
+	 */
+	private void registerListeners() {
+		frame.addStepCommand.addActionListener(this);
+		frame.newOverAllStep.addActionListener(this);
+		frame.clearModelSteps.addActionListener(this);
+		frame.startButton.addActionListener(this);
+		frame.stopButton.addActionListener(this);
+		frame.stepButton.addActionListener(this);
+		frame.modelList.addMouseListener(new java.awt.event.MouseAdapter() {
+			public void mouseClicked(java.awt.event.MouseEvent e) {
+				if (e.getClickCount() == 2) {
+					handleModelListDoubleClick();
+				}
+			}
+		});
+	}
+
+	/**
+	 * 
+	 */
+	private void initCommandList() {
+		commandListModel = new DefaultListModel();
+		frame.syncCommandList.setModel(commandListModel);
+		commandListModel.addElement(new StartCommand());
+		commandListModel.addElement(new StopCommand());
+		frame.syncCommandList
+				.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+		frame.syncCommandList.setSelectedIndex(0);
+	}
+
+	/**
+	 * inits the modelList
+	 */
+	private void initModelList() {
+		modelListModel = new DefaultListModel();
+		frame.modelList.setModel(modelListModel);
+		frame.modelList.addListSelectionListener(this);
+		int modelCount = xulu.getModelControlManager().getCount();
+		for (int i = 0; i < modelCount; i++) {
+			ModelControlFrame frame = xulu.getModelControlManager().getAll()[i];
+			this.addModelControlFrame(frame);
+		}
+		// frame.modelList.add(frame.modelPopupMenu);
+	}
+
+	public MultiModelControlFrame getFrame() {
+		return frame;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see schmitzm.data.event.ObjectListener#performObjectEvent(schmitzm.data.event.ObjectEvent)
+	 */
+	public void performObjectEvent(ObjectEvent e) {
+		// only listen for ChangeEvents
+		if (!(e instanceof ModelControlManager.ChangeEvent))
+			return;
+		ModelControlManager.ChangeEvent event = (ModelControlManager.ChangeEvent) e;
+		// if model was added:
+		if (event.getOldValue() == null && event.getNewValue() != null
+				&& event.getNewValue() instanceof ModelControlFrame)
+			addModelControlFrame((ModelControlFrame) event.getNewValue());
+		// if model was removed
+		if (event.getOldValue() != null && event.getNewValue() == null
+				&& event.getOldValue() instanceof ModelControlFrame)
+			removeModelControlFrame((ModelControlFrame) event.getOldValue());
+	}
+
+	/**
+	 * @param model
+	 */
+	private void addModelControlFrame(ModelControlFrame frame2) {
+		modelListModel.addElement(new ModelListObject(frame2,
+				frame2.getModel(), frame2.getModel().getName()));
+
+	}
+
+	/**
+	 * Removes the model, which belongs to the specified ModelControlFrame from
+	 * the list in the MCC
+	 * 
+	 * @param frame2
+	 *            the ModelControlFrame from the removed model
+	 */
+	private void removeModelControlFrame(ModelControlFrame frame2) {
+		// find the index of the model in the vector
+		for (int i = 0; i < modelListModel.size(); i++) {
+			ModelListObject m = (ModelListObject) modelListModel.get(i);
+			if (frame2.equals(m.getFrame()))
+				modelListModel.remove(i);
+		}
+	}
+
+	/**
+	 * @returns the actually selected ModelListObject from the model list
+	 */
+	private ModelListObject getSelectedModelListObject() {
+		return (ModelListObject) frame.modelList.getSelectedValue();
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
+	 */
+	public void valueChanged(ListSelectionEvent e) {
+		// TODO Auto-generated method stub
+	}
+
+	abstract class ModelCommand {
+		protected boolean finished = false;
+
+		public abstract String toString();
+
+		public void execute() {
+			finished = true;
+		}
+
+		public void reset() {
+			finished = false;
+		}
+
+		// /**
+		// * executed after all commands are executed
+		// */
+		// public void dispose()
+		// {
+		//			
+		// }
+
+		/**
+		 * @return true, if the execution is finished and no further execution
+		 *         is required
+		 */
+		public boolean hasFinished() {
+			return finished;
+		}
+
+		/**
+		 * tries to stop the execution of the command
+		 */
+		public void stop() {
+		};
+
+		/**
+		 * @return Message to be displayed in the console
+		 */
+		public String startMessage() {
+			return null;
+		}
+
+		/**
+		 * @return Message to be displayed
+		 */
+		public String finshedMessage() {
+			return null;
+		}
+	}
+
+	class RepeatStartCommand extends ModelCommand {
+		private final int execTimes;
+
+		private int alreadyExec;
+
+		/**
+		 * @param execTimes
+		 */
+		public RepeatStartCommand(int execTimes) {
+			this.execTimes = execTimes;
+			alreadyExec = 0;
+			// TODO Auto-generated constructor stub
+		}
+
+		public String toString() {
+			return "Start Repeat (" + execTimes + " exec)";
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
+		 */
+		@Override
+		public String finshedMessage() {
+			return "Starting Repeat (" + (alreadyExec) + "/" + execTimes + ")";
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#startMessage()
+		 */
+		@Override
+		public String startMessage() {
+			return null;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#execute()
+		 */
+		@Override
+		public void execute() {
+			alreadyExec++;
+			finished = true;
+		}
+
+		public void reset() {
+			finished = false;
+			alreadyExec = 0;
+		}
+	}
+
+	/**
+	 * The commands between start and stop are repeated
+	 * 
+	 * @author Dominik Appl
+	 */
+	class RepeatStopCommand extends ModelCommand {
+		private final int execTimes;
+
+		private int alreadyExec;
+
+		/**
+		 * @param execTimes
+		 */
+		public RepeatStopCommand(int execTimes) {
+			this.execTimes = execTimes;
+			alreadyExec = 0;
+		}
+
+		public String toString() {
+			return "End Repeat (" + execTimes + " exec)";
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
+		 */
+		@Override
+		public String finshedMessage() {
+			return "Loop iteration finished.(" + alreadyExec + "/" + execTimes
+					+ ")";
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#startMessage()
+		 */
+		@Override
+		public String startMessage() {
+			return null;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#execute()
+		 */
+		@Override
+		public void execute() {
+			alreadyExec++;
+			if (alreadyExec == execTimes)
+				finished = true;
+		}
+
+		public void reset() {
+			finished = false;
+			alreadyExec = 0;
+		}
+	}
+
+	class StartCommand extends ModelCommand {
+		public String toString() {
+			return "------- START MODELLING -------";
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
+		 */
+		@Override
+		public String finshedMessage() {
+			return "Starting execution...";
+		}
+
+	}
+
+	class StopCommand extends ModelCommand {
+		public String toString() {
+			return "------- MODELLING FINISHED -------";
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
+		 */
+		@Override
+		public String finshedMessage() {
+			return "Finished execution";
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#startMessage()
+		 */
+		@Override
+		public String startMessage() {
+			return null;
+		}
+	}
+
+	class ModelStepCommand extends ModelCommand {
+		private ModelControlFrame_Basic controlFrame;
+
+		private final Lock lock = new ReentrantLock();
+
+		private final Condition threadStillRunning = lock.newCondition();
+
+		private String name;
+
+		private XuluModel model;
+
+		private final int execTimes;
+
+		private int finishedExecutions = 0;
+
+		public void reset() {
+			finishedExecutions = 0;
+		}
+
+		/**
+		 * 
+		 */
+		public ModelStepCommand(ModelListObject mlo, int execTimes) {
+			this.execTimes = execTimes;
+			if (!(mlo.getFrame() instanceof ModelControlFrame_Basic))
+				throw new UnsupportedOperationException(
+						"The modelframe must be an instance of ModelControlFrame_Basic");
+			controlFrame = (ModelControlFrame_Basic) mlo.getFrame();
+			name = mlo.getName();
+			model = mlo.getModel();
+		}
+
+		public void execute() {
+			// check first if the model must be initialised
+			if (!model.isInitialised() && !model.isRunning()) {
+				controlFrame.setModelResources();
+				controlFrame.getControlContainer().init();
+			}
+			lock.lock();
+			try {
+				WorkingThreadAdapter adapter = new WorkingThreadAdapter() {
+					/*
+					 * (non-Javadoc)
+					 * 
+					 * @see schmitzm.lang.WorkingThreadAdapter#threadPaused(schmitzm.lang.WorkingThread)
+					 */
+					@Override
+					public void threadPaused(WorkingThread thread) {
+						try {
+							lock.lock();
+							// signal finished if the step is finished
+							threadStillRunning.signal();
+						} finally {
+							lock.unlock();
+						}
+					}
+
+					/*
+					 * (non-Javadoc)
+					 * 
+					 * @see schmitzm.lang.WorkingThreadAdapter#threadStopped(schmitzm.lang.WorkingThread)
+					 */
+					@Override
+					public void threadStopped(WorkingThread thread) {
+						try {
+							lock.lock();
+							// signal finished if the step is finished
+							threadStillRunning.signal();
+						} finally {
+							lock.unlock();
+						}
+					}
+				};
+				controlFrame.getControlContainer().getModelThread()
+						.addThreadListener(adapter);
+				controlFrame.getControlContainer().step();
+				// wait for the model step to finish
+				threadStillRunning.await();
+				controlFrame.getControlContainer().getModelThread()
+						.removeThreadListener(adapter);
+				finishedExecutions++;
+			} catch (InterruptedException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} finally {
+				lock.unlock();
+			}
+		}
+
+		public void stop() {
+			if (!model.isStopped())
+				controlFrame.getControlContainer().stop();
+			// try {
+			// controlFrame.getControlContainer().getModelThread().join();
+			// } catch (InterruptedException e) {
+			// // TODO Auto-generated catch block
+			// e.printStackTrace();
+			// }
+		}
+
+		@Override
+		public boolean hasFinished() {
+			return finishedExecutions >= execTimes;
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#toString()
+		 */
+		@Override
+		public String toString() {
+			return name + " (" + execTimes + " exec)";
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
+		 */
+		@Override
+		public String finshedMessage() {
+			return "...finished";
+		}
+
+		/*
+		 * (non-Javadoc)
+		 * 
+		 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#startMessage()
+		 */
+		@Override
+		public String startMessage() {
+			return "Executing step of " + name;
+		}
+
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
+	 */
+	public void actionPerformed(ActionEvent e) {
+		if (e.getSource() == frame.addStepCommand) {
+			handleAddNewStep();
+		}
+		if (e.getSource() == frame.newOverAllStep) {
+			handleRepeatStep();
+		}
+		if (e.getSource() == frame.startButton) {
+			startInterpreting();
+		}
+		if (e.getSource() == frame.stopButton) {
+			if (interpretingThread != null) {
+				interpretingThread.stopThread();
+			}
+			// ToDO: dispose all models
+
+		}
+		if (e.getSource() == frame.clearModelSteps) {
+			int delIdx = frame.syncCommandList.getSelectedIndex();
+			// do not delete first or last entry
+			if (delIdx > 0 && delIdx < commandListModel.getSize() - 1)
+				commandListModel.remove(delIdx);
+			frame.syncCommandList.setSelectedIndex(delIdx);
+
+		}
+	}
+
+	/**
+	 * 
+	 */
+	private void handleAddNewStep() {
+		if (checkInsertAllowed()) {
+			if (getSelectedModelListObject() == null) {
+				JOptionPane.showMessageDialog(null, "No model selected",
+						"No model selected", JOptionPane.ERROR_MESSAGE);
+				return;
+			}
+			int selIdx = frame.syncCommandList.getSelectedIndex();
+			int execTimes = 1;
+			// get execution times from user
+			try {
+				string = JOptionPane.showInputDialog(frame,
+						"How many steps do you want to execute for this enty?",
+						1);
+				execTimes = Integer.valueOf(string);
+				if (execTimes <= 0)
+					throw new UnsupportedOperationException(
+							"Only positive number allowed!");
+			} catch (Exception ex) {
+				JOptionPane.showMessageDialog(null,
+						"Only positive number allowed", "Error",
+						JOptionPane.ERROR_MESSAGE);
+				return;
+			}
+			commandListModel.add(selIdx + 1, new ModelStepCommand(
+					getSelectedModelListObject(), execTimes));
+			// select new entry
+			frame.syncCommandList.setSelectedIndex(selIdx + 1);
+		}
+	}
+
+	/**
+	 * 
+	 */
+	protected void handleModelListDoubleClick() {
+		ModelListObject selectedModelListObject = getSelectedModelListObject();
+		if (selectedModelListObject != null) {
+			selectedModelListObject.getFrame().setVisible(true);
+			selectedModelListObject.getFrame().toFront();
+		}
+
+	}
+
+	/**
+	 * 
+	 */
+	private void handleRepeatStep() {
+		if (checkInsertAllowed()) {
+			int selIdx = frame.syncCommandList.getSelectedIndex();
+			int execTimes = 1;
+			// get execution times from user
+			try {
+				string = JOptionPane.showInputDialog(frame,
+						"How many steps do you want to execute for this enty?",
+						1);
+				execTimes = Integer.valueOf(string);
+				if (execTimes <= 0)
+					throw new UnsupportedOperationException(
+							"Only positive numbers allowed!");
+			} catch (Exception ex) {
+				JOptionPane.showMessageDialog(null,
+						"Only positive numbers allowed", "Error",
+						JOptionPane.ERROR_MESSAGE);
+				return;
+			}
+			commandListModel.add(selIdx + 1, new RepeatStartCommand(execTimes));
+			commandListModel.add(selIdx + 2, new RepeatStopCommand(execTimes));
+
+			// select new entry
+			frame.syncCommandList.setSelectedIndex(selIdx + 1);
+		}
+	}
+
+	private void startInterpreting() {
+		// clear console and start Thread
+		frame.console.setText("");
+		interpretingThread = new InterpretingThread();
+		interpretingThread.start();
+
+	}
+
+	public void toggleGUI(boolean enabled) {
+		frame.modelList.setEnabled(enabled);
+		frame.addStepCommand.setEnabled(enabled);
+		frame.newOverAllStep.setEnabled(enabled);
+		frame.clearModelSteps.setEnabled(enabled);
+		if (enabled)
+			frame.syncCommandList.setSelectionBackground(Color.LIGHT_GRAY);
+		else
+			frame.syncCommandList.setSelectionBackground(Color.red);
+	}
+
+	/**
+	 * insert is allowed if its not the last position
+	 */
+	private boolean checkInsertAllowed() {
+		if (commandListModel.getSize() - 1 > frame.syncCommandList
+				.getSelectedIndex())
+			return true;
+		JOptionPane.showMessageDialog(null,
+				"You can add nothing after the end command!", "Error",
+				JOptionPane.ERROR_MESSAGE);
+		return false;
+	}
+
+	/**
+	 * Interprets the commandlist
+	 * 
+	 * @author Dominik Appl
+	 */
+	class InterpretingThread extends Thread {
+
+		private boolean exit;
+
+		private ModelCommand currentCommand;
+
+		/**
+		 * Creates a new Thread
+		 */
+		public InterpretingThread() {
+			exit = false;
+		}
+
+		/**
+		 * stops the Thread execution
+		 */
+		public void stopThread() {
+			exit = true;
+			if (currentCommand != null)
+				currentCommand.stop();
+		}
+
+		public void run() {
+			toggleGUI(false);
+			// reset all commands
+			for (int i = 0; i < frame.syncCommandList.getModel().getSize(); i++)
+				((ModelCommand) frame.syncCommandList.getModel()
+						.getElementAt(i)).reset();
+			// select first element
+			try {
+				frame.syncCommandList.setSelectedIndex(0);
+				int currentIdx = 0;
+				while (exit != true) {
+					currentCommand = (ModelCommand) commandListModel
+							.getElementAt(currentIdx);
+					// if the current command is an end of of a global loop
+					// than go back in the list until the start of the loop is
+					// found
+					if (currentCommand instanceof RepeatStopCommand) {
+						currentCommand.execute();
+						// if the all steps are done, just go on
+						if (currentCommand.hasFinished()) {
+							currentIdx++;
+							currentCommand = (ModelCommand) commandListModel
+									.getElementAt(currentIdx);
+						}
+						// else do the repetition by decreasing the index
+						// until the RepeatStartCommand is reached
+						else {
+							while (!(currentCommand instanceof RepeatStartCommand)) {
+								currentIdx--;
+								// if some structure error occured:
+								if (currentIdx <= 0) {
+									JOptionPane
+											.showMessageDialog(
+													frame,
+													"Something is wrong with the command structure. Do not use nested loops or other komplex structures!");
+									exit = true;
+									break;
+								}
+								currentCommand = (ModelCommand) commandListModel
+										.getElementAt(currentIdx);
+							}
+						}
+
+					}
+					if (currentCommand.startMessage() != null)
+						consoleStream.print(currentCommand.startMessage());
+					frame.syncCommandList.setSelectedIndex(currentIdx);
+					currentCommand.execute();
+					if (currentCommand.finshedMessage() != null)
+						consoleStream.println(currentCommand.finshedMessage());
+					// if the command has finished executing, get the next
+					// command
+					if (currentCommand.hasFinished())
+						currentIdx++;
+					if (currentIdx == commandListModel.getSize())
+						exit = true;
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+			} finally {
+				toggleGUI(true);
+			}
+		}
+	}
+
+}

Added: trunk/src/appl/plugin/multimodelcontrol/MultiModelControlPlugin.java
===================================================================
--- trunk/src/appl/plugin/multimodelcontrol/MultiModelControlPlugin.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/plugin/multimodelcontrol/MultiModelControlPlugin.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,29 @@
+package appl.plugin.multimodelcontrol;
+
+import javax.swing.JMenuItem;
+
+import edu.bonn.xulu.gui.XuluInternalFrame;
+import edu.bonn.xulu.plugin.appl.AbstractMenuPlugin;
+
+/**
+ * The Xulu plugin class. See {@link MultiModelControlHandler} for details.
+ *
+ * @author Dominik Appl
+ */
+public class MultiModelControlPlugin extends AbstractMenuPlugin{
+
+	/**
+	 */
+	public MultiModelControlPlugin() {
+		super(1,"Multi Model Control");
+	}
+
+	/* (non-Javadoc)
+	 * @see edu.bonn.xulu.plugin.appl.AbstractMenuPlugin#createPluginApplication()
+	 */
+	@Override
+	protected XuluInternalFrame createPluginApplication() throws Exception {
+		return new MultiModelControlHandler(this.appl).getFrame();
+	}
+
+}

Added: trunk/src/appl/plugin/multimodelcontrol/package.html
===================================================================
--- trunk/src/appl/plugin/multimodelcontrol/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/plugin/multimodelcontrol/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Contains a plugin which allows to control the execution of multiple models at once.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/util/GeneralUtil.java
===================================================================
--- trunk/src/appl/util/GeneralUtil.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/util/GeneralUtil.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,96 @@
+package appl.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.URL;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import net.jini.loader.pref.PreferredClassLoader;
+
+/**
+ * General utility class. See method description for details.
+ * 
+ * @author Dominik Appl
+ */
+public class GeneralUtil {
+
+	public static Logger LOG = LogManager.getLogger("appl.util.GeneralUtil");
+
+	/**
+	 * Loads a class from the specified URL and returns an instance of this class.
+	 * @param location the URL of the rootDirectory/networkLocation
+	 * @param classname the fully qualified name of the class (the class must have a 
+	 * 
+	 * @return the instance of the class or <code>null</code> if loading fails
+	 */
+	public static Object loadClassFromURL(URL location, String classname) {
+		try {
+			URL[] locations = { location };
+			PreferredClassLoader classLoader = new PreferredClassLoader(
+					locations, Thread.currentThread().getContextClassLoader(),
+					null, false);
+			LOG.debug("Try to load " + classname.getClass().getName()
+					+ " from " + location);
+			Class classObject = classLoader.loadClass(classname);
+			return classObject.newInstance();
+		} catch (Exception e) {
+			LOG.error("Could not load class for " + classname + " from "
+					+ location, e);
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * Serializes the given object into the specified file. All exceptions are printed to console.
+	 * @param o the object
+	 * @param destFile the file to write to
+	 */
+	public static void SerializeToFile(Object o, File destFile) {
+		try {
+			destFile.createNewFile();
+			BufferedOutputStream fos = new BufferedOutputStream(
+					new FileOutputStream(destFile));
+			ObjectOutputStream oos = new ObjectOutputStream(fos);
+			oos.writeObject(o);
+			oos.close();
+			fos.close();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Reads the first object out of the file
+	 * @param loadFile the file to read from
+	 * @return the object
+	 */
+	public static Object readSerializedFrom(File loadFile) {
+		Object loadedObject = null;
+		try {
+			BufferedInputStream fis = new BufferedInputStream(
+					new FileInputStream(loadFile));
+			ObjectInputStream ois = new ObjectInputStream(fis);
+			loadedObject = ois.readObject();
+			ois.close();
+			fis.close();
+			// remove File from Filesystem
+		} catch (FileNotFoundException e) {
+			LOG.error(e);
+			e.printStackTrace();
+
+		} catch (Exception e) {
+			LOG.error(e);
+			e.printStackTrace();
+		}
+		return loadedObject;
+	}
+}

Added: trunk/src/appl/util/NonEditableTableModel.java
===================================================================
--- trunk/src/appl/util/NonEditableTableModel.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/util/NonEditableTableModel.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,35 @@
+package appl.util;
+
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.TableModel;
+
+/**
+ * Simple {@link TableModel} that allows to specify columns which are not editable
+ * 
+ * @author Dominik Appl
+ */
+public class NonEditableTableModel extends DefaultTableModel {
+	private final boolean[] isEditable;
+
+	/**
+	 * @param columnNames
+	 *            <code>array</code> containing the names of the new columns;
+	 *            if this is <code>null</code> then the model has no columns
+	 * 
+	 * @param isEditable Specifies for each column if editable or not
+	 * 
+	 * @param rowCount
+	 *            the number of rows the table holds
+	 */
+	public NonEditableTableModel(Object[] columnNames, boolean[] isEditable,
+			int rowCount) {
+		super(columnNames, rowCount);
+		this.isEditable = isEditable;
+	}
+
+	@Override
+	public boolean isCellEditable(int row, int column) {
+		return isEditable[column];
+	}
+
+}

Added: trunk/src/appl/util/RasterUtil.java
===================================================================
--- trunk/src/appl/util/RasterUtil.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/util/RasterUtil.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,219 @@
+package appl.util;
+
+import java.awt.image.DataBuffer;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import schmitzm.data.WritableGrid;
+import schmitzm.geotools.io.GeoImportUtil;
+
+import org.geotools.gce.arcgrid.ArcGridRaster;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+/** 
+ * This Class provides some simple mostly independent functions 
+ * related to Geo-Rasters and {@link WritableGrid WritableGrids}.
+ * 
+ * @author Dominik Appl
+ *
+ */
+
+public class RasterUtil {
+
+		/**
+		 * Extracts metadata out of a ArcGridASCII File without reading the
+		 * whole Grid (only the Header is parsed).
+		 * 
+		 * @param src the ArcInfoASCII file
+		 * @return the meta data
+		 */
+	public static RasterMetaData getRasterMetaData_from_ArcGridASCII_File(
+			File src) {
+
+		try {
+			ArcGridRaster raster = new ArcGridRaster(new InputStreamReader(
+					new FileInputStream(src)), false);
+			raster.parseHeader();
+			  CoordinateReferenceSystem crs = GeoImportUtil.determineProjection(src);
+			return new RasterMetaData(DataBuffer.TYPE_FLOAT, raster.getNCols(),
+					raster.getNRows(), 0, 0, raster.getXlCorner(), raster
+							.getYlCorner(), raster.getCellSize(),crs);
+		    
+		   } catch (FileNotFoundException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			return new RasterMetaData(DataBuffer.TYPE_UNDEFINED, 0, 0, 0, 0, 0, 0,
+					0,null);
+	}
+
+	/**
+	 * Runs through every grid cell and checks if the two Grids are equal (based
+	 * on the {@link RasterMetaData} of the first Grid. If the difference is
+	 * smaller than 0.0001 only conversion Warning is given. Output to console
+	 * may be enabled. Writes out warning to sysout, if metaData is not equal,
+	 * but continues checking
+	 * 
+	 * @param a
+	 *            1st grid
+	 * @param b
+	 *            2nd grid
+	 * @param outputToConsole
+	 *            if true the results and some infos are written on System.out
+	 * @return true, if the grids match
+	 */
+	public static boolean checkEqual(WritableGrid a, WritableGrid b,
+			boolean outputToConsole) {
+
+		if (a == null && b == null)
+			return true;
+		if (a == null || b == null)
+			return false;
+
+		//for errors which are probably caused by rounding  
+		float diffTolerance = 1.0e-5f;
+		float maxdiff = 0; // maximum difference found
+		int maxdiffX = 0, maxdiffY = 0; // coordinates of maxdiff
+
+		RasterMetaData metaData = new RasterMetaData(a);
+		if (!metaData.equals(new RasterMetaData(b))) {
+			if (outputToConsole)
+				System.out
+						.println("Warning! Metadata of the two Grids is not equal!");
+		}
+
+		// run through the whole grid
+		float aValue, bValue;
+		float currentdiff;
+		int counter = 0;
+		for (int y = metaData.getMinY(); y < metaData.getHeight()
+				- metaData.getMinY(); y++)
+			for (int x = metaData.getMinX(); x < metaData.getWidth()
+					- metaData.getMinY(); x++) {
+				counter++;
+				aValue = a.getRasterSampleAsFloat(x, y);
+				bValue = b.getRasterSampleAsFloat(x, y);
+				//check equal
+				if (aValue == bValue)
+					continue;
+				if (Float.isNaN(aValue) && Float.isNaN(bValue))
+					continue;
+
+				//check for light differences which might indicate conversionErrors
+				currentdiff = Math.abs(aValue - bValue);
+				if (currentdiff < diffTolerance) {
+					if (currentdiff > maxdiff) {
+						maxdiff = currentdiff;
+						maxdiffX = x;
+						maxdiffY = y;
+					}
+					continue;
+				}
+				// else not equal:
+				if (outputToConsole)
+					System.out
+							.println("Warning: Two Grids were not equal at pos ("
+									+ x
+									+ ","
+									+ y
+									+ ") --- first value "
+									+ a.getRasterSampleAsFloat(x, y)
+									+ " and second value "
+									+ b.getRasterSampleAsFloat(x, y));
+				return false;
+			}
+		if (outputToConsole && !(maxdiff == 0))
+			System.out
+					.println("The Gridvalues differ slightly. The maximum Difference is: "
+							+ maxdiff
+							+ " at ("
+							+ maxdiffX
+							+ ","
+							+ maxdiffY
+							+ "). Finished grid compare after "
+							+ counter
+							+ " checks");
+		else if (outputToConsole)
+			System.out
+					.println("Grids found equal after " + counter + " checks");
+		return true;
+	}
+
+
+	/**
+	 * Copies all values from a {@link WritableGrid} into another
+	 * {@link WritableGrid}. Of course the grids must have the same dimensions.
+	 * 
+	 * @param src
+	 * @param target
+	 * @throws UnsupportedOperationException
+	 *             if the dimensions of the grids does not match or one of the
+	 *             grids is null
+	 */
+	public static void copyInto(WritableGrid src, WritableGrid target){
+		if(src==null || target==null)
+			throw new UnsupportedOperationException("Error: One of the grids was null");
+		//check if width and height are matching:
+		if((src.getHeight()!=target.getHeight()) || (src.getWidth()!=target.getWidth()))
+				throw new UnsupportedOperationException("The bounds of the two rasters don't not match! Copy failed!");
+		for(int y=0; y < src.getHeight();y++)
+			for(int x=0; x < src.getWidth(); x++)
+				target.setRasterSample(src.getRasterSample(x,y), x,y);
+		
+	}
+	
+	/**
+	 * Prints the grid to the console (useful for testing).
+	 * 
+	 * @param grid the grid to be printed
+	 * @param spacing the space to be reserved for one cell-value
+	 * @param precision the decimal places to be printed out
+	 * @param name the name will be shown in the heading of the output
+	 */
+	public static void printGrid(WritableGrid grid, int spacing, int precision, String name){
+		//generate format String
+		System.out.println("****************************** " + name +  " ******************************");
+		int width =grid.getWidth();
+		int noOfCells = grid.getWidth() * grid.getHeight();
+		Object[] cellarray = new Object[noOfCells];
+		StringBuffer buffer = new StringBuffer(noOfCells * 9);
+		String singleCellFormatString = "%" + spacing + "." + precision + "f ";
+		buffer.append("%n ");
+		for(int y=0; y < grid.getHeight();y++){
+			for(int x=0; x < grid.getWidth(); x++){
+				buffer.append(singleCellFormatString);
+				cellarray[y*width+x]=grid.getRasterSampleAsFloat(x,y);
+			}
+			buffer.append("%n ");
+		}
+		
+		System.out.printf(buffer.toString(), cellarray);
+	}
+	
+	/**
+	 * Prints the grid to the console (useful for testing).
+	 * Spacing will be 5 and precision will be 2.
+	 * 
+	 * @param grid the grid to be printed
+	 * @param name the name will be shown in the heading of the output
+	 */
+	public static void printGrid(WritableGrid grid, String name){
+		printGrid(grid,5,2,name);
+	}
+	
+	/**
+	 * Prints the grid to the console (useful for testing). 
+	 * Spacing will be 5 and precision will be 2.
+	 * 
+	 * @param grid the grid to be printed
+	 */
+	public static void printGrid(WritableGrid grid){
+		printGrid(grid," ");
+	}
+}

Added: trunk/src/appl/util/XuluFrameAdapter.java
===================================================================
--- trunk/src/appl/util/XuluFrameAdapter.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/util/XuluFrameAdapter.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,53 @@
+package appl.util;
+
+import javax.swing.JPanel;
+
+import edu.bonn.xulu.gui.XuluInternalFrame;
+import java.awt.Dimension;
+
+/**
+ * Makes an XuluInternalFrame out of a {@link JPanel}.
+ * 
+ * @author Dominik Appl
+ */
+public class XuluFrameAdapter extends XuluInternalFrame{
+
+	
+	private final JPanel panel;
+
+
+
+	/**
+	 * Creates the internal Frame
+	 * @param titel the window-title
+	 * @param panel the panel to be displayed in the frame
+	 */
+	public XuluFrameAdapter(String titel, JPanel panel) {
+		super(titel);
+		this.panel = panel;
+		initialize();
+		   
+	}
+
+	
+
+	/**
+	 * This method initializes this
+	 * 
+	 */
+	private void initialize() {
+        this.setSize(new Dimension(panel.getSize().width, panel.getSize().height + 30));
+        this.setClosable(true);
+	    this.setDefaultCloseOperation( HIDE_ON_CLOSE );
+	    this.getContentPane().add(panel);	
+	}
+
+
+
+	@Override
+	public void refresh() {
+		
+		
+	}
+
+}  //  @jve:decl-index=0:visual-constraint="10,10"

Added: trunk/src/appl/util/benchmark/Benchmark.java
===================================================================
--- trunk/src/appl/util/benchmark/Benchmark.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/util/benchmark/Benchmark.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,17 @@
+package appl.util.benchmark;
+
+/**
+ * Simple Interface for Benchmarks. Benchmarks may be used to give the user an
+ * impression of the hardware capabilities.
+ * 
+ * @author Dominik Appl
+ */
+public interface Benchmark {
+	/**
+	 * runs the Benchmark
+	 * 
+	 * @return a rating. The rating should be a positive number and linear in
+	 *         the computing power
+	 */
+	public int bench();
+}

Added: trunk/src/appl/util/benchmark/SimpleBenchmark.java
===================================================================
--- trunk/src/appl/util/benchmark/SimpleBenchmark.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/util/benchmark/SimpleBenchmark.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,127 @@
+package appl.util.benchmark;
+
+import java.awt.Rectangle;
+import java.awt.image.DataBuffer;
+import java.util.Random;
+
+import appl.data.LoadingException;
+import appl.ext.XuluConfig;
+import appl.parallel.data.splittable.SplittableLLProxyGrid;
+import appl.util.RasterMetaData;
+import appl.util.RasterUtil;
+import edu.bonn.xulu.plugin.io.grid.array.WritableGridArrayFactory;
+
+/**
+ * The algorithm simply iterates over a grid. The with and height can be
+ * specified by the {@link XuluConfig} Property
+ * <code>Benchmark.SimpleBench.gridwidth</code>. For each cell the average
+ * over a neighborhood region is calculated. The neighborhoodRange can be
+ * specified by <code>Benchmark.SimpleBench.neighborhood</code>. If the
+ * algorithm reaches the end of the raster it starts again at (0,0). The rating
+ * depends on the number of cells visited in the time (ms) specified by
+ * <code>Benchmark.SimpleBench.time<code>. The number of cells is divided by
+ * <code>Benchmark.SimpleBench.calibrator</code> and then given back as rating.
+ * 
+ * @author Dominik Appl
+ */
+public class SimpleBenchmark implements Benchmark {
+	private SplittableLLProxyGrid inputGrid;
+
+	int runningTime = 10000;
+
+	private int gridwidth = 1000;
+
+	private int neighborhoodRange;
+
+	private double calibrator = 1;
+
+	public int bench() {
+		setUp();
+
+		int cellCount = 0;
+		long startTime = System.currentTimeMillis();
+		Rectangle partition = new Rectangle(0, 0, inputGrid.getWidth(),
+				inputGrid.getHeight());
+		boolean exit = false;
+		for (int step = 0; exit == false; step++) {
+			// the overallsum is simply the sum over all elements
+			float overallSum = 0f;
+			for (int y = 0; y < inputGrid.getHeight(); y++)
+				for (int x = 0; x < inputGrid.getWidth(); x++) {
+					if (System.currentTimeMillis() - startTime > runningTime)
+						exit = true;
+					else
+						cellCount++;
+					float tmp = inputGrid.getRasterSampleAsFloat(x, y);
+					if (!Float.isNaN(tmp))
+						overallSum += tmp;
+					// the local sum is simply the sum over all elements in the
+					// neighborhood
+					float localSum = 0;
+					// number of cells over which the sum is calculated
+					int noOfCells = 0;
+					// for each cell: calculate the sum of all neighbors
+					for (int y2 = y - neighborhoodRange; y2 <= y
+							+ neighborhoodRange; y2++)
+						for (int x2 = x - neighborhoodRange; x2 <= x
+								+ neighborhoodRange; x2++)
+							// check if the coordinates are valid (inside the
+							// grid and not NaN)
+							if (partition.contains(x2, y2))
+								if (!Float.isNaN(inputGrid
+										.getRasterSampleAsFloat(x2, y2))) {
+									localSum += inputGrid
+											.getRasterSampleAsFloat(x2, y2);
+									noOfCells++;
+								}
+
+				}
+		}
+		return (int) (cellCount / calibrator);
+	}
+
+	/**
+	 * The method is used to load grids and to initialize the benchmarks
+	 * configuration.
+	 */
+	private void setUp() {
+		// read config
+		int width = XuluConfig.getXuluConfig().getIntProperty(
+				"Benchmark.SimpleBench.gridwidth");
+		if (width != 0)
+			this.gridwidth = width;
+		// init running time
+		int time = XuluConfig.getXuluConfig().getIntProperty(
+				"Benchmark.SimpleBench.runningtime");
+		if (time != 0)
+			this.runningTime = time;
+		// init calibrator
+		double calibrator = XuluConfig.getXuluConfig().getDoubleProperty(
+				"Benchmark.SimpleBench.calibrator");
+		if (calibrator != 0)
+			this.calibrator = calibrator;
+		// init neighborhoodRange
+		neighborhoodRange = XuluConfig.getXuluConfig().getIntProperty(
+				"Benchmark.SimpleBench.neighborhood");
+		// create input Grid
+		inputGrid = new SplittableLLProxyGrid(new WritableGridArrayFactory(),
+				new RasterMetaData(DataBuffer.TYPE_DOUBLE, gridwidth,
+						gridwidth, 0, 0, 0, 0, 50, null));
+		// load grid (so late loading has no influence on the calculation)
+		try {
+			inputGrid.loadData();
+		} catch (LoadingException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		// fill Grid with random Data
+		Random rand = new Random();
+		for (int y = 0; y < inputGrid.getHeight(); y++)
+			for (int x = 0; x < inputGrid.getWidth(); x++)
+				inputGrid.setGridSample(rand.nextDouble(), x, y);
+	}
+
+	public static void main(String[] args) {
+		System.out.println("Current rating: " + new SimpleBenchmark().bench());
+	}
+}

Added: trunk/src/appl/util/benchmark/package.html
===================================================================
--- trunk/src/appl/util/benchmark/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/util/benchmark/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Provides benchmarking functionality.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/appl/util/package.html
===================================================================
--- trunk/src/appl/util/package.html	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/appl/util/package.html	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,5 @@
+<html>
+<body>
+	Collection of several usefull classes.
+</body>
+</html>
\ No newline at end of file

Added: trunk/src/de/skrueger/xulu/plugin/gnur/GnuRGUI.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/GnuRGUI.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/GnuRGUI.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,420 @@
+/** GnuR Plugin - A XULU-plugin for applying R-powered statistics on objects in the XULU-datapool.
+    Copyright (C) 2007  Stefan A. Krüger
+
+    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+    You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+    Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+    Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+    Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/   
+package de.skrueger.xulu.plugin.gnur;
+
+/**
+ * TODO 
+ * Ausführen von .R skripten
+ * Löschen des Workspace!?
+ * Ãœbergabe von Grids
+ * Eingabefeld zu TextFied für mherzeilige Eingaben
+ */
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetAdapter;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+
+import org.rosuda.JRI.REXP;
+import org.rosuda.JRI.RList;
+import org.rosuda.JRI.RVector;
+import org.rosuda.JRI.Rengine;
+
+import schmitzm.data.RasterCalculator;
+import schmitzm.data.event.ObjectEvent;
+import schmitzm.data.event.ObjectListener;
+import schmitzm.data.property.ListProperty;
+import schmitzm.data.property.ListPropertyReadAccess;
+import schmitzm.data.property.Property;
+import schmitzm.swing.ManualInputOption;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.appl.DataPool;
+import edu.bonn.xulu.gui.XuluInternalFrame;
+import edu.bonn.xulu.plugin.data.grid.MultiGrid;
+import edu.bonn.xulu.plugin.data.grid.SingleGrid;
+
+public class GnuRGUI extends XuluInternalFrame {
+  /** Speichert eine Referenz auf das Fenster-Objekt, um aus verschachtelten
+   *  Klassen einfach darauf zugreifen zu koennen. */
+  protected final GnuRGUI THIS = this;
+  /** Speichert eine Referenz auf die Xulu-Applikation, in der der Code-Generator
+   *  ausgefuehrt wird. */
+  protected XuluModellingPlatform appl = null;
+  /** Tabelle in der die Eingabe-Raster angegeben werden. */
+  protected RVarsTable            rVarsTable = null;
+  private   RVarsTableModel 	  rVarsTableModel = null;
+  private   JScrollPane           rVarsScrollPane = null;
+
+  /** Eingabefeld fuer die Formel. */
+  protected ManualInputOption.Text rule = null;
+  /** Button to Import the Variables to R from the datapool. */
+  protected JButton importButton = null;
+  /** Button to Export the Variables from R to the datapool. */
+  protected JButton exportButton = null;
+
+  /** Referenz auf den Container des Fensters. */
+  protected Container contentPane = null;
+  /** The RConsole-Panel contains of ab Output- and an Inputfied for R */
+  private RConsolePanel rConsole = null;
+
+  /**
+   * Erzeugt eine neue GUI fuer den {@link RasterCalculator}.
+   * @param appl Instanz der Xulu-Applikation, in der der Rechner
+   *             ausgefuehrt wird
+   */
+  public GnuRGUI(XuluModellingPlatform appl) {
+    super("GNU-R toolbox");
+    this.appl = appl;
+
+    this.setVisible(false);
+    this.setSize( new Dimension(500,400) );
+    this.setClosable(true);
+    this.setDefaultCloseOperation( HIDE_ON_CLOSE );
+    this.getContentPane().setLayout( new GridBagLayout() );
+    contentPane  = this.getContentPane();
+    initGUI();
+    refresh();
+
+    // Listener auf den Datenpool setzen, damit Auswahlfelder automatisch
+    // aktualisiert werden
+    appl.getDataPool().addObjectListener( new ObjectListener() {
+      public void performObjectEvent(ObjectEvent e) {
+        if ( e instanceof DataPool.DataPoolChangeEvent )
+          refresh();
+      }
+    });
+  }
+
+  /**
+   * Initalisiert die GUI des Fensters.
+   */
+  protected void initGUI() {
+	// Input-Raster-Tabelle
+	rVarsTableModel = new RVarsTableModel(appl);
+	rVarsTable = new RVarsTable(rVarsTableModel);
+	rVarsTable.setToolTipText("Simply do drang and drop");
+	rVarsTable.setPreferredScrollableViewportSize( new Dimension(400,200));
+	rVarsScrollPane = rVarsTable.createScrollPane();
+	// Formel
+	rule = new ManualInputOption.Text("Rule:", true);
+	rule
+		.setToolTipText("Insert your arithmetical rule here (Use arithmetical operators, constants and #1, #2, ... as raster reference identifier)");
+	// Button zum Starten
+	importButton = new JButton("Import");
+	importButton.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		importRVars();
+		// After Import of vars into R, show all vars..
+		rConsole.sendToConsole("ls()");
+	    }
+	});
+
+	exportButton = new JButton("Export");
+	exportButton.addActionListener(new ActionListener() {
+	    public void actionPerformed(ActionEvent e) {
+		exportRVars();
+	    }
+	});
+
+	// Drag & Drop fuer RVars
+	DropTarget dropTarget = new DropTarget(appl.getMainFrame(),
+		new DropTargetAdapter() {
+		    public void dragEnter(DropTargetDragEvent e) {
+
+			// Pruefen, ob mind, ein akzeptables Objekt im Datenpool
+                        // selektiert ist
+			Object[] selObjects = appl.getMainFrame()
+				.getDataPoolFrame().getSelectedObjects();
+			for (Object obj : selObjects) {
+			    try {
+				RVarAdapter.createFrom((Property) obj, true);
+        			return;
+			    } catch (PropertytypeNotConvertableToRVar ee) {
+				// ee.printStackTrace();
+				System.out.println("Not convertable..");
+			    } 
+			    System.out.println(obj.getClass());
+			}
+			// Reject drop, if nothing convertible was found.
+			e.rejectDrag();
+		    }
+
+		    public void drop(DropTargetDropEvent e) {
+			Object[] selObjects = appl.getMainFrame()
+				.getDataPoolFrame().getSelectedObjects();
+
+			for (Object obj : selObjects) {
+			    // rVarsTableModel.addRVariable(
+				    //RVarAdapter.createFrom(obj, false)  );
+			    refresh();
+			}
+		    }
+		});
+
+	rVarsTable.setDropTarget(dropTarget);
+	rVarsScrollPane.setDropTarget(dropTarget);
+
+	/*
+         * The R-Console Window
+         */
+	try {
+	    rConsole = new RConsolePanel();
+	    rConsole.init();
+	} catch (IOException e1) {
+	    e1.printStackTrace();
+	}
+
+	// Komponenten in Fenster anordnen
+	contentPane.add(new JLabel("Input/Output-Rasters (use context menu or simply drag rasters from xulu data pool):"), new GridBagConstraints(
+		0, 0, 2, 1, 0, 0,
+		GridBagConstraints.NORTHWEST,
+		GridBagConstraints.HORIZONTAL, 
+		new Insets(5, 10, 0,10), 0, 0));
+	
+	contentPane.add(rVarsScrollPane, new GridBagConstraints(
+		0, 1, 2, 3, 0.1, 0.1, 
+		GridBagConstraints.CENTER, 
+		GridBagConstraints.BOTH,
+		new Insets(0, 10, 5, 10), 0, 0));
+
+	contentPane.add(rConsole, new GridBagConstraints(
+		0, 4, 2, 2, 0.5, 0.5,
+		GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, 
+		new Insets(0, 10, 5, 10), 0, 0));
+
+	contentPane.add(importButton, new GridBagConstraints(
+		0, 6, 1, 1, 0.0, 0, 
+		GridBagConstraints.WEST, 
+		GridBagConstraints.NONE,
+		new Insets(0, 10, 5, 10), 0, 0));
+	contentPane.add(exportButton, new GridBagConstraints(
+		1, 6, 1, 1, 0.0, 0, 
+		GridBagConstraints.WEST, 
+		GridBagConstraints.NONE,
+		new Insets(0, 10, 5, 10), 0, 0));
+    }
+
+
+/**
+ * Aktualisiert die Auswahl-Felder auf Basis des Datenpools.
+ */
+  public void refresh() {
+    // Aktualisierung der Tabelle
+    rVarsTableModel.refreshInputOption();
+    rVarsTableModel.fireTableDataChanged();
+  }
+
+
+
+
+  /**
+   */
+  private void exportRVars() {
+		if (rConsole.getREngine() == null) return;
+		System.out.println("Reusing Rengine.. Exporting from R... ");
+		
+		Vector<RVarAdapter> vars = rVarsTableModel.getRVars();
+		for (RVarAdapter rv : vars) {
+			//TODO  rv.fromR( rConsole.getREngine() );
+		}
+  }
+
+  private void importRVars() {
+	Vector<RVarAdapter> vars = rVarsTableModel.getRVars();
+	for (RVarAdapter rv : vars) {
+		rv.toR(rConsole.getREngine());
+	}
+  }
+
+  
+  private void doRstuff(Rengine re) {
+		/* High-level API - do not use RNI methods unless there is no other way
+			to accomplish what you want */
+		try {
+			REXP x;
+			re.eval("data(iris)",false);
+			System.out.println(x=re.eval("iris"));
+			System.out.println(x=re.eval("a <- 2*3"));
+			System.out.println(re.eval("a"));
+			// generic vectors are RVector to accomodate names
+			RVector v = x.asVector();
+			if (v.getNames()!=null) {
+				System.out.println("has names:");
+				for (Enumeration e = v.getNames().elements() ; e.hasMoreElements() ;) {
+					System.out.println(e.nextElement());
+				}
+			}
+			// for compatibility with Rserve we allow casting of vectors to lists
+			RList vl = x.asList();
+			String[] k = vl.keys();
+			if (k!=null) {
+				System.out.println("and once again from the list:");
+				int i=0; while (i<k.length) System.out.println(k[i++]);
+			}			
+			
+			// now for a real dotted-pair list:
+			System.out.println(x=re.eval("pairlist(a=1,b='foo',c=1:5)"));
+			RList l = x.asList();
+			if (l!=null) {
+				int i=0;
+				String [] a = l.keys();
+				System.out.println("Keys:");
+				while (i<a.length) System.out.println(a[i++]);
+				System.out.println("Contents:");
+				i=0;
+				while (i<a.length) System.out.println(l.at(i++));
+			}
+			System.out.println(re.eval("sqrt(36)"));
+		} catch (Exception e) {
+			System.out.println("EX:"+e);
+			e.printStackTrace();
+		}
+		
+		// Part 2 - low-level API - for illustration purposes only!
+		//System.exit(0);
+		
+	    // simple assignment like a<-"hello" (env=0 means use R_GlobalEnv)
+	    long xp1 = re.rniPutString("hello");
+	    re.rniAssign("a", xp1, 0);
+
+	    // Example: how to create a named list or data.frame
+	    double da[] = {1.2, 2.3, 4.5};
+	    double db[] = {1.4, 2.6, 4.2};
+	    long xp3 = re.rniPutDoubleArray(da);
+	    long xp4 = re.rniPutDoubleArray(db);
+	    
+	    // now build a list (generic vector is how that's called in R)
+	    long la[] = {xp3, xp4};
+	    long xp5 = re.rniPutVector(la);
+
+	    // now let's add names
+	    String sa[] = {"a","b"};
+	    long xp2 = re.rniPutStringArray(sa);
+	    re.rniSetAttr(xp5, "names", xp2);
+
+	    // ok, we have a proper list now
+	    // we could use assign and then eval "b<-data.frame(b)", but for now let's build it by hand:       
+	    String rn[] = {"1", "2", "3"};
+	    long xp7 = re.rniPutStringArray(rn);
+	    re.rniSetAttr(xp5, "row.names", xp7);
+	    
+	    long xp6 = re.rniPutString("data.frame");
+	    re.rniSetAttr(xp5, "class", xp6);
+	    
+	    // assign the whole thing to the "b" variable
+	    re.rniAssign("b", xp5, 0);
+	    {
+	        System.out.println("Parsing");
+	        long e=re.rniParse("data(iris)", 1);
+	        System.out.println("Result = "+e+", running eval");
+	        long r=re.rniEval(e, 0);
+	        System.out.println("Result = "+r+", building REXP");
+	        REXP x=new REXP(re, r);
+	        System.out.println("REXP result = "+x);
+	    }
+	    {
+	        System.out.println("Parsing");
+	        long e=re.rniParse("iris", 1);
+	        System.out.println("Result = "+e+", running eval");
+	        long r=re.rniEval(e, 0);
+	        System.out.println("Result = "+r+", building REXP");
+	        REXP x=new REXP(re, r);
+	        System.out.println("REXP result = "+x);
+	    }
+	    {
+	        System.out.println("Parsing");
+	        long e=re.rniParse("names(iris)", 1);
+	        System.out.println("Result = "+e+", running eval");
+	        long r=re.rniEval(e, 0);
+	        System.out.println("Result = "+r+", building REXP");
+	        REXP x=new REXP(re, r);
+	        System.out.println("REXP result = "+x);
+	        String s[]=x.asStringArray();
+	        if (s!=null) {
+	            int i=0; while (i<s.length) { System.out.println("["+i+"] \""+s[i]+"\""); i++; }
+	        }
+	    }
+	    {
+	        System.out.println("Parsing");
+	        long e=re.rniParse("rnorm(10)", 1);
+	        System.out.println("Result = "+e+", running eval");
+	        long r=re.rniEval(e, 0);
+	        System.out.println("Result = "+r+", building REXP");
+	        REXP x=new REXP(re, r);
+	        System.out.println("REXP result = "+x);
+	        double d[]=x.asDoubleArray();
+	        if (d!=null) {
+	            int i=0; while (i<d.length) { System.out.print(((i==0)?"":", ")+d[i]); i++; }
+	            System.out.println("");
+	        }
+	        System.out.println("");
+	    }
+	    {
+	        REXP x=re.eval("1:10");
+	        System.out.println("REXP result = "+x);
+	        int d[]=x.asIntArray();
+	        if (d!=null) {
+	            int i=0; while (i<d.length) { System.out.print(((i==0)?"":", ")+d[i]); i++; }
+	            System.out.println("");
+	        }
+	    }
+
+	    re.eval("print(1:10/3)");
+	    
+	if (false) {
+	    // so far we used R as a computational slave without REPL
+	    // now we start the loop, so the user can use the console
+	    System.out.println("Now the console is yours ... have fun");
+	    re.startMainLoop();
+	} else {
+	    re.end();
+	    System.out.println("end");
+	}    
+	  
+  }
+  
+  private static ListProperty[] getListPropertysFromObject(Object obj){
+	  if ( obj instanceof SingleGrid )
+	      obj = ((SingleGrid)obj).getProperty( SingleGrid.PROP_GRID );
+	    if ( obj instanceof MultiGrid )
+	      obj = ((MultiGrid)obj).getProperty( MultiGrid.PROP_GRIDS );
+
+	    
+	    	    	
+    if ( obj instanceof ListProperty ) {
+        ListPropertyReadAccess a = ((ListProperty)obj).getReadAccess(obj);
+        ListProperty[] lists = new ListProperty[ a.getCount() ];
+        for (int i=0; i<lists.length; i++)
+          lists[i] = (ListProperty)a.getValue(i);
+        a.release();
+        return lists;
+      }
+      return null;
+  }
+
+    
+
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/GnuRPlugin.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/GnuRPlugin.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/GnuRPlugin.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,40 @@
+/** GnuR Plugin - A XULU-plugin for applying R-powered statistics on objects in the XULU-datapool.
+    Copyright (C) 2007  Stefan A. Krüger
+
+    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+    You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+    Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+    Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+    Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/   
+package de.skrueger.xulu.plugin.gnur;
+
+import edu.bonn.xulu.gui.XuluInternalFrame;
+import edu.bonn.xulu.plugin.appl.AbstractMenuPlugin;
+
+/**
+ * This plugin implements the {@link de.skrueger.xulu.plugin.gnur.GnuRGUI}
+ * into the Xulu-menu "Model".
+ * @author <a href="mailto:stefan at wikisquare.de">Stefan Krueger</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class GnuRPlugin extends AbstractMenuPlugin  {
+  private static final int MODEL_MENU = 1;
+
+  /**
+   * Erzeugt eine neue Plugin-Instanz.
+   */
+  public GnuRPlugin() {
+    super(MODEL_MENU,"Use GNU-R on your datapool");
+  }
+  
+  /**
+   * Erzeugt eine Instanz der Plugin-Applikation {@link GnuRGUI}.
+   */
+  protected XuluInternalFrame createPluginApplication() throws Exception {
+//    return (XuluInternalFrame)LangUtil.loadClass(CALCULATOR_CLASSNAME,appl.getDynamicClassRootDirectory().toURL()).getConstructor(XuluModellingPlatform.class).newInstance(appl);
+    return new GnuRGUI(appl);
+  }
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/JRTextArea.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/JRTextArea.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/JRTextArea.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,57 @@
+/** GnuR Plugin - A XULU-plugin for applying R-powered statistics on objects in the XULU-datapool.
+    Copyright (C) 2007  Stefan A. Krüger
+
+    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+    You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+    Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+    Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+    Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/   
+package de.skrueger.xulu.plugin.gnur;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.TexturePaint;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+import javax.swing.JTextArea;
+
+public class JRTextArea extends JTextArea {
+	static BufferedImage img = null;
+	TexturePaint texture;
+	boolean fileFound = false;
+	
+	public JRTextArea() {
+		super();
+		if (img == null)	// Open the image if not happened earlier  
+		    try {
+			File file = new File ("rlogo.jpg");
+			System.out.println("name = "+file.getAbsolutePath());
+			img = ImageIO.read( file);
+		    } catch (IOException e) {
+			e.printStackTrace();
+		    }		
+		fileFound = true;
+		// Schrift ausgeben
+		setOpaque(false);
+	}
+	
+	public void paintComponent(Graphics g) {
+		if (fileFound){
+			Graphics2D g2 = (Graphics2D)g;
+			Rectangle rect = new Rectangle(0,0, img.getWidth(null), img.getHeight(null));
+			texture = new TexturePaint(img, rect);
+			g2.setPaint(texture);
+			g.fillRect(0, 0, getWidth(), getHeight());
+			g.drawString("sds", 0, 0);
+		}
+		super.paintComponent(g);
+	}
+	
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/PropertytypeNotConvertableToRVar.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/PropertytypeNotConvertableToRVar.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/PropertytypeNotConvertableToRVar.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,33 @@
+/** GnuR Plugin - A XULU-plugin for applying R-powered statistics on objects in the XULU-datapool.
+    Copyright (C) 2007  Stefan A. Krüger
+
+    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+    You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+    Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+    Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+    Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/  
+package de.skrueger.xulu.plugin.gnur;
+
+import schmitzm.data.property.Property;
+import schmitzm.data.property.PropertyException;
+
+/**
+ * This Exception is thrown, when the object from the datapool is not convertable to an R object. This can be
+ * due to the structure of the data, or due to the GnuR plugins capabilities.  
+ *
+ * @author Stefan A. Krüger
+ */
+public class PropertytypeNotConvertableToRVar extends PropertyException{
+
+	public PropertytypeNotConvertableToRVar(Property prop) {
+		super(prop, "The Propertytype can not be converted to an R variable.");
+	}
+
+	public PropertytypeNotConvertableToRVar(Property prop, String msg) {
+	    super(prop, msg);
+	}
+
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/RConsolePanel.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/RConsolePanel.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/RConsolePanel.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,322 @@
+/** GnuR Plugin - A XULU-plugin for applying R-powered statistics on objects in the XULU-datapool.
+    Copyright (C) 2007  Stefan A. Krüger
+
+    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+    You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+    Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+    Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+    Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/
+package de.skrueger.xulu.plugin.gnur;
+
+import java.awt.Cursor;
+import java.awt.FileDialog;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.util.Vector;
+
+import javax.swing.BorderFactory;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.border.EtchedBorder;
+
+import org.apache.log4j.Logger;
+import org.rosuda.JRI.RMainLoopCallbacks;
+import org.rosuda.JRI.Rengine;
+
+public class RConsolePanel extends JPanel implements RMainLoopCallbacks {
+    Logger log; // TODO .. some smarter logging that System.out
+
+    /** There may only be one REngine for the whole XULU Framework.*/
+    private static Rengine re = null;
+
+    boolean readInput = false;		// Is true when the InputField is ready to be sent to R
+    boolean readInput2 = false;		// Is true when the internal InputField is ready to be sent to R
+
+    // Output from R
+    public JTextArea rOut = new JRTextArea();
+    private JScrollPane cmdOutSp;
+
+    // Inputf to R
+    public JTextArea rCmdIn = new JTextArea(4,80);
+    private JScrollPane cmdInSp;
+
+    // Keeps a list of the last commands entered in R.
+    Vector<String> history    = new Vector<String>();
+    int    historyPos = 0;
+
+    protected int maxLines = 200;
+
+    /* Cursor when waiting for R */
+    Cursor hourglassCursor = new Cursor(Cursor.WAIT_CURSOR);
+    Cursor defaultCursor = new Cursor(Cursor.DEFAULT_CURSOR);
+
+    public RConsolePanel() throws IOException {
+        rOut.setEditable(false);
+        rOut.setRows(200);
+        rOut.setBorder( BorderFactory.createEtchedBorder(EtchedBorder.LOWERED) );
+
+        rCmdIn.addKeyListener(keyL);
+        rCmdIn.setBorder( BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
+
+        setLayout(new GridBagLayout());
+        cmdOutSp = new JScrollPane( rOut );
+	add(  cmdOutSp ,
+        	new GridBagConstraints(
+        		0, 0, 2, 1, 1, 1,
+        		GridBagConstraints.NORTHWEST,
+        		GridBagConstraints.BOTH,
+        		new Insets(5, 0, 2, 0),
+        		0, 0) );
+        cmdInSp = new JScrollPane( rCmdIn );
+        	add(  cmdInSp, new GridBagConstraints(
+        		0, 1, 2, 1, 1, 1,
+        		GridBagConstraints.NORTHWEST,
+        		GridBagConstraints.BOTH,
+        		new Insets(2, 0, 5, 0),
+        		0, 0) );
+    }
+
+    public void init() {
+	if (re == null) {
+	    System.out.println("Creating Rengine (with arguments)");
+            String[] args = new String[1];
+            args[0] = "--no-save";
+            // 1) we pass the arguments from the command line
+            // 2) we won't use the main loop at first, we'll start it later
+            // (that's the "false" as second argument)
+            // 3) the callbacks are implemented by the TextConsole class above
+            re = new Rengine(args, false, this);
+            System.out.println("Rengine created, waiting for R");
+            // the engine creates R is a new thread, so we should wait until
+            // it's ready
+            if (!re.waitForR()) {
+        	System.out.println("Cannot load R");
+    		return;
+    	    }
+    	    re.startMainLoop();
+    	};
+    }
+
+    final KeyListener keyL = new KeyAdapter() {
+        public void keyPressed(KeyEvent ev) {
+
+            if(ev.getKeyCode() == KeyEvent.VK_UP + KeyEvent.CTRL_DOWN_MASK) {
+                if(historyPos > 0) {
+                  String line = history.elementAt(historyPos-1);
+                  historyPos--;
+                  rCmdIn.setText(line);
+                }
+              }
+            else if(ev.getKeyCode() == KeyEvent.VK_DOWN + KeyEvent.CTRL_DOWN_MASK) {
+                if(historyPos < history.size()-1) {
+                  String line = (String)history.elementAt(historyPos+1);
+                  historyPos++;
+                  rCmdIn.setText(line);
+                }
+              }
+            else
+        	// No Up- or Down-key pressed.
+            {
+            String line = rCmdIn.getText();
+            if (    (ev.getModifiers() == KeyEvent.CTRL_MASK)
+        	 && ( ev.getKeyCode() == KeyEvent.VK_ENTER)   ) {
+
+        	// If something worth saving was typed...
+        	if(!("".equals(line) ||
+                     "\n".equals(line) ||
+                     "\n\r".equals(line) ||
+                     "\r\n".equals(line))) {
+                    history.add( line.trim() );
+                }
+
+                if("clear".equals(line)) {
+                    // Wipes the R-Output window.
+                    rOut.setText("");
+                }
+                else
+                {
+                    showLastLine();
+                    readInput = true;
+                }
+            }
+            }
+        }
+    };
+
+    private String throwInCmd;
+
+
+    /**
+     * Scrolls down the ScrollWindow of the ROutput.
+     */
+    public void showLastLine() {
+        SwingUtilities.invokeLater(new Runnable() {
+          public void run() {
+            if (maxLines > 0) {
+              int linesToRemove = rOut.getLineCount() - maxLines;
+              while (linesToRemove < 0 ){
+        	 rOut.setText( "\n" + rOut.getText());
+        	 linesToRemove++;
+              }
+              if (linesToRemove > 0) {
+        	    int index = 0;
+                    for (int i=0; i<linesToRemove; i++) {
+                      index = rOut.getText().indexOf('\n', index) + 1;
+                    }
+                    rOut.setText(rOut.getText().substring(index));
+              } else {
+
+              }
+            }
+          }
+        });
+      }
+
+    class ReaderThread extends Thread {
+        PipedInputStream pi;
+        ReaderThread(PipedInputStream pi) {
+            this.pi = pi;
+        }
+
+        public void run() {
+            final byte[] buf = new byte[1024];
+            try {
+               while (true) {
+                    final int len = pi.read(buf);
+                    if (len == -1) {
+                        break;
+                    }
+                    SwingUtilities.invokeLater(new Runnable() {
+                        public void run() {
+                            rOut.append(new String(buf, 0, len));
+
+                            // Make sure the last line is always visible
+                            rOut.setCaretPosition(rOut.getDocument().getLength());
+
+                            // Keep the text area down to a certain character size
+                            int idealSize = 1000;
+                            int maxExcess = 500;
+                            int excess = rOut.getDocument().getLength() - idealSize;
+                            if (excess >= maxExcess) {
+                                rOut.replaceRange("", 0, excess);
+                            }
+                        }
+                    });
+                }
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * called by the R-Engine, when it want's to print to STDOUT
+     */
+//    @Override
+    public void rWriteConsole(Rengine re, String text) {
+    	rOut.append(text);
+    	showLastLine();
+    }
+
+//    @Override
+    public void rBusy(Rengine re, int which) {
+    	if (which == 1) {
+    		System.out.println("busy");
+    		rCmdIn.setEnabled(false);
+    		setCursor(hourglassCursor);
+    	} else {
+    		rCmdIn.setEnabled(true);
+    		System.out.println("not busy");
+    		setCursor(defaultCursor);
+    		rCmdIn.requestFocus();
+    	}
+    }
+
+//    @Override
+    public String rReadConsole(Rengine re, String prompt, int addToHistory) {
+    	rCmdIn.setEnabled(true);
+    	while ((!readInput) && (!readInput2) ) {
+    		try {
+    			Thread.sleep(100);
+    		} catch (InterruptedException e) {
+    			e.printStackTrace();
+    		}
+    	}
+
+    	String  text = "";
+    	// Input comes from the GNU-R Plugin GUI
+    	if (readInput) {
+    	    readInput=false;
+    	    text = rCmdIn.getText()+"\n";
+    	    rCmdIn.setText("");
+    	}
+    	else if (readInput2) {
+    	    // Sent to R-Console by cmd : public void sendToConsole(String s)
+    	    readInput2 = false;
+    	    text = throwInCmd+"\n";
+    	    throwInCmd = "";
+    	}
+
+    	System.out.print("Sending as Console Input = "+text);
+    	return text;
+    }
+
+    /**
+     * Easy way to send a command to R
+     * The result is shown on the R Console
+     * @param s
+     */
+    public void sendToConsole(String s) {
+	throwInCmd = s;
+	readInput2 = true;
+    }
+
+//    @Override
+    public void rShowMessage(Rengine re, String message) {
+    	rOut.append("rShowMessage \"" + message + "\"");
+    }
+
+//    @Override
+    public String rChooseFile(Rengine re, int newFile) {
+    	FileDialog fd = new FileDialog(new Frame(),
+    			(newFile == 0) ? "Select a file" : "Select a new file",
+    			(newFile == 0) ? FileDialog.LOAD : FileDialog.SAVE);
+    	fd.setVisible(true);
+    	String res = null;
+    	if (fd.getDirectory() != null)
+    		res = fd.getDirectory();
+    	if (fd.getFile() != null)
+    		res = (res == null) ? fd.getFile() : (res + fd.getFile());
+    	return res;
+    }
+
+//    @Override
+    public void rFlushConsole(Rengine re) {
+    }
+
+//    @Override
+    public void rLoadHistory(Rengine re, String filename) {
+    }
+
+    public void rSaveHistory(Rengine re, String filename) {
+    	System.out.println("Maybe I want to export the stuff here!?");
+    }
+
+    /**
+     * Returns the static R-Engine
+     */
+    public Rengine getREngine() {
+        return re;
+    }
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/RVar.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/RVar.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/RVar.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,103 @@
+package de.skrueger.xulu.plugin.gnur;
+
+import org.rosuda.JRI.REXP;
+import org.rosuda.JRI.Rengine;
+
+import schmitzm.data.property.ScalarProperty;
+import schmitzm.data.property.ValueProperty;
+
+/**
+ * Link between datapool and R-Engine 
+ * @author stefan
+ */
+
+public class RVar {
+	/**
+	 * Soll diese Datenstruktur in die R Engine importiert und-/oder aus der 
+	 * Engine heraus exportiert werden?  
+	 */
+	private Boolean exp = true;
+	private Boolean imp = true;
+
+	private ValueProperty prop = null;
+	private String RVarName = null;
+
+	public RVar ( ValueProperty prop) throws PropertytypeNotConvertableToRVar {
+		if (prop instanceof ScalarProperty) {
+			this.prop = prop;
+			RVarName = prop.getName().replaceAll(" ", "_");
+		} else {
+			throw new PropertytypeNotConvertableToRVar( prop );
+		}
+	}
+	
+	public Boolean isExport() {
+		return exp;
+	}
+	
+	public Boolean isImport() {
+		return imp;
+	}
+
+	
+	/**
+	 * @return the name of the variabl ein the R environment
+	 */
+	public String getRName() {
+		return RVarName;
+	}
+	
+
+	/**
+	 * Set the name that will reference the R-variable inside the RVar.
+	 * TODO: Check for doubles, name validity
+	 * @param rname
+	 */
+	public void setRName(String rname) {
+		RVarName = rname.replace(" ", "_");
+	}
+
+	/**
+	 * @return the name of the object in the datapool
+	 */
+	public String getName() {
+		return prop.getName();
+	}
+
+	public boolean toR(Rengine re) {
+		REXP x;
+		
+		if (!isImport()) return false;
+		
+		if (prop instanceof ScalarProperty) {
+			Integer val = prop.getOneTimeReadAccess().getValueAsInt();
+			String expr = getRName() + " <- " + val;
+			re.eval(expr);
+			return true;
+		} else {
+			System.out.println("Can't import this var!"+getName());
+			return false;
+		}
+	}
+	
+
+	public boolean fromR(Rengine re) {
+		REXP x;
+		
+		if (!isExport()) return false;
+		
+		if (prop instanceof ScalarProperty) {
+			String expr = getRName();
+			REXP eval = re.eval(expr);
+			System.out.println(eval);
+			Double val = eval.asDouble();
+			prop.getOneTimeWriteAccess().setValue(val.intValue());
+			System.out.println(getName()+" now has value "+val.intValue());
+			return true;
+		} else {
+			System.out.println("Can't export this var!"+getName());
+			return false;
+		}
+	}
+	
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/RVarAdapter.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/RVarAdapter.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/RVarAdapter.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,88 @@
+package de.skrueger.xulu.plugin.gnur;
+
+import org.rosuda.JRI.Rengine;
+
+import schmitzm.data.property.MatrixProperty;
+import schmitzm.data.property.Property;
+import schmitzm.data.property.ScalarProperty;
+
+/**
+ * Link between datapool and R-Engine
+ * @author stefan
+ */
+
+public abstract class RVarAdapter {
+	/**
+	 * Soll diese Datenstruktur in die R Engine importiert und-/oder aus der
+	 * Engine heraus exportiert werden?
+	 */
+	private Boolean exp = true;
+	private Boolean imp = true;
+
+	protected Property prop = null;
+	private String RVarName = null;
+
+	/**
+	 *
+	 * @param obj
+	 * @param testOnly	if true, than only check if Property is compatible-.. otherwise throw PropertytypeNotConvertableToRVarException
+	 * @throws PropertytypeNotConvertableToRVar
+	 */
+	static public RVarAdapter createFrom ( Property obj, boolean testOnly) throws PropertytypeNotConvertableToRVar {
+		if (obj instanceof ScalarProperty) {
+		    System.out.print("Scalprop");
+		    if (!testOnly) return new RVarScalar( (ScalarProperty)obj );
+		} else if (obj instanceof MatrixProperty) {
+		    System.out.print("MatrixProp");
+		    if (!testOnly) return new RVarMatrix( (MatrixProperty)obj );
+		} else {
+			throw new PropertytypeNotConvertableToRVar( obj );
+		}
+		return null;
+	}
+
+	public Boolean isExport() {
+		return exp;
+	}
+
+	public Boolean isImport() {
+		return imp;
+	}
+
+
+	/**
+	 * @return the name of the variabl ein the R environment
+	 */
+	public String getRName() {
+		return RVarName;
+	}
+
+
+	/**
+	 * Set the name that will reference the R-variable inside the RVar.
+	 * TODO: Check for doubles, name validity
+	 * @param rname
+	 */
+	public void setRName(String rname) {
+		RVarName = rname.replace(" ", "_");
+	}
+
+	/**
+	 * @return the name of the object in the datapool
+	 */
+	public String getName() {
+		return prop.getName();
+	}
+
+	public abstract void toR(Rengine re);
+
+	public abstract void fromR(Rengine re);
+
+	protected RVarAdapter(Property prop) {
+	    super();
+	    this.prop = prop;
+
+	    // Change name of var so that its R-sytax-proof.
+	    RVarName = prop.getName().replaceAll(" ", "_");
+	}
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/RVarMatrix.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/RVarMatrix.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/RVarMatrix.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,139 @@
+package de.skrueger.xulu.plugin.gnur;
+
+import org.rosuda.JRI.REXP;
+import org.rosuda.JRI.Rengine;
+
+import schmitzm.data.property.MatrixProperty;
+
+public class RVarMatrix extends RVarAdapter {
+    
+    MatrixProperty prop = (MatrixProperty) super.prop;
+    private Class cType;		// Class/type of the MatrixProperties' values
+    int[] size;				// Getting the size of the matrix in X and Y direction
+    
+    protected RVarMatrix(MatrixProperty prop) {
+	super(prop);
+	cType = prop.getType();
+	size =  prop.getSize();;
+	System.out.println("MatrixProp created...");
+    }
+
+    @Override
+    /**
+     * Export a matrix from the R environment into a MatrixProperty
+     * @author Stefan A. Krüger
+     */    
+    public void fromR(Rengine re) {
+	if (!isImport()) return;
+	
+	// So far we can only handle two-dimensional matrixes.
+	int dims = prop.getDimension(); 
+	if (dims != 2) {
+	    throw new PropertytypeNotConvertableToRVar(prop,"Sorry. So far the GNU-R plugin can only handle two-dimensional matrixes.");
+	}
+
+	
+    	REXP ex = re.eval( getRName() );
+    	if ((cType == Integer.class) || (cType == Short.class) || (cType == Float.class) ) {
+    	    double ee[][] = ex.asMatrix();
+    	    if (ee==null) 
+    		throw new PropertytypeNotConvertableToRVar(prop, cType.toString() + " - error was not expected."); 
+    	    	System.out.println("len von ee[] = "+ee.length);
+    		System.out.println("ee[1] = "+ee[1]);
+    		
+    	    	// Filling the PropertyMatrix with the double-matrix from R
+    	    	for (int x = 0; x < size[0]; x++)  {
+    	    	    for (int y = 0; y < size[1]; y++)  {
+    	    		Double d = Double.valueOf(ee[x][y]);
+    	    		if ( cType == Float.class ) prop.getOneTimeWriteAccess().setValue( d.floatValue(), x, y );
+    	    		if ( cType == Double.class ) prop.getOneTimeWriteAccess().setValue( d, x, y );
+    	    		if ( cType == Integer.class ) prop.getOneTimeWriteAccess().setValue( Integer.valueOf( d.intValue()), x, y );
+    	    		if ( cType == Short.class ) prop.getOneTimeWriteAccess().setValue( Integer.valueOf( d.shortValue()), x, y );
+    	    	    }
+    	    	}
+    	    	return;
+    	} else
+        if (cType == String.class) {
+            throw new PropertytypeNotConvertableToRVar(prop, cType.toString() + " - cant import that type from R. Ask the programmer kindly to implement it.");
+        } else {
+            throw new PropertytypeNotConvertableToRVar(prop, cType.toString() + " - cant import that type from R. Sorry.");
+        }
+    	
+//    	// Filling the PropertyMatrix fomr a 1-dim object-array
+//    	for (int x = 0; x < size[0]; x++)  {
+//    	    for (int y = 0; y < size[1]; y++)  {
+//    		// System.out.println( prop.getOneTimeReadAccess().getValue( x,y ) );
+//    		int idx = y + (x*size[1]);
+//    		prop.getOneTimeWriteAccess().setValue( longarray[idx], x, y );
+//    	    }
+//    	}
+    	
+    }
+
+
+    
+    
+    
+    @Override
+    /**
+     * Import a MatrixProperty into the R environment
+     */
+    public void toR(Rengine re) {
+	if (!isExport()) return;
+	
+	// So far we can only handle two-dimensional matrixes.
+	int dims = prop.getDimension(); 
+	if (dims != 2) {
+	    throw new PropertytypeNotConvertableToRVar(prop,"Sorry. So far the GNU-R plugin can only handle two-dimensional matrixes.");
+	}
+	
+    	// Filling a 1-dim object-array
+    	Object longarray[] = new Object [ size[0] * size[1] ];
+    	for (int x = 0; x < size[0]; x++)  {
+    	    for (int y = 0; y < size[1]; y++)  {
+    		// System.out.println( prop.getOneTimeReadAccess().getValue( x,y ) );
+    		int idx = y + (x*size[1]);
+    		longarray[idx] = prop.getOneTimeReadAccess().getValueAsInt( x,y );
+    	    }
+    	}
+    	// System.out.println ("Length of the longarray = " + longarray.length );
+    	
+    	// LongArray referenze in R 
+        long xpLA = -1;
+        
+    	// Check which types we can import into R:
+        
+    	if ((cType == Integer.class) || (cType == Short.class)) {
+    	    // Converting object-array to int[]
+    	    int[] aa = new int[longarray.length];
+    	    for (int i = 0; i<longarray.length-1; i++) {
+    		aa[i] = (Integer) longarray[i];
+    	    }
+    	    // importing to R
+    	    xpLA = re.rniPutIntArray(  aa );
+    	} else 
+        if (cType == Float.class) {
+    	    double[] aa = new double[longarray.length];
+    	    for (int i = 0; i<longarray.length-1; i++) {
+    		aa[i] = (Double) longarray[i];
+    	    }
+    	    // importing to R
+    	    xpLA = re.rniPutDoubleArray( aa );
+        } else
+        if (cType == String.class) {
+            String[] aa = new String[longarray.length];
+    	    for (int i = 0; i<longarray.length-1; i++) {
+    		aa[i] = (String) longarray[i];
+    	    }
+    	    // importing to R
+	    xpLA = re.rniPutStringArray( aa );
+        } else {
+            throw new PropertytypeNotConvertableToRVar(prop, cType.toString() + " - cant convert that type to R. Sorry.");
+        }
+    		
+
+    	// Convert xpLA to a R-matrix
+    	re.rniAssign( getRName(), xpLA, 0);
+    	re.eval( getRName()+"<-matrix ( "+getRName()+","+size[0]+" ) ");
+    }
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/RVarScalar.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/RVarScalar.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/RVarScalar.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,41 @@
+package de.skrueger.xulu.plugin.gnur;
+
+import org.rosuda.JRI.REXP;
+import org.rosuda.JRI.Rengine;
+
+import schmitzm.data.property.ScalarProperty;
+
+public class RVarScalar extends RVarAdapter{
+    
+    ScalarProperty prop = (ScalarProperty) super.prop;
+
+    public RVarScalar( ScalarProperty prop) {
+	super(prop );
+	System.out.println("Scalarprop created...\n");
+    }
+    
+    @Override
+    public void toR(Rengine re) {
+    	REXP x;
+    	if (!isImport()) return;
+    	
+    	Integer val = prop.getOneTimeReadAccess().getValueAsInt();
+    	String expr = getRName() + " <- " + val;
+    	re.eval(expr);
+    }
+
+    @Override
+    public void fromR(Rengine re) {
+	if (!isExport()) return;
+
+	REXP x;
+        
+        String expr = getRName();
+        REXP eval = re.eval(expr);
+        System.out.println(eval);
+        Double val = eval.asDouble();
+        prop.getOneTimeWriteAccess().setValue(val.intValue());
+        System.out.println(getRName()+" now has value "+val.intValue());
+    }
+    
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/RVarSingleGrid.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/RVarSingleGrid.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/RVarSingleGrid.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,36 @@
+package de.skrueger.xulu.plugin.gnur;
+
+import org.rosuda.JRI.Rengine;
+
+import schmitzm.data.property.Property;
+
+import edu.bonn.xulu.plugin.data.grid.SingleGrid;
+
+public class RVarSingleGrid extends RVarAdapter {
+    
+//    SingleGrid grid = (SingleGrid) super.prop;
+//
+//    protected RVarSingleGrid(SingleGrid grid) {
+////	super(grid);
+//    }
+
+    protected RVarSingleGrid(Property prop) {
+	super(prop);
+	// TODO Auto-generated constructor stub
+    }
+
+    @Override
+    public void fromR(Rengine re) {
+
+    }
+
+    @Override
+    /**
+     * 
+     */
+    public void toR(Rengine re) {
+	
+
+    }
+
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/RVarsTable.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/RVarsTable.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/RVarsTable.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,12 @@
+package de.skrueger.xulu.plugin.gnur;
+
+import schmitzm.swing.table.MutableTable;
+import schmitzm.swing.table.MutableTableModel;
+
+public class RVarsTable extends MutableTable {
+
+	public RVarsTable(MutableTableModel model) {
+		super(model);
+	}
+
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/RVarsTableModel.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/RVarsTableModel.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/RVarsTableModel.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,153 @@
+package de.skrueger.xulu.plugin.gnur;
+
+import java.util.Vector;
+
+import schmitzm.data.event.ObjectEvent;
+import schmitzm.data.event.ObjectListener;
+import schmitzm.data.property.ScalarProperty;
+import schmitzm.geotools.gui.GeotoolsGUIUtil;
+import schmitzm.swing.SelectionInputOption;
+import schmitzm.swing.table.AbstractMutableTableModel;
+import schmitzm.swing.table.MutableTableModel;
+import edu.bonn.xulu.XuluModellingPlatform;
+import edu.bonn.xulu.appl.DataPool;
+
+///////////////////////////////////////////////////////////////////
+//////////////   TableModel for the DnD-Tabel der R Variables  //////////////
+///////////////////////////////////////////////////////////////////
+
+class RVarsTableModel extends AbstractMutableTableModel {
+  /** Speichert die in der Tabelle gespeicherten Raster */
+	protected Vector<RVarAdapter> objects = new Vector<RVarAdapter>();
+  
+  /** Speichert die Instanz der Xulu-Applikation. */
+  protected XuluModellingPlatform appl = null;
+  /** Eingabe-Option fuer ein einzelnes Objekt. */
+  protected SelectionInputOption.Combo objectInputOption = null;
+
+  /** Flag, ob sich der Inhalt des Datenpools geaendert hat und die Arrays
+   *  {@link #fitObjects} und {@link #fitObjectNames} aktualisiert werden
+   *  muessen */
+  protected boolean  dataPoolChanged = true;
+  /** Passende Objekte im Datenpool */
+  protected Object[] fitObjects = null;
+  /** Bezeichnungen der passenden Objekte im Datenpool */
+  protected String[] fitObjectNames = null;
+
+  /**
+   * Erzeugt ein neues Tabellen-Modell.
+   * @param appl Instanz der Xulu-Applikation
+   * @param rowIndexPrefix Praefix, das den Zeilen-Indizes vorangestellt wird
+   */
+  public RVarsTableModel(XuluModellingPlatform appl) {
+    super();
+    this.appl = appl;
+    objectInputOption = new SelectionInputOption.Combo(getColumnName(1),true);
+    refreshInputOption();
+    // Listener auf den Datenpool setzen, damit das Auswahlfeld aktualisiert
+    // werden kann (wenn notwendig)
+    appl.getDataPool().addObjectListener( new ObjectListener() {
+      public void performObjectEvent(ObjectEvent e) {
+        if ( e instanceof DataPool.DataPoolChangeEvent ) {
+          dataPoolChanged = true;
+        }
+      }
+    });
+  }
+
+  /**
+   * Liefert die Spaltennamen der Tabelle.
+   */
+  @Override
+  public String[] createColumnNames() {
+    return new String[] {null,"Datapool-Object","Names in R","Import","Export"};
+  }
+
+  /**
+   * Ruft {@link #determineFitObjectsAndNames()}, wenn das {@link #dataPoolChanged}-Flag
+   * auf {@code true} steht und setzt das Flag zurueck.
+   */
+  protected void refreshFitObjects() {
+    if ( dataPoolChanged )
+      determineFitObjectsAndNames();
+    dataPoolChanged = false;
+  }
+
+  /**
+   * Aktualisiert das Dialog-Auswahlfeld, in dam alle passenden Objekte
+   * aus dem Datenpool vorgeblendet werden.
+   */
+  protected void refreshInputOption() {
+    refreshFitObjects();
+    objectInputOption.setSelectionObjects(fitObjects,fitObjectNames);
+  }
+
+  /**
+   * Wird aufgerufen, wenn sich der Inhalt des Xulu-Datenpools aendert.
+   * Muss die Arrays {@link #fitObjects} und {@link #fitObjectNames} mit
+   * allen passenden Objekten des Datenpools und deren Bezeichnungen
+   * befuellen.
+   */
+  protected void determineFitObjectsAndNames() {
+}
+
+
+  /**
+   * Loescht eine Tabellenzeile.
+   * @param row Zeilenindex (beginnend bei 0)
+   */
+  public void performRemoveRow(int row) {
+    objects.remove(row);
+  }
+
+  /**
+   * Macht nichts, da in der Tabelle keine Daten veraendert werden koennen.
+   * @param row Zeilenindex (beginnend bei 0)
+   * @param col Spaltenindex (beginnend bei 0)
+   */
+  public void performChangeData(int row, int col) {
+  }
+
+  /**
+   * Liefert die Anzahl an Zeilen.
+   */
+  public int getRowCount() {
+    return objects.size();
+  }
+
+  /**
+   * Liefert den Inhalt einer Tabellenzelle.
+   * @param row Zeilenindex (beginnend bei 0)
+   * @param col Spaltenindex (beginnend bei 0)
+   */
+  public Object getValueAt(int row, int col) {
+    switch ( col ) {
+      case 0: return row;
+      case 1: return objects.elementAt(row).getRName(); // TODO 
+      case 2: return objects.elementAt(row).getRName();
+      case 3: return objects.elementAt(row).isImport();
+      case 4: return objects.elementAt(row).isExport();
+    }
+    return null;
+  }
+
+
+public void performAddRow() {
+	System.out.println("?!");
+}
+
+
+public void addRVariable(RVarAdapter rv) {
+	objects.add(rv);
+	refreshFitObjects();
+}
+
+/**
+ * Returns the 
+ * @return
+ */
+public Vector<RVarAdapter> getRVars() {
+	return objects;
+}
+
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/funGeneric.r
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/funGeneric.r	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/funGeneric.r	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,39 @@
+### generic functions
+
+### ============================================================================
+### set start working directory automatic
+locPath <- function (dest=c('data','SatData', 'model', 'model.data', 'prog')) {
+  dest <- match.arg(dest)
+  switch(dest, 
+         data = directory <- c("i:/Benin","M:/4_Research/Benin_Daten"), 
+         SatData = directory <- c("F:","M:/4_Research/Benin_Daten"),
+         model = directory <- c("e:/Xulu-100m/statistics","M:/4_Research/Xulu"),
+         model.data = directory <- c("e:/database_modelling","M:/4_Research/LUCC_Modelling/database_modelling"), 
+         prog = directory <- c("Y:/6_Programming/R","D:/6_Programming/R") )
+
+  # look if directory at home is available and set path apropriately
+  if (!is.na(file.info(directory[2])$isdir)){locdrive = directory[2]} else {locdrive <- directory[1]}
+  locdrive <- paste(locdrive,"/",sep="")
+  return(locdrive)
+}
+
+### path to base path for R script files, e.g. this generic function file
+locPathP <- function () {
+  DirUni <- "Y:/6_Programming"
+  DirHome <- "D:/6_Programming"
+  if (!is.na(file.info(DirHome)$isdir)){locdrive = DirHome} else {locdrive <- DirUni}
+  locdrive <- paste(locdrive,"/",sep="")
+  return(locdrive)
+}
+
+### ============================================================================
+### copy content of graphic device to a postscript file
+### file is located in working directory
+### works best if ps is given the width and height of the current device
+
+### the option  onefile=F is essential to have the bounding box -> LATEX!
+
+psFile <- function(file="Rplot.eps", dim, ...) {
+        dev.copy2eps(file=file, width=dim[1], height=dim[2],
+        horizontal = FALSE, onefile=F, paper = "special", ...)
+}

Added: trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/functions.R
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/functions.R	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/functions.R	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,240 @@
+#########################################################################
+################# function definitions  #################################
+#########################################################################
+
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+###                        File operations                                 
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 
+# --------------------------------------------------------------
+### sort filelist
+### args:
+### 1. List of input files
+### 2. seperator string. where to split the numbers from mai file name
+
+sort.filelist <- function (FileList, s="_") {
+  f=strsplit(FileList, s)
+  v=numeric()
+  # extract number element out of list, which is simulation year
+  for (i in 1:length(f)){v=c(v,f[[i]][2])}
+  v=as.numeric(v)
+  # sort years with index values
+  vs=sort(v, index.return=T)
+  # apply sortet year list to Filelist
+  FileList.sort = FileList[vs[[2]]]
+  return(FileList.sort)
+}
+
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+###                        Read ASCII GRID data                            
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### ---------------------------------------------------------------------
+### read several ascii grid into list                                   
+### ---------------------------------------------------------------------
+
+read.grd <- function (FileList, n=length(FileList), path="") {
+  #test for right / in path string
+  if (path!="" & length(grep("/$",path))>0) path=path else {path=paste(path,"/",sep="")} 
+  
+  grid.lst = list()
+  for (i in 1:n) {
+    grid.lst[[i]] <- read.asciigrid(paste(path,FileList[i],sep=""), as.image=T )
+    
+  }
+  names(grid.lst) <- FileList
+  return(grid.lst)
+}
+
+
+### ---------------------------------------------------------------------
+### read several ascii grid into one dataframe ONLY DATA!                 
+### ---------------------------------------------------------------------
+
+read.asciigrid.df <- function(GridList, nPixels) {
+  for (i in 1:length(GridList)) {
+    InData = read.asciigrid(GridList[i], as.image=T )
+    InData = as.numeric(InData$z)
+    if (length(na.omit(InData)) != nPixels ) {
+      print("amount of pixel values doesn't match!!!!!")
+      print(GridList[i])
+      }
+    if (i==1) {
+      ascii.df = as.data.frame(InData)
+      }
+    else {  
+    ascii.df = cbind(ascii.df,InData) 
+      }
+    }
+}
+
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+###                        Sampling functions                            
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ---------------------------------------------------------------------
+# balanced sampling of lc pixels
+# ---------------------------------------------------------------------
+
+
+balanced.sampling <- function(dataframe, lc.type, max_samp) {
+
+  dataframe$lu <- ifelse (dataframe[[1]] == lc.type, 1, 0)
+
+  dataframe.S1 = subset(dataframe, lu==1)
+  
+  if (sum(dataframe.S1$lu, na.rm = T) > 2000) {
+    RandomList = runif(max_samp,min=1, max=length(dataframe.S1$lu))
+    dataframe.S1 = dataframe.S1[RandomList,]
+  }
+  
+  # set maximum sampling amount to number of cases if <2000
+  if (sum(dataframe$lu, na.rm = T) < 2000) {
+    print (c("LU type", lc.type, "has", sum(dataframe$lu, na.rm = T), "occurances, do balanced sampling"))
+    max_samp = sum(dataframe$lu, na.rm = T)
+    }
+    
+  dataframe.S0 = subset(dataframe, lu==0)
+   RandomList = runif(max_samp,min=1, max=length(dataframe.S0$lu))
+  dataframe.S0 = dataframe.S0[RandomList,]
+
+  dataframe.S = rbind(dataframe.S1,dataframe.S0)
+  colnames(dataframe.S) <- colnames(dataframe)
+  return(dataframe.S)
+  }
+
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+###                 write results from logit model to file                 
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ---------------------------------------------------------------------
+# write AUV values to file
+# ---------------------------------------------------------------------
+
+WriteAUC <- function (fitstep, BeninData, i) {
+  pred = prediction(fitted(fitstep),as.vector(BeninData$lu))
+  # ---------------------------------------------------------------------
+  # compute AUC
+  # ---------------------------------------------------------------------
+  auc = performance(pred, measure="auc")
+  # auc is object of class performance, data stored in slots
+  # to access slots (and datas) use @ (in Newsletter 4/1 is said
+  # don't use it but I don't know an other way
+  aucValue = auc at y.values[[1]]
+  write (paste("AUC for LC no",i, ":", aucValue, sep=" "), outputRegEval, append=TRUE)
+}
+
+
+# ---------------------------------------------------------------------
+# write betas in a CLUE-S compatible file
+# ---------------------------------------------------------------------
+
+WriteCoefClue <- function(fitstep, outRegressionFile, i, description="new run") {
+  coef <- summary(fitstep)$coefficients
+  betas <- as.vector(coef[,1])
+  # insert number of dforces
+  betas <- append(betas, length(betas)-1 , after=1)
+  # insert number of landcover class
+  betas <- append(betas, i, after=0)
+  # insert second collumn for dforce id
+  betas <- cbind(betas, "") [, c(1,2)]
+  # match dforce id of coef list with value list above
+  res_dforces_names <- as.data.frame(dimnames(coef)[[1]])
+  res_dforces <- merge(dforce, res_dforces_names, by=1, sort=FALSE)
+  # insert dforce id into second collumn
+  z <- length(dimnames(coef)[[1]]) -1
+  for (j in 1:z) {
+  	betas[j+3,2] <- res_dforces$dforce_number[j]
+  }
+  if (i == 0) {
+    write("\n----------------------------------",outRegressionFile,append=TRUE) 
+    write(description,outRegressionFile,append=TRUE) 
+  }
+  write(t(betas), outRegressionFile, ncolumns=2, append=TRUE)
+}
+
+
+# ---------------------------------------------------------------------
+# write betas in a XULU compatible file
+# ---------------------------------------------------------------------
+
+WriteCoefXulu <- function(fitstep, outeval, i , description="new run") {
+  coef <- summary(fitstep)$coefficients
+  betas <- as.vector(coef[,1])
+
+  coef.val <- numeric(length=length(dforce_number)+1 )
+
+  # assign intercept
+  coef.val[1] = betas[1]
+  # assign coef
+  # get position (index) of df name
+  df.pos = match(dimnames(coef)[[1]][-1], dforce_name)
+  # assign the coef at appropriate postition in vector
+  coef.val[df.pos+1] = betas[-1]
+  # insert semicolon
+  coef.val = paste(coef.val, ";", sep="")
+  if (i==0) {
+     write(paste("--------------- (", description, ")", sep=""),outeval,append=TRUE) 
+     #write(description,outeval,append=TRUE) 
+  }
+  write(paste("\n ----- LC ",i, " ------", sep=""),outeval,append=TRUE) 
+  write(coef.val, outeval, ncolumns=length(dforce_number)+1, append=TRUE)
+}
+
+
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+###                    Plot results from logit model                       
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+# ---------------------------------------------------------------------
+# plot fitted values from logistic regression model
+# ---------------------------------------------------------------------
+
+plot.fitted <- function(FileList, fitted.data, dataset, numrows=580, numcols=539) {
+
+  InData = read.asciigrid(FileList[1], as.image=T )
+  # convert data matrix to numeric
+  v=as.numeric(InData$z)
+  ## get index of data values
+  x=which(v>=0)
+  # calculate probabilities for whole data set (if subset used)
+  prd=predict(fitted.data, newdata=dataset, type="response")
+  prd=na.omit(prd)
+  ## assign new values to x position
+  v[x]=prd
+  # transform it back to matrix
+  v=matrix(v,  nrow=numrows, ncol=numcols)
+  # get matrix back to image
+  predict.grid = InData
+  predict.grid$z = v
+  image(predict.grid, col=terrain.colors(24))
+  legend.entries = seq(0,1, by=1/10,digits=1)
+  legend("bottomright",legend=legend.entries, fill=terrain.colors(11))
+
+}
+
+### color ramp
+### -> see colorRampPalette function and RColorBrewer
+
+#image(grid.prob[[2]], col=rainbow(24, start=0, end=2/6))
+#
+#colorRamp.redblue <- function (n) 
+#{
+#    x <- ramp(seq(0, 1, length = n))
+#    rgb(x[, 1], x[, 2], x[, 3], max = 255)
+#}
+#
+#
\ No newline at end of file

Added: trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/logit_regression_all_v1.3.R
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/logit_regression_all_v1.3.R	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/Rcode/logit_regression_all_v1.3.R	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,266 @@
+########################################################################
+########################################################################
+# Skript to calculate logit regression for landcover analysis
+# make random subset of input data to minimize computation time 
+# input: datafile prepared with CLUS-S file conversion tool
+# output: ascii file ready to use as alloc.1 in CLUE-S
+# adapt the following parameters:
+# - path to files and filenames
+# - look if colnames are all acoorect!
+# - Subset of data to use (exclude irrelevant predictors and cover classes)
+# CHANGES:
+#
+# Version 1.3:
+# - mehr automatismen, um daten anderer Konfiguration zu verarbeiten
+#   z.B. Daten in 100m und für Xulu -> LN muss nicht bei 0 anfangen
+# Version 1.2:
+# - balanced sampling also for small classes: 
+#   equal samples of 0 and 1 (tip from Peter V.)
+#
+# Version 1.1:
+# - extract certain methods to functions (write different values)
+# 
+# Version 1.0:
+# - read data automaticaly from directory and assign colnames from filenames
+# 
+
+########################################################################
+########################################################################
+ 
+
+# load libraries
+library(MASS)
+library(ROCR)
+library(sp)
+
+#######################################################################
+# read functions
+#######################################################################
+source(paste(locPath(dest="prog"),"CLUE-S/functions.R", sep=""))
+
+# ---------------------------------------------------------------------
+# define path to data
+# ---------------------------------------------------------------------                             
+setwd(locPath(dest="model"))
+
+outputRegressionFile = "R_coefficients_lc.txt" 
+outputRegXulu = "R_coefficients_xulu.txt"
+outputRegEval = "R_regression_evaluation_all.txt"
+
+# ---------------------------------------------------------------------
+# import landcover data and driving forces into R
+# import data are output from CLUE-S conversion tool
+# ---------------------------------------------------------------------
+
+# read directly from ASCII GRID
+# take care the NO MINUS signs are pressent in file names!!
+# replace with underscores
+extension <- ".txt"
+FileList = list.files(pattern = paste("\\",extension,"$",sep=""))
+#FileList = list.files(pattern = "\\.txt$")
+FileList = FileList[-which(FileList == "ac_orig_all.asc")]
+
+# read ascii data into dataframe and test if all have same pixel amount
+BeninData = read.asciigrid.df(FileList, 1434056 )  #for 250m resolution: 229863
+
+# write colnames (filename) to dataframe
+# delete file name extension
+FileListN = gsub(extension,"",FileList)
+# replace undescore in variable name by .
+FileListN = gsub("_", ".",FileListN)
+colnames(BeninData)=FileListN
+
+# convert to factor levels
+BeninData$soil = factor(BeninData$soil)
+BeninData$tpi = factor(BeninData$tpi)
+
+# resort df that lc data are first collumn
+#BeninData = BeninData[c(8,1:7,9:length(BeninData))]
+BeninData = data.frame(BeninData$lc2000, subset(BeninData, select= -lc2000))
+#colnames(BeninData[1]) <- "lc.2000"        # funktiniert nicht!
+## muss names(BeninData)[1]="lc.2000" sein! # colname ist Benindata.lc.2000
+                                            # alle folgenden stellen ändern
+                                            # in glm etc.
+  
+  
+
+# ---------------------------------------------------------------------
+# PRE-FORMATING OF DATA
+# ---------------------------------------------------------------------
+# create list of colnames
+# ---------------------------------------------------------------------
+
+# get number of fields in dataset
+numLUClasses <- max(BeninData[[1]], na.rm = T)
+# 
+LuClasses <- seq(min(BeninData[[1]], na.rm = T) , max(BeninData[[1]], na.rm = T))
+
+# get number of fields in dataset
+numData = length(BeninData)
+
+# create dataframe with driving force names and id numbers
+# due to factor levels it is not possible to take the clomanes 
+# of the dataframe.
+
+
+dforce_name = vector()
+for (i in 2:length(BeninData)) {
+  if (is.factor(BeninData[[i]])){
+    #print ("factor")
+    factor.range <- range(as.numeric(levels(BeninData[[5]])))
+    for (j in factor.range[1]+1 : factor.range[2]){ 
+      dforce_name = append(dforce_name, paste(colnames(BeninData[i]),j, sep=""))
+    }
+  }
+  else {
+  dforce_name = append(dforce_name, colnames(BeninData[i]))
+  }
+}
+dforce_number <- seq(0,length(dforce_name)-1)
+dforce <- data.frame(dforce_name, dforce_number)
+
+
+
+
+########################################################################
+# Logistic regression with random subset of data
+# SELECT BETWEEN THE FOLLLOWING METHODS TO SUBSET DATA11
+########################################################################
+
+# ---------------------------------------------------------------------
+# fit binary logistic model to lc data
+# loop that goes through all landcover types and calculate
+# regression parameters with subset of data and stepwise
+# regression
+# 
+# leave out first list in data_benin as this is AgricChange
+# ---------------------------------------------------------------------
+
+
+# start loop with all LC classes
+i=1
+for (i in LuClasses) {
+  print("---------------------------") # leerzeile
+  print(paste("calculation on landcover no:", i, sep=" "))
+
+	# balanced sampling of data
+	BeninDataS = balanced.sampling(BeninData, i, 25000)  
+	
+	# load data from previous sampling:
+  load(list.files(pattern = paste("BeninDataSampleLc", i,sep="")))
+  
+  # save sample
+	#save(BeninDataS, file=paste("BeninDataSampleLc", i, "_", Sys.Date(), ".Rdata", sep=""), compress=T)
+	
+  # --------------------------------------------------------------
+	# do logitis regression fit
+	# --------------------------------------------------------------
+  #fit0 <- glm(lu ~ bev2000 + d.road.2000 +d.village  , family=binomial, 
+  #  data=subset(BeninDataS, select=c(-BeninData.lc.2000.f,  -d.a.area.1991, -d.f.area.2000)))
+  
+  
+  fit <- assign(paste("fit_lc", i, sep=""), glm(lu ~ . , family=binomial, 
+    data=subset(BeninDataS, select=c(-BeninData.lc2000)) ))
+
+  # --------------------------------------------------------------
+  # do stepwise selection of coefficients
+  # --------------------------------------------------------------   
+	fitstep <- assign(paste("step_lc", i, sep=""), stepAIC(fit, direction="both"))
+	
+	
+	# write results to file
+  #WriteCoefClue(fit0, outputRegressionFile, i, "25000 samples, only lc0, selected df")
+  WriteCoefXulu(fitstep, outputRegXulu, i,)
+  #WriteAUC(fitstep, BeninDataS, i)
+  
+}
+
+#######################################################################
+############ plot fitted value as image
+####################################################################### 
+
+## plot.fitted(FileList, fitted object, data to predict, numrows(grid), numcols) 
+
+plot.fitted(FileList, fitstep, BeninData)  
+
+
+#######################################################################
+# plot log curve data 
+#######################################################################
+
+# ---------------------------------------------------------------------
+# real data:
+# ---------------------------------------------------------------------
+fit1 <- glm(lu ~ CostDist , family=binomial, data=BeninDataS[-1])
+coef = fit1$coef
+
+# ---------------------------------------------------------------------
+# manual calculation of response values
+# ---------------------------------------------------------------------
+logistW = exp(coef[1:1]+(coef[2:2]*BeninDataS$DistRoad))/(1 + exp(coef[1:1]+(coef[2:2]*BeninDataS$DistRoad)))
+plot(BeninDataS$DistRoad,logistW)
+lines(BeninDataS$DistRoad, predict(fit1, type="response"))
+
+# use function predict to calculate response values
+p=predict(fit1, type="response")
+d1=data.frame(BeninDataS$CostDist, p)
+ord=order(d1$p, decreasing = TRUE)
+d1=d1[ord,]
+plot(d1), type="line")
+
+# ---------------------------------------------------------------------   
+#easyest possibility to plot fitted log curve:
+# ---------------------------------------------------------------------
+plot(BeninDataS$CostDist, fit1$fitted)
+
+d1 = BeninDataS$CostDist
+d2 = fit1$fitted
+plot(d2)
+d = data.frame(d1,d2)
+plot(d)
+
+# ---------------------------------------------------------------------
+# test with artificial data
+# ---------------------------------------------------------------------
+fit1 <- glm(lu ~ DistRoad , family=binomial, data=BeninDataS[-1])
+d1 = seq(0, 50000, 50)
+logistW = exp(coef[1:1]+(coef[3:3]*d1))/(1 + exp(coef[1:1]+(coef[3:3]*d1)))
+plot(d1,logistW)
+lines(d1, predict(fit1, data.frame(DistRoad = d1, lc = rep(1, length(d1))), type="response"))
+
+
+#######################################################################
+# caculate some performance measures
+#######################################################################
+
+# ---------------------------------------------------------------------
+# pseudo R² McFadden
+# ---------------------------------------------------------------------
+r = 1-(step$deviance/step$null.deviance)
+
+
+# ---------------------------------------------------------------------
+# calculate ROC curve
+# ---------------------------------------------------------------------
+
+pred = prediction(fitted(fitstep),as.vector(fitstep$data$lu))
+perf <- performance(pred, measure = "tpr", x.measure = "fpr")
+
+# magnify graph
+par.olf <- par(cex=1.5)
+plot(perf, col="red", lwd=3)
+par(par.old)
+
+# ---------------------------------------------------------------------
+# compute AUC
+# ---------------------------------------------------------------------
+
+auc = performance(pred, measure="auc")
+# auc is object of class performance, data stored in slots
+# to access slots (and datas) use @ (in Newsletter 4/1 is said don't use it
+# but I don't know an other way
+aucValue = auc at y.values[[1]]
+print(aucValue)
+write (paste("AUC for",colnames(BeninData[1]), ":", aucValue,sep=" "), outputRegEval)
+
+

Added: trunk/src/de/skrueger/xulu/plugin/gnur/SwingIO.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/SwingIO.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/SwingIO.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,362 @@
+package de.skrueger.xulu.plugin.gnur;
+/*
+ * Copyright (c) 2003-2004, KNOPFLERFISH project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials
+ *   provided with the distribution.
+ *
+ * - Neither the name of the KNOPFLERFISH project nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.util.Vector;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollBar;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+
+public class SwingIO extends JPanel {
+
+  JTextArea  text;
+  JTextField tfCmd;
+
+  int p0 = -1;
+  int p1 = 0;
+
+  String last = "";
+
+  InputStream origIn;
+  PrintStream origOut;
+  PrintStream origErr;
+
+  PipedOutputStream textSource;
+
+  TextReader       in;
+  PrintStream      out;
+
+  JPanel panel;
+  JScrollPane scroll;
+  Label  cmdLabel;
+
+  Vector history    = new Vector();
+  int    historyPos = 0;
+
+  StringBuffer lineBuff = new StringBuffer();
+
+  boolean bGrabbed = false;
+
+  int maxLines = new Integer(System.getProperty("org.knopflerfish.desktop.console.maxlines", "5000")).intValue();
+
+  void setSystemIO() {
+
+    boolean bDebugClass = "true".equals(System.getProperty("org.knopflerfish.framework.debug.classloader", "false"));
+
+    if(!bDebugClass) {
+      if(!bGrabbed) {
+        try {
+
+          origIn  = System.in;
+          origOut = System.out;
+          origErr = System.err;
+
+          //    System.setIn(in);
+          System.setOut(new PrintStream(out));
+          System.setErr(new PrintStream(out));
+
+          bGrabbed = true;
+
+        } catch (Exception e) {
+          bGrabbed = false;
+        }
+      }
+    }
+  }
+
+  void restoreSystemIO() {
+
+    //    synchronized(grabLock)
+      {
+      if(bGrabbed) {
+        try {
+          if(origIn != null) {
+            System.setIn(origIn);
+          }
+          if(origOut != null) {
+            System.setOut(origOut);
+          }
+          if(origIn != null) {
+            System.setErr(origErr);
+          }
+//          ConsoleSwing.log(LogService.LOG_DEBUG, "...restored system I/O");
+          bGrabbed = false;
+        } catch (Exception e) {
+  //        ConsoleSwing.log(LogService.LOG_ERROR, "Failed to restore IO", e);
+        }
+      }
+
+    }
+
+  }
+
+
+  public SwingIO() {
+    super(new BorderLayout());
+
+    panel = this;
+
+    try {
+      text = new JTextArea("", 8, 80);
+      text.setEditable(false);
+      String bootText =
+        "Knopflerfish OSGi console. Copyright (c) 2004 Knopflerfish.";
+
+      // See if we're using the knopflerfish framework. If so, grab
+      // the boot string from the startup class
+      try {
+        Class mainClazz = Class.forName("org.knopflerfish.framework.Main");
+        bootText        = (String)mainClazz.getField("bootText").get(null);
+      } catch (Throwable e) {
+        bootText        = "";
+        //  e.printStackTrace();
+        // anything else defaults to the std boot text above
+      }
+      text.setText(bootText +
+       "\n\n" +
+       "Type 'help' for help or 'alias' for a list of common commands\n\n");
+      scroll = new JScrollPane(text,
+                               JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+                               JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+
+      tfCmd = new JTextField();
+
+      final KeyListener keyL = new KeyAdapter() {
+          public void keyPressed(KeyEvent ev) {
+            if(ev.getKeyCode() == KeyEvent.VK_UP) {
+              if(historyPos > 0) {
+                String line = (String)history.elementAt(historyPos-1);
+                historyPos--;
+                tfCmd.setText(line);
+              }
+            } else if(ev.getKeyCode() == KeyEvent.VK_DOWN) {
+              if(historyPos < history.size()-1) {
+                String line = (String)history.elementAt(historyPos+1);
+                historyPos++;
+                tfCmd.setText(line);
+              }
+            } else if(ev.getKeyCode() == KeyEvent.VK_ENTER) {
+              String line = tfCmd.getText();
+              if(!("".equals(line) ||
+                   "\n".equals(line) ||
+                   "\n\r".equals(line) ||
+                   "\r\n".equals(line))) {
+                history.addElement(line);
+                historyPos = history.size();
+              }
+              if("clear".equals(line)) {
+                clear();
+              } else if("quit".equals(line)) {
+//                org.knopflerfish.bundle.desktop.swing
+//                  .Activator.desktop.stopFramework();
+              } else {
+                // Try simple command expansion first
+                if(line.startsWith("!") && line.length() > 1) {
+                  String s2 = line.substring(1);
+                  String bestStr = "";
+                  for(int i = 0; i < history.size(); i++) {
+                    String s = (String)history.elementAt(i);
+                    if(s.startsWith(s2) || s.length() >= bestStr.length()) {
+                      bestStr = s;
+                    }
+                  }
+                  if(!"".equals(bestStr)) {
+                    line = bestStr;
+                  }
+                }
+
+                // ..and send to console via inputstream
+                String s = line + "\r\n";
+                text.append(s);
+                showLastLine();
+                if(in != null) {
+                  in.print(s);
+                  in.flush();
+                }
+              }
+              tfCmd.setText("");
+            }
+          }
+        };
+
+      tfCmd.addKeyListener(keyL);
+
+      // move focus away from text output to text input
+      // in key press
+      text.addKeyListener(new  KeyAdapter() {
+          public void keyPressed(KeyEvent ev) {
+            int modifiers = ev.getModifiers();
+
+            // Don't steal special key events like CTRL-C
+            if(modifiers == 0) {
+              tfCmd.requestFocus();
+            }
+          }
+
+        });
+
+      out = new PrintStream(new TextAreaOutputStream(this, text));
+
+      GridBagLayout gridbag = new GridBagLayout();
+      GridBagConstraints c = new GridBagConstraints();
+
+      panel.add(scroll,         BorderLayout.CENTER);
+
+      Panel cmdPanel = new Panel(new BorderLayout());
+
+      cmdLabel = new Label("> ");
+      cmdPanel.add(cmdLabel,        BorderLayout.WEST);
+      cmdPanel.add(tfCmd,           BorderLayout.CENTER);
+
+      panel.add(cmdPanel,        BorderLayout.SOUTH);
+
+
+      reinit();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+
+  void clear() {
+    text.setText("");
+  }
+
+  void showLastLine() {
+    SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        if (maxLines > 0) {
+          int linesToRemove = text.getLineCount() - maxLines;
+          int index = 0;
+          if (linesToRemove > 0) {
+            for (int i=0; i<linesToRemove; i++) {
+              index = text.getText().indexOf('\n', index) + 1;
+            }
+            text.setText(text.getText().substring(index));
+          }
+        }
+
+        JScrollBar bar = scroll.getVerticalScrollBar();
+        if(bar != null) {
+          int v = bar.getMaximum();
+          bar.setValue(v*2);
+        }
+      }
+    });
+  }
+
+  Font font;
+
+  synchronized void reinit() {
+    font = new Font("Areal", Font.PLAIN, 20);
+
+//    text.setBackground(Config.parseColor(1));
+//    text.setForeground(Config.parseColor(2));
+    text.setFont(font);
+
+    tfCmd.setBackground(text.getBackground());
+    tfCmd.setForeground(text.getForeground());
+    tfCmd.setFont(text.getFont());
+
+    cmdLabel.setBackground(text.getBackground());
+    cmdLabel.setForeground(text.getForeground());
+    cmdLabel.setFont(text.getFont());
+  }
+
+  void start() {
+    stop();
+    in         = new TextReader();
+    setVisible(true);
+      setSystemIO();
+  }
+
+  void stop() {
+    restoreSystemIO();
+    setVisible(false);
+    if(in != null) {
+      in.close();
+      in = null;
+    }
+  }
+
+
+  public class TextAreaOutputStream extends OutputStream {
+
+  	  JTextArea     text;
+  	  SwingIO        swingIO;
+  	  StringBuffer buff = new StringBuffer();
+
+  	  TextAreaOutputStream(SwingIO swingIO, JTextArea text) {
+  	    this.swingIO = swingIO;
+  	    this.text  = text;
+  	  }
+
+  	  public void flush() {
+  	    text.append(buff.toString());
+  	    buff.setLength(0);
+  	  }
+
+  	  public void write(int b) {
+  	    char c = (char)b;
+  	    if(c == '\r') {
+  	    } else if(c == '\n') {
+  	      text.append(buff.toString() + "\n");
+  	      buff.setLength(0);
+  	      swingIO.showLastLine();
+  	    } else {
+  	      buff.append(c);
+  	    }
+  	  }
+  	}
+}
+
+

Added: trunk/src/de/skrueger/xulu/plugin/gnur/TextReader.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/TextReader.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/TextReader.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,138 @@
+package de.skrueger.xulu.plugin.gnur;
+/*
+ * Copyright (c) 2003-2004, KNOPFLERFISH project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials
+ *   provided with the distribution.
+ *
+ * - Neither the name of the KNOPFLERFISH project nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.io.IOException;
+import java.io.Reader;
+
+
+
+public class TextReader extends Reader {
+
+  StringBuffer sb = new StringBuffer();
+
+  Object  lock     = new Object();
+  Object  waitLock = new Object();
+
+  public TextReader() {
+  }
+
+  public int available() {
+    if(sb == null) {
+      throw new RuntimeException("Stream closed");
+    }
+    System.out.println("read available=" + sb.length());
+    return sb.length();
+  }
+
+  public void close() {
+    flush();
+    sb = null;
+  }
+  
+  public void mark(int readlimit) {
+  }
+
+  
+  public boolean markSupported() {
+    return false;
+  }
+
+  public void reset() {
+  }
+
+  public long skip(long n) {
+    if(sb == null) {
+      throw new RuntimeException("Stream closed");
+    }
+    sb.delete(0, (int)Math.max(n, sb.length()));
+    return sb.length();
+  }
+ 
+  public void print(String s) {
+    if(sb == null) {
+      throw new RuntimeException("Stream closed");
+    }
+    sb.append(s);
+    if(s.length() > 0) {
+      flush();
+    }
+  }
+
+  void flush() {
+    synchronized(waitLock) {
+      waitLock.notifyAll();
+    }
+  }
+
+  char[] buf = new char[1];
+
+  public int read() throws IOException {
+    if(-1 != read(buf, 0, 1)) {
+      return buf[0];
+    }
+    
+    return -1;
+  }
+
+  public int read(char[] b) throws IOException {
+    return read(b, 0, b.length);
+  }
+
+  public int read(char[] cbuf, int off, int len) throws IOException {
+    synchronized(waitLock) {
+      if(sb == null) {
+	throw new RuntimeException("Stream closed");
+      }
+      if(len == 0) {
+	return 0;
+      }
+      try {
+	while(sb == null || len > sb.length()) {
+	  waitLock.wait();
+	}
+      } catch(InterruptedException e) {
+	throw new IOException(e.getMessage());
+      }
+      
+      int i   = 0;
+      while(i < len) {
+	cbuf[off + i] = sb.charAt(i);
+	i++;
+      }
+      sb.delete(0, i);
+      return len;
+    }
+  }
+}
\ No newline at end of file

Added: trunk/src/de/skrueger/xulu/plugin/gnur/testsomethong.java
===================================================================
--- trunk/src/de/skrueger/xulu/plugin/gnur/testsomethong.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/de/skrueger/xulu/plugin/gnur/testsomethong.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,22 @@
+package de.skrueger.xulu.plugin.gnur;
+
+import java.io.File;
+
+import javax.swing.JFrame;
+
+public class testsomethong {
+
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		JFrame frame = new JFrame();
+		
+		frame.getContentPane().add( new JRTextArea());
+		frame.pack();
+		frame.setVisible(true);
+		
+
+	}
+
+}

Added: trunk/src/edu/bonn/xulu/XuluModellingPlatform.java
===================================================================
--- trunk/src/edu/bonn/xulu/XuluModellingPlatform.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/edu/bonn/xulu/XuluModellingPlatform.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,697 @@
+/** XULU - This file is part of the eXtendable Unified Land Use Modelling Platform (XULU)
+
+    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+    You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+    Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser General Public License, wie von der Free Software Foundation veröffentlicht, weiterverteilen und/oder modifizieren; entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) jeder späteren Version.
+    Diese Bibliothek wird in der Hoffnung weiterverbreitet, daß sie nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der GNU Lesser General Public License.
+    Sie sollten eine Kopie der GNU Lesser General Public License zusammen mit dieser Bibliothek erhalten haben; falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.
+ **/
+
+package edu.bonn.xulu;
+
+import javax.swing.UIManager;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Vector;
+import java.util.TreeSet;
+import java.util.SortedSet;
+import java.util.Locale;
+import java.io.FileInputStream;
+import java.io.File;
+import java.io.PrintStream;
+
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import schmitzm.lang.SortableVector;
+import schmitzm.swing.SwingUtil;
+import schmitzm.swing.SwingWorker;
+import schmitzm.swing.ExceptionDialog;
+import schmitzm.geotools.GTUtil;
+import schmitzm.lang.ResourceProvider;
+import schmitzm.lang.DefaultComparator;
+import schmitzm.geotools.io.GeoImportUtil;
+
+import edu.bonn.xulu.gui.XuluMainFrame;
+import edu.bonn.xulu.gui.XuluStartingFrame;
+import edu.bonn.xulu.appl.XuluComponent;
+import edu.bonn.xulu.appl.XuluComponentUtil;
+import edu.bonn.xulu.appl.DataPool;
+import edu.bonn.xulu.appl.XuluRegistry;
+import edu.bonn.xulu.appl.XuluRegistryReader;
+import edu.bonn.xulu.appl.VisualisationManager;
+import edu.bonn.xulu.appl.ModelControlManager;
+import edu.bonn.xulu.appl.EventManager;
+import edu.bonn.xulu.appl.XuluPlugin;
+import edu.bonn.xulu.appl.XuluConstants;
+import edu.bonn.xulu.plugin.appl.DataScriptInterpreter_Basic;
+import edu.bonn.xulu.plugin.appl.XuluRegistryReader_BasicAscii;
+
+import appl.ext.XuluConfig;
+
+/**
+ * Diese Klasse implementiert das Hauptprogramm der Xulu-Modeling-Platform.
+ * Beim Starten koennen folgende Kommandozeilenparameter angegeben werden:
+ * <ul>
+ * <li><code>? | /? | -? | -h | h | --help</code><br>
+ *     Zeigt eine Hilfe zu den Kommandozeilenparametern an.</li>
+ * <li><code>-kso</code><br>
+ *     Haelt den Start-Dialog offen, bis "OK" gedrueckt wird.</li>
+ * <li><code>-nogui</code><br>
+ *     Xulu-GUI wird <b>nicht</b> gestartet! Dies macht nur Sinn, wenn autom.
+ *     ein Skript gestartet wird oder die Xulu-Applikation per Konstruktor
+ *     aus einer anderen Applikation instanziiert wird.</li>
+ * <li><code>-noplugin</code><br>
+ *     Ignoriert die in der Xulu-Registry angegebene Autostart-Funktion fuer
+ *     Plugins.</li>
+ * <li><code>-r <i>path</i></code><br>
+ *     Setzt das Start-Verzeichnis (Root) fuer die Instanz, in dem die Registry- und
+ *     XuluProperties-Dateien zu finden sind (Standard: Start-Verzeichnis).</li>
+ * <li><code>-w <i>path</i></code><br>
+ *     Setzt das Arbeitsverzeichnis fuer die Instanz.</li>
+ * <li><code>-l <i>language</i></code><br>
+ *     Setzt die Sprache fuer die GUI. Muss ein ISO-639 Code sein.</li>
+ * <li><code>-rf <i>filepath</i></code><br>
+ *     Setzt die zu Beginn einzulesende Registry-Datei (Default: <code>registry.xif</code>)</li>
+ * <li><code>-rr <i>package.class</i></code><br>
+ *     Setzt den RegistryReader, der zum Einlesen der Registry verwendet wird.
+ *     Muss eine ueber einen Standard-Konstruktor instanziierbare Subklasse
+ *     von {@link XuluRegistryReader} sein (Default: {@link XuluRegistryReader_BasicAscii}.</li>
+ * <li><code>-d <i>path</i></code><br>
+ *     Setzt den Suchpfad (Classpath) fuer die dynamisch zu aktualisierenden Klassen
+ *     (zur Zeit nur Modell-Klassen, also das Paket <code>edu.bonn.xulu.plugin.model</code>).
+ *     Standardmaessig wird das Verzeichnis <code>classes_dyn</code>
+ *     unterhalb des Xulu-Programmverzeichnisses verwendet.<br>
+ *     <b>Bemerke:</b><br>
+ *     Dieses Verzeichnis darf <b>kein</b> Bestandteil des CLASSPATH der JVM
+ *     sein, in der Xulu gestartet wird, da ansonsten das dynamische
+ *     Aktualisieren veraenderter Klassen nicht funktioniert!</li>
+ * <li><code>-s <i>filepath</i></code><br>
+ *     Fuehrt nach dem Initialisieren automatisch die durch ';' getrennten Skripte aus</li>
+ * </ul>
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class XuluModellingPlatform implements XuluComponent {
+
+  /** Liste aller in Xulu verwendeten {@link ResourceProvider} */
+  public static final SortableVector<ResourceProvider> RESOURCE_BUNDLES = new SortableVector<ResourceProvider>();
+  static {
+    // Resource Bundles aus Standard-Paketen umlenken
+    schmitzm.swing.SwingUtil.RESOURCE.resetResourceBundle(XuluConstants.EXTENTION_BUNDLE,"schmitzm.swing");
+    schmitzm.geotools.gui.GeotoolsGUIUtil.RESOURCE.resetResourceBundle(XuluConstants.EXTENTION_BUNDLE,"schmitzm.gt");
+    schmitzm.jfree.JFreeChartUtil.RESOURCE.resetResourceBundle(XuluConstants.EXTENTION_BUNDLE,"schmitzm.jfree");
+    schmitzm.data.DataUtil.RESOURCE.resetResourceBundle(XuluConstants.EXTENTION_BUNDLE,"schmitzm.data");
+    // Resource Bundles in Liste sammeln
+    registerResourceProvider(schmitzm.swing.SwingUtil.RESOURCE);
+    registerResourceProvider(schmitzm.geotools.gui.GeotoolsGUIUtil.RESOURCE);
+    registerResourceProvider(schmitzm.jfree.JFreeChartUtil.RESOURCE);
+    registerResourceProvider(schmitzm.data.DataUtil.RESOURCE);
+  }
+
+  private static boolean keepStartFrameOpen = false;
+  private        boolean startGUI = true;
+  private        boolean autostartPlugins = true;
+
+  private boolean packFrame = false;
+
+  // Art und Weise die Registry einzulesen
+  // ACHTUNG: NACH AENDERUG AUCH DIE JAVADOC OBEN ANPASSEN
+  private File               registryFile   = new File("registry.xif");
+  private XuluRegistryReader registryReader = new XuluRegistryReader_BasicAscii();
+
+  // Xulu-Komponenten
+  private DataPool             dataPool       = null;
+  private XuluRegistry         registry       = null;
+  private VisualisationManager visManager     = null;
+  private ModelControlManager  modelManager   = null;
+  private EventManager         eventManager   = null;
+  // Haupt-GUI
+  private XuluMainFrame        mainFrame      = null;
+
+  // Programm-Parameter
+  private File                 startDir    = new File(".");
+  private File                 pluginDir    = new File("plugin");
+  private File                 workDir     = new File(".");
+  private File                 dynClassDir = null;
+  private File                 startupScriptFiles[] = null;
+
+  /**
+   * Erzeugt eine neue Instanz der Xulu-Modelling-Platform.
+   */
+  public XuluModellingPlatform() {
+    this( new String[0] );
+  }
+
+  /**
+   * Erzeugt eine neue Instanz der Xulu-Modelling-Platform.
+   * @param args Kommandozeilenparameter
+   */
+  public XuluModellingPlatform(String[] args) {
+    this(args,null);
+  }
+
+  private void giveStatus(String text, PrintStream stream) {
+    if (stream == null)
+      return;
+    stream.print(text);
+  }
+
+  /**
+   * Erzeugt eine neue Instanz der Xulu-Modelling-Platform.
+   * @param args       Kommandozeilenparameter
+   * @param infoStream Stream in den Status-Meldungen geschrieben werden, die
+   *                   ueber den Fortschritt der Initialisierung Auskunft geben
+   */
+  public XuluModellingPlatform(String[] args, PrintStream infoStream) {
+    //this.dynClassDir = new File("classes_dyn");
+    try {
+      this.dynClassDir = new File(ClassLoader.getSystemResource("").toURI());
+    } catch(Exception err) {
+      throw new RuntimeException(err);
+    }
+    
+    giveStatus("Reading command line parameters...",infoStream);
+    interpreteCommandLineParameters(args);
+    giveStatus(" done.\n",infoStream);
+
+    //Reading config file (automaticly loaded from File 'XuluProperties'
+    appl.ext.XuluConfig.getXuluConfig( startDir );
+
+    // Datenpool erzeugen und initialisieren
+    giveStatus("Creating xulu data pool...",infoStream);
+    this.dataPool = new DataPool();
+    giveStatus(" done.\n",infoStream);
+
+    // Registry erzeugen
+    giveStatus("Creating xulu registry...",infoStream);
+    this.registry = new XuluRegistry();
+    giveStatus(" done.\n",infoStream);
+
+    // Visualisierungsmanager erzeugen und initialisieren
+    giveStatus("Creating xulu visualisation manager...",infoStream);
+    this.visManager = new VisualisationManager();
+    giveStatus(" done.\n",infoStream);
+
+    // Manager fuer Modell-Kontrollkomponenten erzeugen und initialisieren
+    giveStatus("Creating xulu model manager...",infoStream);
+    this.modelManager = new ModelControlManager();
+    giveStatus(" done.\n",infoStream);
+
+    // Manager fuer Ereignisse erzeugen und initialisieren
+    giveStatus("Creating xulu event manager...",infoStream);
+    this.eventManager = new EventManager(this);
+    giveStatus(" done.\n",infoStream);
+
+    // MainFrame erzeugen und initialisieren
+    if ( startGUI ) {
+      giveStatus("Creating xulu main window...",infoStream);
+      this.mainFrame = new XuluMainFrame(this);
+      //Frames Ueberpruefen, die voreingestellte Groesse haben
+      //Frames packen, die nutzbare bevorzugte Groesseninformationen enthalten, z.B. aus ihrem Layout
+      if (packFrame)
+        mainFrame.pack();
+      else
+        mainFrame.validate();
+      SwingUtil.centerFrameOnScreen(mainFrame);
+      mainFrame.setVisible(true);
+      mainFrame.arrangeInnerFrames();
+      giveStatus(" done.\n",infoStream);
+    }
+
+    // Registry einlesen
+    giveStatus("Reading xulu registry file...",infoStream);
+    try {
+      FileInputStream fileIn = new FileInputStream(registryFile);
+      registryReader.readRegistry(this,fileIn,registry);
+      fileIn.close();
+    } catch (Exception err) {
+      System.err.println("Fehler beim Initialisieren der XuluRegistry: "+err);
+    }
+    giveStatus(" done.\n",infoStream);
+
+    // RecentImports und RecentScripts aus Properties lesen
+    registry.getRecentImports().loadFromXuluProperties(this);
+    registry.getRecentScripts().loadFromXuluProperties(this);
+    // Standard-CRS aus Properties lesen
+    giveStatus("Read default CRS from XULU properties...",infoStream);
+    String defaultCRS = XuluConfig.getXuluConfig().getProperty("General.DefaultCRS");
+    CoordinateReferenceSystem crs = defaultCRS != null ? GTUtil.createCRS(defaultCRS) : null;
+    if ( crs != null )  {
+      GeoImportUtil.DEFAULT_CRS = crs;
+      giveStatus(" done.\n",infoStream);
+    } else {
+      giveStatus(" failt!\n",infoStream);
+    }
+
+
+    // Autostart-Plugins starten
+    // --> WICHTIG: sollte VOR dem Ausfuehren der Start-Skripte stattfinden,
+    //              damit das LoggerPlugin bereits gestartet ist (fuer
+    //              Meldungen waehrend der Start-Skripte!)
+    if ( this.autostartPlugins ) {
+      XuluPlugin[] autostartPlugin = registry.getAutostartPlugins();
+      giveStatus("Executing Autostart-Plugins...",infoStream);
+      for (int i=0; autostartPlugin != null && i<autostartPlugin.length; i++ )
+        autostartPlugin[i].execute(this);
+      giveStatus(" done.\n",infoStream);
+    }
+
+    // Start the scripts
+    if (startupScriptFiles != null)
+      for (File file : startupScriptFiles) {
+        if (file != null) {
+          giveStatus("Executing script " + file.getName() + "...", infoStream);
+          try {
+            FileInputStream fileIn = new FileInputStream(file);
+            new DataScriptInterpreter_Basic().execute(fileIn, this);
+            fileIn.close();
+          }
+          catch (Exception err) {
+            System.err.println("Error while executing startup script: " + err);
+          }
+          giveStatus(" done.\n", infoStream);
+        }
+      }
+
+  }
+
+  /**
+   * Zerstoert die Instanz der Xulu-Anwendung in dem ein
+   * {@link System#exit(int) System.exit(0)} ausgefuehrt wird. Zuvor werden
+   * folgende Komponenten zerstoert:
+   * <ul>
+   * <li>{@linkplain DataPool#dispose() Daten-Pool}</li>
+   * <li>{@linkplain ModelControlManager#dispose() Model-Control-Manager}</li>
+   * <li>{@linkplain VisualisationManager#dispose() Visualisation-Manager}</li>
+   * <li>{@linkplain XuluMainFrame#dispose() GUI-Hauptfenster}</li>
+   * </ul>
+   */
+  public void dispose() {
+    XuluComponentUtil.checkDisposed(this);
+    registry.getRecentImports().storeToXuluProperties(this);
+    registry.getRecentScripts().storeToXuluProperties(this);
+    XuluConfig.getXuluConfig().store();
+    if ( modelManager != null )
+      modelManager.removeAll();
+    modelManager = null;
+    if ( visManager != null )
+      visManager.removeAll();
+    visManager = null;
+    if ( dataPool != null )
+      dataPool.dispose();
+    dataPool = null;
+    if ( mainFrame != null )
+      mainFrame.dispose();
+    mainFrame = null;
+    if ( startGUI )
+      System.exit(0);
+  }
+
+  /**
+   * Prueft, ob die Xulu-Anwendung zerstoert ist.
+   * @see #dispose()
+   */
+  public boolean isDisposed() {
+    return getRegistry() == null;
+  }
+
+  /**
+   * Liefert das Startverzeichnis der Xulu-Applikation.
+   */
+  public File getStartingDirectory() {
+    return startDir;
+  }
+
+  /**
+   * Liefert das CLASSPATH-Verzeichnis unterhalb dessen die Klassen zu finden
+   * sind, die dynamisch in Xulu geladen werden koennen.<br>
+   * <b>Bemerkung:</b><br>
+   * Dieses Verzeichnis darf <b>nicht</b> im CLASSPATH der JVM enthalten sein,
+   * in der Xulu ausgefuehrt wird!!
+   */
+  public File getDynamicClassRootDirectory() {
+    return dynClassDir;
+  }
+
+  /**
+   * Setzt das CLASSPATH-Verzeichnis unterhalb dessen die Klassen zu finden
+   * sind, die dynamisch in Xulu geladen werden koennen.<br>
+   * <b>Bemerkung:</b><br>
+   * Dieses Verzeichnis darf <b>nicht</b> im CLASSPATH der JVM enthalten sein,
+   * in der Xulu ausgefuehrt wird!!
+   */
+  public void setDynamicClassRootDirectory(File searchPath) {
+    dynClassDir = searchPath;
+  }
+
+  /**
+   * Liefert das Verzeichnis ('{@code plugin}' unterhalb des Start-Verzeichnisses)
+   * in dem von Plugins benoetigte Dateien abgelegt werden.
+   */
+  public File getPluginDirectory() {
+    return pluginDir;
+  }
+
+  /**
+   * Liefert das Arbeitsverzeichnis der Xulu-Applikation.
+   */
+  public File getWorkingDirectory() {
+    return workDir;
+  }
+
+  /**
+   * Setzt das Arbeitsverzeichnis der Xulu-Applikation.
+   */
+  public void setWorkingDirectory(File workDir) {
+    if ( !workDir.isDirectory() || !workDir.exists() )
+      throw new RuntimeException("Working directory must be a directory and must exist!");
+    this.workDir = workDir;
+  }
+
+  /**
+   * Liefert den Datenpool der Xulu-Instanz.
+   */
+  public DataPool getDataPool() {
+    return dataPool;
+  }
+
+  /**
+   * Liefert die Registry der Xulu-Instanz.
+   */
+  public XuluRegistry getRegistry() {
+      return registry;
+  }
+
+  /**
+   * Liefert den Verwaltungsmanager fuer die Visualisierungstool-Instanzen.
+   */
+  public VisualisationManager getVisualisationManager() {
+      return visManager;
+  }
+
+  /**
+   * Liefert den Verwaltungsmanager fuer die Modell-Kontroll-Komponenten.
+   */
+  public ModelControlManager getModelControlManager() {
+      return modelManager;
+  }
+
+  /**
+   * Liefert den Verwaltungsmanager fuer die Modell-Kontroll-Komponenten.
+   */
+  public EventManager getEventManager() {
+      return eventManager;
+  }
+
+  /**
+   * Liefert das Hauptfenster der Xulu-Instanz.
+   */
+  public XuluMainFrame getMainFrame() {
+      return mainFrame;
+  }
+
+  /**
+   * Interpretiert die Kommandozeilen-Parameter, die fuer die Xulu-Instanz
+   * relevant sind.
+   * Dies sind:
+   * <ul>
+   * <li><code>-r <i>path</i></code><br>
+   *     Setzt das Start-Verzeichnis (Root) fuer die Instanz, in dem die Registry- und
+   *     XuluProperties-Dateien zu finden sind.</li>
+   * <li><code>-w <i>path</i></code><br>
+   *     Setzt das Arbeitsverzeichnis fuer die Instanz.</li>
+   * <li><code>-rf <i>path</i></code><br>
+   *     Bestimmt die einzulesende Registry-Datei.</li>
+   * <li><code>-rr <i>package.class</i></code><br>
+   *     Bestimmt die Art, die Registry-Datei einzulesen. <i>package.class</i> muss eine
+   *     Unterklasse von {@link XuluRegistryReader} sein und einen Standard-Konstruktor
+   *     besitzen.</li>
+   * <li><code>-d <i>path</i></code><br>
+   *     Setzt den Suchpfad (Classpath) fuer die dynamisch zu ladenen Klassen (zur Zeit
+   *     nur Modell-Klassen). Standardmaessig wird das Verzeichnis <code>classes_dyn</code>
+   *     unterhalb des Xulu-Programmverzeichnisses verwendet.<br>
+   *     <b>Bemerke:</b><br>
+   *     Dieses Verzeichnis darf <b>kein</b> Bestandteil des CLASSPATH der JVM
+   *     sein, in der Xulu gestartet wird, da ansonsten das dynamische
+   *     Aktualisieren veraenderter Klassen nicht funktioniert!</li>
+   * <li><code>-s <i>path<i></code><br>
+   *     Fuehrt die angegebenen durch ';' getrennten Scripte beim Starten aus. </li>
+   * <li><code>-nogui</code><br>
+   *     Verhindert, dass die Xulu-GUI gestartet wird. Dies macht nur Sinn, wenn autom.
+   *     ein Skript gestartet wird oder die Xulu-Applikation per Konstruktor
+   *     aus einer anderen Applikation instanziiert wird.</li>
+   * <li><code>-noplugin</code><br>
+   *     Ignoriert die in der Xulu-Registry angegebene Autostart-Funktion fuer
+   *     Plugins.</li>
+   * </ul>
+   */
+  private void interpreteCommandLineParameters(String[] args) {
+    for (int i=0; args!=null && i<args.length; i++) {
+      // bereits verarbeitete Argumente ignorieren
+      if ( args[i] == null )
+        continue;
+
+       // Angabe des Root-Verzeichnisses
+       // -r <path>
+       if ( args[i].equalsIgnoreCase("-r") )
+         try {
+           startDir = new File(args[i+1]);
+           i++;
+           continue;
+         } catch (Exception err) {
+           System.err.println("Invalid Argument: After -w a valid path is expected");
+           continue;
+         }
+        // Angabe des Arbeitsverzeichnisses
+        // -w <path>
+        if ( args[i].equalsIgnoreCase("-w") )
+          try {
+            setWorkingDirectory( new File(args[i+1]) );
+            i++;
+            continue;
+          } catch (Exception err) {
+            System.err.println("Invalid Argument: After -w a valid path is expected");
+            continue;
+          }
+       //Angabe von Startup-Skripten
+       // -s <file>
+       if ( args[i].equalsIgnoreCase("-s") )
+         try {
+             //splitte nach den einzelnen files
+        	 String[] fileNames = args[i+1].split(";");
+        	 startupScriptFiles = new File[fileNames.length];
+        	 for (int j = 0; j < fileNames.length; j++) {
+				startupScriptFiles [j] = new File(fileNames[j]);
+			}
+           i++;
+           continue;
+         } catch (Exception err) {
+           System.err.println("Invalid Argument: After -s a valid paths sperated by ';' are expected");
+           continue;
+         }
+        // Angabe der Registry-Datei
+        // -rf <file>
+        if ( args[i].equalsIgnoreCase("-rf") )
+         try {
+           registryFile = new File( args[i+1] );
+           i++;
+           continue;
+         } catch (Exception err) {
+           System.err.println("Invalid Argument: After -rf a valid path is expected");
+           continue;
+         }
+         // Angabe des Registry-Readers
+         // -r <package.class>
+         if ( args[i].equalsIgnoreCase("-rr") )
+          try {
+            registryReader = (XuluRegistryReader)Class.forName(args[i+1]).newInstance();
+            i++;
+            continue;
+          } catch (InstantiationException err) {
+            System.err.println("Invalid Argument: Subclass of XuluRegistryReader needs a default constructor");
+            continue;
+          } catch (Exception err) {
+            System.err.println("Invalid Argument: After -rr a subclass of XuluRegistryReader is expected");
+            continue;
+          }
+          // Angabe des Such-Pfades fuer dynamische Klassen
+          // -d <path>
+          if ( args[i].equalsIgnoreCase("-d") )
+           try {
+             setDynamicClassRootDirectory( new File(args[i+1]) );
+             i++;
+             continue;
+           } catch (Exception err) {
+             System.err.println("Invalid Argument: After -d a valid path is expected");
+             continue;
+           }
+         // Flag, dass keine GUI gestartet wird
+         if ( args[i].equalsIgnoreCase("-nogui") ) {
+           this.startGUI = false;
+           continue;
+         }
+         // Flag, dass keine Plugins gestartet werden
+         if ( args[i].equalsIgnoreCase("-noplugin") ) {
+           this.autostartPlugins = false;
+           continue;
+         }
+     System.err.println("Unknown Argument: "+args[i]);
+   }
+  }
+
+  ///////////////////////////////////////////////////////////////////
+  // Starter-Methoden
+  ///////////////////////////////////////////////////////////////////
+  /**
+   * Interpretiert die Kommandozeilen-Parameter, die statisch relevant sind.
+   * Dies sind:
+   * <ul>
+   * <li><code>? | /? | -? | -h | h | --help</code><br>
+   *     Zeigt eine Hilfe zu den Kommandozeilenparametern an.</li>
+   * <li><code>-kso</code><br>
+   *     Haelt das Startup-Fenster nach dem Xulu-Start offen.</li>
+   * <li><code>-l <i>language</i></code><br>
+   *     Setzt die Sprache der GUI. <i>language</i> muss ein ISO-639 Code sein.</li>
+   * </ul>
+   */
+  private static void interpreteStaticCommandLineParameters(String[] args) {
+    for (int i=0; args!=null && i<args.length; i++) {
+        // Parameter-Hilfe
+        // ? -? /? h -h --help
+        if ( args[i].startsWith("?")  || args[i].startsWith("-?") ||
+             args[i].startsWith("/?") ||
+             args[i].equalsIgnoreCase("h") || args[i].equalsIgnoreCase("-h") ||
+             args[i].equalsIgnoreCase("--help") ) {
+          showParameterHelp();
+          args[i] = null; // Argument als verarbeitet kennzeichnen
+          System.exit(0);
+        }
+        // Angabe der Sprache
+        // -l <language>
+        if ( args[i].equalsIgnoreCase("-l") )
+          try {
+            Locale.setDefault( new Locale(args[i+1]) );
+            i++;
+            // Argumente als verarbeitet kennzeichnen
+            args[i-1] = null;
+            args[i] = null;
+            continue;
+          } catch (Exception err) {
+            System.err.println("Invalid Argument: After -l a valid ISO-639 code is expected");
+            continue;
+          }
+        // Start-Up-Fenster offen halten
+        if ( args[i].equalsIgnoreCase("-kso") ) {
+          keepStartFrameOpen = true;
+          args[i] = null; // Argument als verarbeitet kennzeichnen
+        }
+    }
+  }
+
+  private static void showParameterHelp() {
+    System.out.println("\nUsage: java [jre commands] edu.bonn.xulu.XuluModellingPlatform [Xulu commands]");
+    System.out.println("Xulu commands:  ? | /? | -?       Shows this help message");
+    System.out.println("               -h |  h | --help   Shows this help message");
+    System.out.println("               -kso       gs        Keeps the starting frame open.");
+    System.out.println("               -r <path>          Sets the starting (root) directory to <path>");
+    System.out.println("               -w <path>          Sets the working directory to <path>");
+    System.out.println("               -l <language>      Sets the language for the application");
+    System.out.println("                                  Note:");
+    System.out.println("                                  <language> must be a lowercase two-letter");
+    System.out.println("                                  ISO-639 code and the corresponding");
+    System.out.println("                                  ResourceBundle classes must be implemented.");
+    System.out.println("                                  Currently 'de' and 'en' are supported.");
+    System.out.println("               -rf <filepath>     Sets the path to xulu registry file.");
+    System.out.println("               -rr <class>        Sets the class to read the xulu registry");
+    System.out.println("                                  Note:");
+    System.out.println("                                  <class> must be a subclass of XuluRegistryReader");
+    System.out.println("                                  and have a default constructor.");
+    System.out.println("                                  A full class name (package.class) must be specified.");
+    System.out.println("               -d <path>          Sets the directory where the dynamic (reloadable)");
+    System.out.println("                                  classes are located.");
+    System.out.println("                                  Note:");
+    System.out.println("                                  <path> is not allowed to be a part of the CLASSPATH!");
+    System.out.println("               -s <path>          Executes the given datapool scipt after xulu start.");
+    System.out.println("               -nogui             Avoids starting the Xulu GUI. This makes only sence,");
+    System.out.println("                                  if a script is executed automatically or the");
+    System.out.println("                                  XuluModellingPlatform class is instanciated manually");
+    System.out.println("                                  by another application.");
+    System.out.println("               -noplugin          Ignores the autostart functionality specified for");
+    System.out.println("                                  plugins in the Xulu registry.");
+    System.out.println();
+  }
+
+  /**
+   * Startet die Xulu-Anwendungung.
+   * @param args Kommandozeilenparameter
+   */
+  public static void main(final String[] args) {
+    try {
+      if( XuluConfig.getXuluConfig().getBooleanProperty("General.useSystemLookAndFeel") )
+        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+
+      interpreteStaticCommandLineParameters(args);
+
+      // Waehrend die Xulu-Applikation (im Hintergrund) gestartet wird, wird
+      // ein Fenster angezeigt, in dem die Initialisierungsphasen angezeigt
+      // werden
+      SwingWorker.Work initWork = new SwingWorker.Work() {
+        public Object execute() {
+          new XuluModellingPlatform(args,((XuluStartingFrame)getSwingWorker().getDialog()).getPrintStream());
+          return null;
+        }
+        public void performError(Throwable err) {
+          err.printStackTrace();
+          super.performError(err);
+          System.exit(-1);
+        }
+      };
+      SwingWorker startingWindow = new SwingWorker(initWork,new XuluStartingFrame()) {
+        // wenn der Start-Dialog abgebrochen wird, wird die komplette
+        // Applikation abgebrochen
+        public void terminate() {
+          System.exit(0);
+        }
+      };
+      // Ueber den Kommandozeilenparameter -kso wird das Start-Fenster
+      // offen gehalten und nicht automatisch geschlossen
+      startingWindow.setKeepOpen( keepStartFrameOpen );
+      startingWindow.start();
+
+      // Begruessungsmeldung im Xulu-Fenster
+      System.out.println("Start XULU by");
+      System.out.println("   java [jre commands] edu.bonn.xulu.XuluModellingPlatform --help");
+      System.out.println("to see available command line parameters.\n");
+    } catch(Throwable e) {
+      e.printStackTrace();
+      ExceptionDialog.show(e);
+      System.exit(-1);
+    }
+  }
+
+  /**
+   * Fuegt einen {@link ResourceProvider} in die Liste der in Xulu verwendeten
+   * ResourceProvider ein.
+   * @param rp ein ResourceProvider
+   */
+  public static void registerResourceProvider(ResourceProvider rp) {
+    RESOURCE_BUNDLES.add(rp);
+  }
+
+  /**
+   * Erzeugt einen {@link ResourceProvider} unterhalb von {@link XuluConstants#LOCALES_BASE}
+   * ({@code locales}) und fuegt ihn in die Liste der in Xulu verwendeten
+   * ResourceProvider ein.
+   * @param bundleName    Name des Bundles
+   * @param defaultLocale Standard-SPrache des Bundles
+   * @see XuluConstants#LOCALES_BASE
+   */
+  public static ResourceProvider registerResourceProvider(String bundleName, Locale defaultLocale) {
+    ResourceProvider rp = new ResourceProvider(LOCALES_BASE+"."+bundleName,defaultLocale);
+    registerResourceProvider( rp );
+    return rp;
+  }
+
+}

Added: trunk/src/edu/bonn/xulu/appl/AbstractCommandInterpreter.java
===================================================================
--- trunk/src/edu/bonn/xulu/appl/AbstractCommandInterpreter.java	2009-02-24 23:27:09 UTC (rev 1)
+++ trunk/src/edu/bonn/xulu/appl/AbstractCommandInterpreter.java	2009-02-25 11:54:01 UTC (rev 2)
@@ -0,0 +1,99 @@
+/** XULU - This file is part of the eXtendable Unified Land Use Modelling Platform (XULU)
+
+    This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+    You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
+
+    Diese Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen der GNU Lesser Gen